-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
feat(medusa, core-flows, fulfillment): calculate SO price endpoint #10532
Changes from 4 commits
5d36c2c
3c0c0f7
61b43c3
f65caaa
bbe68de
5ef927f
1191b52
a931121
9a48057
24fb6e0
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 |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { | ||
CalculateShippingOptionPriceDTO, | ||
IFulfillmentModuleService, | ||
} from "@medusajs/framework/types" | ||
import { Modules } from "@medusajs/framework/utils" | ||
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" | ||
|
||
export const calculateShippingOptionsPricesStepId = | ||
"calculate-shipping-options-prices" | ||
/** | ||
* This step calculates the prices for one or more shipping options. | ||
*/ | ||
export const calculateShippingOptionsPricesStep = createStep( | ||
calculateShippingOptionsPricesStepId, | ||
async (input: CalculateShippingOptionPriceDTO[], { container }) => { | ||
const service = container.resolve<IFulfillmentModuleService>( | ||
Modules.FULFILLMENT | ||
) | ||
|
||
const prices = await service.calculateShippingOptionsPrices(input) | ||
|
||
return new StepResponse(prices) | ||
} | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { FulfillmentWorkflow } from "@medusajs/framework/types" | ||
import { | ||
createWorkflow, | ||
transform, | ||
WorkflowData, | ||
WorkflowResponse, | ||
} from "@medusajs/framework/workflows-sdk" | ||
import { calculateShippingOptionsPricesStep } from "../steps" | ||
import { useQueryGraphStep } from "../../common" | ||
|
||
export const calculateShippingOptionsPricesWorkflowId = | ||
"calculate-shipping-options-prices-workflow" | ||
/** | ||
* This workflow calculates the prices for one or more shipping options. | ||
*/ | ||
export const calculateShippingOptionsPricesWorkflow = createWorkflow( | ||
calculateShippingOptionsPricesWorkflowId, | ||
( | ||
input: WorkflowData<FulfillmentWorkflow.CalculateShippingOptionsPricesWorkflowInput> | ||
): WorkflowResponse<FulfillmentWorkflow.CalculateShippingOptionsPricesWorkflowOutput> => { | ||
const optionIds = transform({ input }, ({ input }) => | ||
input.map(({ shipping_option_id }) => shipping_option_id) | ||
) | ||
|
||
const shippingOptionsQuery = useQueryGraphStep({ | ||
entity: "shipping_option", | ||
filters: { id: optionIds }, | ||
fields: ["id", "provider_id", "data"], | ||
}) | ||
|
||
const data = transform( | ||
{ shippingOptionsQuery }, | ||
({ shippingOptionsQuery }) => { | ||
const shippingOptions = shippingOptionsQuery.data | ||
|
||
return shippingOptions.map((shippingOption) => ({ | ||
id: shippingOption.id, | ||
provider_id: shippingOption.provider_id, | ||
data: shippingOption.data, | ||
context: { | ||
cart: { | ||
id: shippingOption.cart_id, | ||
}, | ||
}, | ||
})) | ||
} | ||
) | ||
|
||
const prices = calculateShippingOptionsPricesStep(data) | ||
|
||
return new WorkflowResponse(prices) | ||
} | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,7 +53,6 @@ export interface IFulfillmentProvider { | |
*/ | ||
calculatePrice( | ||
optionData: Record<string, unknown>, | ||
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. thought: think we still need
For requests that are made prior to adding the shipping method to a cart, the For example:
However, when adding the shipping method to cart and the price is calculated, you might need the data for the calculation. For example:
In your implementation of // pseudo code
calculatePrice() {
if (drop_point_id) {
const acceptPackageSizes = await this.fetchDropPointPackageSizes(drop_point_id)
const price = // one of those package sizes
return price
}
} 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. ahh ok, thanks for clarifying - will revert the changes |
||
data: Record<string, unknown>, | ||
context: Record<string, unknown> | ||
): Promise<CalculatedShippingOptionPrice> | ||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { CalculatedShippingOptionPrice } from "../../fulfillment" | ||
|
||
export type CalculateShippingOptionsPricesWorkflowInput = { | ||
cart_id: string | ||
shipping_option_id: string | ||
}[] | ||
|
||
export type CalculateShippingOptionsPricesWorkflowOutput = | ||
CalculatedShippingOptionPrice[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { HttpTypes } from "@medusajs/framework/types" | ||
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" | ||
import { calculateShippingOptionsPricesWorkflow } from "@medusajs/core-flows" | ||
|
||
import { StoreCalculateShippingOptionPriceType } from "../../validators" | ||
|
||
export const POST = async ( | ||
req: MedusaRequest<StoreCalculateShippingOptionPriceType>, | ||
fPolic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
res: MedusaResponse<HttpTypes.StoreCalculateShippingOptionPriceResponse> | ||
) => { | ||
const { result } = await calculateShippingOptionsPricesWorkflow( | ||
req.scope | ||
).run({ | ||
input: [ | ||
{ | ||
shipping_option_id: req.params.id, | ||
cart_id: req.validatedBody.cart_id, | ||
}, | ||
], | ||
}) | ||
|
||
res.status(200).json(result[0]) | ||
} |
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.
q: is it enough to pass the cart id and the rest of what is needed can be fetched by the provider or should we pass specific customer info, address info etc. (if, for example, a calculated option is used in an RMA flow)
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.
Think we will need more, such as items to calculate prices on product/inventory item dimensions. To be consistent with other providers, we don't want to delegate the responsibility of fetching data from core modules to the provider (yet). This should be a preliminary step and passed to the provider.
Just looping in @srindom – he might have an idea about what we could start with
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.
@fPolic to unblock the PR, here's what I think we will definitely need:
We can add these now and expand in the future in case we need more.