Skip to content

Commit

Permalink
feat: implement calculate SO price endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
fPolic committed Dec 11, 2024
1 parent d8a92db commit 5d36c2c
Show file tree
Hide file tree
Showing 13 changed files with 209 additions and 2 deletions.
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)
}
)
1 change: 1 addition & 0 deletions packages/core/core-flows/src/fulfillment/steps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export * from "./update-fulfillment"
export * from "./update-shipping-profiles"
export * from "./upsert-shipping-options"
export * from "./validate-shipment"
export * from "./calculate-shipping-options-prices"
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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 shippingOptionsQuery = useQueryGraphStep({
entity: "shipping_option",
filters: { id: input.map((i) => i.shipping_option_id) },
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
Expand Up @@ -14,3 +14,4 @@ export * from "./update-fulfillment"
export * from "./update-service-zones"
export * from "./update-shipping-options"
export * from "./update-shipping-profiles"
export * from "./calculate-shipping-options-prices"
29 changes: 29 additions & 0 deletions packages/core/types/src/fulfillment/mutations/shipping-option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,32 @@ export interface UpdateShippingOptionDTO {
* A shipping option to be created or updated.
*/
export interface UpsertShippingOptionDTO extends UpdateShippingOptionDTO {}

/**
* The data needed for the associated fulfillment provider to calculate the price of a shipping option.
*/
export interface CalculateShippingOptionPriceDTO {
/**
* The ID of the shipping option.
*/
id: string

/**
* The ID of the fulfillment provider.
*/
provider_id: string

/**
* The option data from the provider.
*/
data: Record<string, unknown>

/**
* The calculation context needed for the associated fulfillment provider to calculate the price of a shipping option.
*/
context: {
cart: {
id: string
}
} & Record<string, unknown>
}
29 changes: 29 additions & 0 deletions packages/core/types/src/fulfillment/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
ShippingProfileDTO,
} from "./common"
import {
CalculateShippingOptionPriceDTO,
CreateFulfillmentSetDTO,
CreateGeoZoneDTO,
CreateServiceZoneDTO,
Expand All @@ -44,6 +45,7 @@ import {
CreateShippingProfileDTO,
UpsertShippingProfileDTO,
} from "./mutations/shipping-profile"
import { CalculatedShippingOptionPrice } from "./provider"

/**
* The main service interface for the Fulfillment Module.
Expand Down Expand Up @@ -2647,6 +2649,33 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context
): Promise<boolean[]>

/**
* This method calculates the prices for one or more shipping options.
*
* @param {CalculateShippingOptionPriceDTO[]} shippingOptionsData - The shipping options data to calculate the prices for.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<CalculatedShippingOptionPrice[]>} The calculated shipping option prices.
*
* @example
* const prices =
* await fulfillmentModuleService.calculateShippingOptionsPrices(
* [
* {
* provider_id: "webshipper",
* data: {
* cart: {
* id: "cart_123",
* },
* },
* },
* ]
* )
*/
calculateShippingOptionsPrices(
shippingOptionsData: CalculateShippingOptionPriceDTO[],
sharedContext?: Context
): Promise<CalculatedShippingOptionPrice[]>

/**
* This method retrieves a paginated list of fulfillment providers based on optional filters and configuration.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@ import { StoreCartShippingOption } from "../../fulfillment"
export interface StoreShippingOptionListResponse {
shipping_options: StoreCartShippingOption[]
}

export interface StoreCalculateShippingOptionPriceResponse {
calculated_amount: number
is_calculated_price_tax_inclusive: boolean
}
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[]
1 change: 1 addition & 0 deletions packages/core/types/src/workflow/fulfillment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from "./service-zones"
export * from "./shipping-profiles"
export * from "./update-fulfillment"
export * from "./update-shipping-options"
export * from "./calculate-shipping-options-prices"
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>,
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])
}
15 changes: 13 additions & 2 deletions packages/medusa/src/api/store/shipping-options/middlewares.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { MiddlewareRoute } from "@medusajs/framework/http"
import {
MiddlewareRoute,
validateAndTransformBody,
} from "@medusajs/framework/http"
import { validateAndTransformQuery } from "@medusajs/framework"
import { listTransformQueryConfig } from "./query-config"
import { StoreGetShippingOptions } from "./validators"
import {
StoreCalculateShippingOptionPrice,
StoreGetShippingOptions,
} from "./validators"

export const storeShippingOptionRoutesMiddlewares: MiddlewareRoute[] = [
{
Expand All @@ -14,4 +20,9 @@ export const storeShippingOptionRoutesMiddlewares: MiddlewareRoute[] = [
),
],
},
{
method: ["POST"],
matcher: "/store/shipping-options/:id/calculate",
middlewares: [validateAndTransformBody(StoreCalculateShippingOptionPrice)],
},
]
7 changes: 7 additions & 0 deletions packages/medusa/src/api/store/shipping-options/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ export const StoreGetShippingOptions = createFindParams({
})
.merge(StoreGetShippingOptionsFields)
.merge(applyAndAndOrOperators(StoreGetShippingOptionsFields))

export type StoreCalculateShippingOptionPriceType = z.infer<
typeof StoreCalculateShippingOptionPrice
>
export const StoreCalculateShippingOptionPrice = z.object({
cart_id: z.string(),
})
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
CalculatedShippingOptionPrice,
Context,
DAL,
FilterableFulfillmentSetProps,
Expand Down Expand Up @@ -1998,6 +1999,23 @@ export default class FulfillmentModuleService
return await promiseAll(promises)
}

@InjectTransactionManager()
async calculateShippingOptionsPrices(
shippingOptionsData: FulfillmentTypes.CalculateShippingOptionPriceDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<CalculatedShippingOptionPrice[]> {
const promises = shippingOptionsData.map((option) =>
this.fulfillmentProviderService_.calculatePrice(
option.provider_id,
option.data,
option.context,
sharedContext
)
)

return await promiseAll(promises)
}

@InjectTransactionManager()
// @ts-expect-error
async deleteShippingProfiles(
Expand Down

0 comments on commit 5d36c2c

Please sign in to comment.