diff --git a/integration-tests/http/src/utils/providers/fulfillment-manual-calculated/services/manual-fulfillment.ts b/integration-tests/http/src/utils/providers/fulfillment-manual-calculated/services/manual-fulfillment.ts index dcba7c6cc9599..083dc23099769 100644 --- a/integration-tests/http/src/utils/providers/fulfillment-manual-calculated/services/manual-fulfillment.ts +++ b/integration-tests/http/src/utils/providers/fulfillment-manual-calculated/services/manual-fulfillment.ts @@ -41,7 +41,10 @@ export class ManualFulfillmentService extends AbstractFulfillmentProviderService async createFulfillment() { // No data is being sent anywhere - return {} + return { + data: {}, + labels: [], + } } async cancelFulfillment() { @@ -49,6 +52,6 @@ export class ManualFulfillmentService extends AbstractFulfillmentProviderService } async createReturnFulfillment() { - return {} + return { data: {}, labels: [] } } } diff --git a/packages/core/core-flows/src/cart/steps/validate-shipping-methods-data.ts b/packages/core/core-flows/src/cart/steps/validate-shipping-methods-data.ts index ca78740559802..a0040ad0da15b 100644 --- a/packages/core/core-flows/src/cart/steps/validate-shipping-methods-data.ts +++ b/packages/core/core-flows/src/cart/steps/validate-shipping-methods-data.ts @@ -1,8 +1,7 @@ import { Modules, promiseAll } from "@medusajs/framework/utils" import { - CartDTO, IFulfillmentModuleService, - StockLocationDTO, + ValidateFulfillmentDataContext, } from "@medusajs/types" import { createStep, StepResponse } from "@medusajs/workflows-sdk" @@ -11,7 +10,7 @@ export type ValidateShippingMethodsDataInput = { provider_id: string option_data: Record method_data: Record - context: CartDTO & { from_location: StockLocationDTO; [k: string]: unknown } + context: ValidateFulfillmentDataContext }[] export const validateAndReturnShippingMethodsDataStepId = @@ -38,7 +37,7 @@ export const validateAndReturnShippingMethodsDataStep = createStep( option.provider_id, option.option_data, option.method_data, - option.context + option.context as ValidateFulfillmentDataContext ) return { diff --git a/packages/core/types/src/fulfillment/common/cart.ts b/packages/core/types/src/fulfillment/common/cart.ts new file mode 100644 index 0000000000000..d66ce1e175af2 --- /dev/null +++ b/packages/core/types/src/fulfillment/common/cart.ts @@ -0,0 +1,29 @@ +import { CartDTO } from "../.." + +export type CartPropsForFulfillment = { + id: CartDTO["id"] + shipping_address: CartDTO["shipping_address"] + items: CartDTO["items"] & { + variant: { + id: string + weight: number + length: number + height: number + width: number + material: string + product: { + id: string + } + } + product: { + id: string + collection_id: string + categories: { + id: string + }[] + tags: { + id: string + }[] + } + } +} diff --git a/packages/core/types/src/fulfillment/common/index.ts b/packages/core/types/src/fulfillment/common/index.ts index e6d058d9983d0..4f4872305d340 100644 --- a/packages/core/types/src/fulfillment/common/index.ts +++ b/packages/core/types/src/fulfillment/common/index.ts @@ -10,3 +10,5 @@ export * from "./fulfillment-provider" export * from "./fulfillment" export * from "./fulfillment-item" export * from "./fulfillment-label" +export * from "./cart" +export * from "./order" diff --git a/packages/core/types/src/fulfillment/common/order.ts b/packages/core/types/src/fulfillment/common/order.ts new file mode 100644 index 0000000000000..a2a5fe8518762 --- /dev/null +++ b/packages/core/types/src/fulfillment/common/order.ts @@ -0,0 +1,1176 @@ +import { BigNumberRawValue, BigNumberValue } from "../../totals" + +/** + * The order's status. + */ +type FulfillmentOrderStatus = + | "pending" + | "completed" + | "draft" + | "archived" + | "canceled" + | "requires_action" + +export interface FulfillmentOrderDTO { + /** + * The ID of the order. + */ + id: string + + /** + * The version of the order. + */ + version: number + + /** + * The order's display ID. + */ + display_id: number + + /** + * The status of the order. + */ + status: FulfillmentOrderStatus + + /** + * The ID of the region the order belongs to. + */ + region_id?: string + + /** + * The ID of the customer on the order. + */ + customer_id?: string + + /** + * The ID of the sales channel the order belongs to. + */ + sales_channel_id?: string + + /** + * The email of the order. + */ + email?: string + + /** + * The currency of the order + */ + currency_code: string + + /** + * The associated shipping address. + * + * @expandable + */ + shipping_address?: FulfillmentOrderAddressDTO + + /** + * The associated billing address. + * + * @expandable + */ + billing_address?: FulfillmentOrderAddressDTO + + /** + * The associated order details / line items. + * + * @expandable + */ + items?: FulfillmentOrderLineItemDTO[] + + /** + * The associated shipping methods + * + * @expandable + */ + shipping_methods?: FulfillmentOrderShippingMethodDTO[] + + /** + * The summary of the order totals. + * + * @expandable + */ + summary?: FulfillmentOrderSummaryDTO + + /** + * Holds custom data in key-value pairs. + */ + metadata?: Record | null + + /** + * When the order was canceled. + */ + canceled_at?: string | Date + + /** + * When the order was created. + */ + created_at: string | Date + + /** + * When the order was updated. + */ + updated_at: string | Date + + /** + * The original item total of the order. + */ + original_item_total: BigNumberValue + + /** + * The original item subtotal of the order. + */ + original_item_subtotal: BigNumberValue + + /** + * The original item tax total of the order. + */ + original_item_tax_total: BigNumberValue + + /** + * The item total of the order. + */ + item_total: BigNumberValue + + /** + * The item subtotal of the order. + */ + item_subtotal: BigNumberValue + + /** + * The item tax total of the order. + */ + item_tax_total: BigNumberValue + + /** + * The original total of the order. + */ + original_total: BigNumberValue + + /** + * The original subtotal of the order. + */ + original_subtotal: BigNumberValue + + /** + * The original tax total of the order. + */ + original_tax_total: BigNumberValue + + /** + * The total of the order. + */ + total: BigNumberValue + + /** + * The subtotal of the order. (Excluding taxes) + */ + subtotal: BigNumberValue + + /** + * The tax total of the order. + */ + tax_total: BigNumberValue + + /** + * The discount subtotal of the order. + */ + discount_subtotal: BigNumberValue + + /** + * The discount total of the order. + */ + discount_total: BigNumberValue + + /** + * The discount tax total of the order. + */ + discount_tax_total: BigNumberValue + + /** + * The gift card total of the order. + */ + gift_card_total: BigNumberValue + + /** + * The gift card tax total of the order. + */ + gift_card_tax_total: BigNumberValue + + /** + * The shipping total of the order. + */ + shipping_total: BigNumberValue + + /** + * The shipping subtotal of the order. + */ + shipping_subtotal: BigNumberValue + + /** + * The shipping tax total of the order. + */ + shipping_tax_total: BigNumberValue + + /** + * The original shipping total of the order. + */ + original_shipping_total: BigNumberValue + + /** + * The original shipping subtotal of the order. + */ + original_shipping_subtotal: BigNumberValue + + /** + * The original shipping tax total of the order. + */ + original_shipping_tax_total: BigNumberValue + + /** + * The raw original item total of the order. + * + * @ignore + */ + raw_original_item_total: BigNumberRawValue + + /** + * The raw original item subtotal of the order. + * + * @ignore + */ + raw_original_item_subtotal: BigNumberRawValue + + /** + * The raw original item tax total of the order. + * + * @ignore + */ + raw_original_item_tax_total: BigNumberRawValue + + /** + * The raw item total of the order. + * + * @ignore + */ + raw_item_total: BigNumberRawValue + + /** + * The raw item subtotal of the order. + * + * @ignore + */ + raw_item_subtotal: BigNumberRawValue + + /** + * The raw item tax total of the order. + * + * @ignore + */ + raw_item_tax_total: BigNumberRawValue + + /** + * The raw original total of the order. + * + * @ignore + */ + raw_original_total: BigNumberRawValue + + /** + * The raw original subtotal of the order. + * + * @ignore + */ + raw_original_subtotal: BigNumberRawValue + + /** + * The raw original tax total of the order. + * + * @ignore + */ + raw_original_tax_total: BigNumberRawValue + + /** + * The raw total of the order. + * + * @ignore + */ + raw_total: BigNumberRawValue + + /** + * The raw subtotal of the order. (Excluding taxes) + * + * @ignore + */ + raw_subtotal: BigNumberRawValue + + /** + * The raw tax total of the order. + * + * @ignore + */ + raw_tax_total: BigNumberRawValue + + /** + * The raw discount total of the order. + * + * @ignore + */ + raw_discount_total: BigNumberRawValue + + /** + * The raw discount tax total of the order. + * + * @ignore + */ + raw_discount_tax_total: BigNumberRawValue + + /** + * The raw gift card total of the order. + * + * @ignore + */ + raw_gift_card_total: BigNumberRawValue + + /** + * The raw gift card tax total of the order. + * + * @ignore + */ + raw_gift_card_tax_total: BigNumberRawValue + + /** + * The raw shipping total of the order. + * + * @ignore + */ + raw_shipping_total: BigNumberRawValue + + /** + * The raw shipping subtotal of the order. + * + * @ignore + */ + raw_shipping_subtotal: BigNumberRawValue + + /** + * The raw shipping tax total of the order. + * + * @ignore + */ + raw_shipping_tax_total: BigNumberRawValue + + /** + * The raw original shipping total of the order. + * + * @ignore + */ + raw_original_shipping_total: BigNumberRawValue + + /** + * The raw original shipping subtotal of the order. + * + * @ignore + */ + raw_original_shipping_subtotal: BigNumberRawValue + + /** + * The raw original shipping tax total of the order. + * + * @ignore + */ + raw_original_shipping_tax_total: BigNumberRawValue +} + +/** + * The address details. + */ +interface FulfillmentOrderAddressDTO { + /** + * The ID of the address. + */ + id: string + + /** + * The customer ID of the address. + */ + customer_id?: string + + /** + * The first name of the address. + */ + first_name?: string + + /** + * The last name of the address. + */ + last_name?: string + + /** + * The phone number of the address. + */ + phone?: string + + /** + * The company of the address. + */ + company?: string + + /** + * The first address line of the address. + */ + address_1?: string + + /** + * The second address line of the address. + */ + address_2?: string + + /** + * The city of the address. + */ + city?: string + + /** + * The country code of the address. + */ + country_code?: string + + /** + * The province/state of the address. + */ + province?: string + + /** + * The postal code of the address. + */ + postal_code?: string + + /** + * Holds custom data in key-value pairs. + */ + metadata?: Record | null + + /** + * When the address was created. + */ + created_at: Date | string + + /** + * When the address was updated. + */ + updated_at: Date | string +} + +/** + * The order line item totals details. + */ +interface FulfillmentOrderLineItemTotalsDTO { + /** + * The original total of the order line item. + */ + original_total: BigNumberValue + + /** + * The original subtotal of the order line item. + */ + original_subtotal: BigNumberValue + + /** + * The original tax total of the order line item. + */ + original_tax_total: BigNumberValue + + /** + * The item total of the order line item. + */ + item_total: BigNumberValue + + /** + * The item subtotal of the order line item. + */ + item_subtotal: BigNumberValue + + /** + * The item tax total of the order line item. + */ + item_tax_total: BigNumberValue + + /** + * The total of the order line item. + */ + total: BigNumberValue + + /** + * The subtotal of the order line item. + */ + subtotal: BigNumberValue + + /** + * The tax total of the order line item. + */ + tax_total: BigNumberValue + + /** + * The discount total of the order line item. + */ + discount_total: BigNumberValue + + /** + * The discount tax total of the order line item. + */ + discount_tax_total: BigNumberValue + + /** + * The refundable total of the order line item. + */ + refundable_total: BigNumberValue + + /** + * The refundable total per unit of the order line item. + */ + refundable_total_per_unit: BigNumberValue + + /** + * The raw original total of the order line item. + * + * @ignore + */ + raw_original_total: BigNumberRawValue + + /** + * The raw original subtotal of the order line item. + * + * @ignore + */ + raw_original_subtotal: BigNumberRawValue + + /** + * The raw original tax total of the order line item. + * + * @ignore + */ + raw_original_tax_total: BigNumberRawValue + + /** + * The raw item total of the order line item. + * + * @ignore + */ + raw_item_total: BigNumberRawValue + + /** + * The raw item subtotal of the order line item. + * + * @ignore + */ + raw_item_subtotal: BigNumberRawValue + + /** + * The raw item tax total of the order line item. + * + * @ignore + */ + raw_item_tax_total: BigNumberRawValue + + /** + * The raw total of the order line item. + * + * @ignore + */ + raw_total: BigNumberRawValue + + /** + * The raw subtotal of the order line item. + * + * @ignore + */ + raw_subtotal: BigNumberRawValue + + /** + * The raw tax total of the order line item. + * + * @ignore + */ + raw_tax_total: BigNumberRawValue + + /** + * The raw discount total of the order line item. + * + * @ignore + */ + raw_discount_total: BigNumberRawValue + + /** + * The raw discount tax total of the order line item. + * + * @ignore + */ + raw_discount_tax_total: BigNumberRawValue + + /** + * The raw refundable total of the order line item.. + * + * @ignore + */ + raw_refundable_total: BigNumberRawValue + + /** + * The raw refundable total per unit of the order line item. + * + * @ignore + */ + raw_refundable_total_per_unit: BigNumberRawValue +} + +/** + * The line item details. + */ +interface FulfillmentOrderLineItemDTO + extends FulfillmentOrderLineItemTotalsDTO { + /** + * The ID of the line item. + */ + id: string + + /** + * The title of the line item. + */ + title: string + + /** + * The subtitle of the line item. + */ + subtitle?: string | null + + /** + * The thumbnail of the line item. + */ + thumbnail?: string | null + + /** + * The ID of the variant associated with the line item. + */ + variant_id?: string | null + + /** + * The ID of the product associated with the line item. + */ + product_id?: string | null + + /** + * The title of the product associated with the line item. + */ + product_title?: string | null + + /** + * The description of the product associated with the line item. + */ + product_description?: string | null + + /** + * The subtitle of the product associated with the line item. + */ + product_subtitle?: string | null + + /** + * The ID of the type of the product associated with the line item. + */ + product_type_id?: string | null + + /** + * The type of the product associated with the line item. + */ + product_type?: string | null + + /** + * The collection of the product associated with the line item. + */ + product_collection?: string | null + + /** + * The handle of the product associated with the line item. + */ + product_handle?: string | null + + /** + * The SKU (stock keeping unit) of the variant associated with the line item. + */ + variant_sku?: string | null + + /** + * The barcode of the variant associated with the line item. + */ + variant_barcode?: string | null + + /** + * The title of the variant associated with the line item. + */ + variant_title?: string | null + + /** + * The option values of the variant associated with the line item. + */ + variant_option_values?: Record | null + + /** + * Indicates whether the line item requires shipping. + */ + requires_shipping: boolean + + /** + * Indicates whether the line item is discountable. + */ + is_discountable: boolean + + /** + * Indicates whether the line item price is tax inclusive. + */ + is_tax_inclusive: boolean + + /** + * The compare at unit price of the line item. + */ + compare_at_unit_price?: number + + /** + * The raw compare at unit price of the line item. + * + * @ignore + */ + raw_compare_at_unit_price?: BigNumberRawValue + + /** + * The unit price of the line item. + */ + unit_price: number + + /** + * The raw unit price of the line item. + * + * @ignore + */ + raw_unit_price: BigNumberRawValue + + /** + * The quantity of the line item. + */ + quantity: number + + /** + * The raw quantity of the line item. + * + * @ignore + */ + raw_quantity: BigNumberRawValue + + /** + * The details of the item + */ + detail: FulfillmentOrderItemDTO + + /** + * The date when the line item was created. + */ + created_at: Date + + /** + * The date when the line item was last updated. + */ + updated_at: Date + + /** + * Holds custom data in key-value pairs. + */ + metadata?: Record | null +} + +/** + * The order item details. + */ +interface FulfillmentOrderItemDTO { + /** + * The ID of the order item. + */ + id: string + + /** + * The ID of the associated item. + */ + item_id: string + + /** + * The associated line item. + * + * @expandable + */ + item: FulfillmentOrderLineItemDTO + + /** + * The quantity of the order line item. + */ + quantity: number + + /** + * The raw quantity of the order line item. + * + * @ignore + */ + raw_quantity: BigNumberRawValue + + /** + * The fulfilled quantity of the order line item. + */ + fulfilled_quantity: number + + /** + * The raw fulfilled quantity of the order line item. + * + * @ignore + */ + raw_fulfilled_quantity: BigNumberRawValue + + /** + * The delivered quantity of the order line item. + */ + delivered_quantity: number + + /** + * The raw delivered quantity of the order line item. + * + * @ignore + */ + raw_delivered_quantity: BigNumberRawValue + + /** + * The shipped quantity of the order line item. + */ + shipped_quantity: number + + /** + * The raw shipped quantity of the order line item. + * + * @ignore + */ + raw_shipped_quantity: BigNumberRawValue + + /** + * The quantity of return requested for the order line item. + */ + return_requested_quantity: number + + /** + * The raw quantity of return requested for the order line item. + * + * @ignore + */ + raw_return_requested_quantity: BigNumberRawValue + + /** + * The quantity of return received for the order line item. + */ + return_received_quantity: number + + /** + * The raw quantity of return received for the order line item. + * + * @ignore + */ + raw_return_received_quantity: BigNumberRawValue + + /** + * The quantity of return dismissed for the order line item. + */ + return_dismissed_quantity: number + + /** + * The raw quantity of return dismissed for the order line item. + * + * @ignore + */ + raw_return_dismissed_quantity: BigNumberRawValue + + /** + * The quantity of written off for the order line item. + */ + written_off_quantity: number + + /** + * The raw quantity of written off for the order line item. + * + * @ignore + */ + raw_written_off_quantity: BigNumberRawValue + + /** + * The metadata of the order detail + */ + metadata: Record | null + + /** + * The date when the order line item was created. + */ + created_at: Date + + /** + * The date when the order line item was last updated. + */ + updated_at: Date +} + +/** + * The order shipping method details. + */ +interface FulfillmentOrderShippingMethodDTO { + /** + * The ID of the shipping method. + */ + id: string + + /** + * The ID of the associated order. + */ + order_id: string + + /** + * The name of the shipping method. + */ + name: string + + /** + * The description of the shipping method. + */ + description?: string + + /** + * The price of the shipping method. + */ + amount: BigNumberValue + + /** + * The raw price of the shipping method. + * + * @ignore + */ + raw_amount: BigNumberRawValue + + /** + * Whether the shipping method price is tax inclusive or not. + */ + is_tax_inclusive: boolean + + /** + * The ID of the shipping option the method was created from. + */ + shipping_option_id?: string + + /** + * Additional data needed for fulfillment. + */ + data?: Record + + /** + * Holds custom data in key-value pairs. + */ + metadata?: Record | null + + /** + * When the shipping method was created. + */ + created_at: Date | string + + /** + * When the shipping method was updated. + */ + updated_at: Date | string + + /** + * The original total of the order shipping method. + */ + original_total: BigNumberValue + + /** + * The original subtotal of the order shipping method. + */ + original_subtotal: BigNumberValue + + /** + * The original tax total of the order shipping method. + */ + original_tax_total: BigNumberValue + + /** + * The total of the order shipping method. + */ + total: BigNumberValue + + /** + * The subtotal of the order shipping method. + */ + subtotal: BigNumberValue + + /** + * The tax total of the order shipping method. + */ + tax_total: BigNumberValue + + /** + * The discount total of the order shipping method. + */ + discount_total: BigNumberValue + + /** + * The discount tax total of the order shipping method. + */ + discount_tax_total: BigNumberValue + + /** + * The raw original total of the order shipping method. + * + * @ignore + */ + raw_original_total: BigNumberRawValue + + /** + * The raw original subtotal of the order shipping method. + * + * @ignore + */ + raw_original_subtotal: BigNumberRawValue + + /** + * The raw original tax total of the order shipping method. + * + * @ignore + */ + raw_original_tax_total: BigNumberRawValue + + /** + * The raw total of the order shipping method. + * + * @ignore + */ + raw_total: BigNumberRawValue + + /** + * The raw subtotal of the order shipping method. + * + * @ignore + */ + raw_subtotal: BigNumberRawValue + + /** + * The raw tax total of the order shipping method. + * + * @ignore + */ + raw_tax_total: BigNumberRawValue + + /** + * The raw discount total of the order shipping method. + * + * @ignore + */ + raw_discount_total: BigNumberRawValue + + /** + * The raw discount tax total of the order shipping method. + * + * @ignore + */ + raw_discount_tax_total: BigNumberRawValue +} + +/** + * @interface + * + * The order summary details. + */ +type FulfillmentOrderSummaryDTO = { + /** + * The total of the order summary. + */ + total: BigNumberValue + + /** + * The subtotal of the order summary. + */ + subtotal: BigNumberValue + + /** + * The total tax of the order summary. + */ + total_tax: BigNumberValue + + /** + * The ordered total of the order summary. + */ + ordered_total: BigNumberValue + + /** + * The fulfilled total of the order summary. + */ + fulfilled_total: BigNumberValue + + /** + * The returned total of the order summary. + */ + returned_total: BigNumberValue + + /** + * The return request total of the order summary. + */ + return_request_total: BigNumberValue + + /** + * The write off total of the order summary. + */ + write_off_total: BigNumberValue + + /** + * The projected total of the order summary. + */ + projected_total: BigNumberValue + + /** + * The net total of the order summary. + */ + net_total: BigNumberValue + + /** + * The net subtotal of the order summary. + */ + net_subtotal: BigNumberValue + + /** + * The net total tax of the order summary. + */ + net_total_tax: BigNumberValue + + /** + * The balance of the order summary. + */ + balance: BigNumberValue + + /** + * The paid total of the order summary. + */ + paid_total: BigNumberValue + + /** + * The refunded total of the order summary. + */ + refunded_total: BigNumberValue + + /** + * The pending difference of the order. + */ + pending_difference: BigNumberValue + + /** + * The raw pending difference of the order. + * + * @ignore + */ + raw_pending_difference: BigNumberRawValue +} diff --git a/packages/core/types/src/fulfillment/mutations/shipping-option.ts b/packages/core/types/src/fulfillment/mutations/shipping-option.ts index 3f76237281876..bdeeb429c75e2 100644 --- a/packages/core/types/src/fulfillment/mutations/shipping-option.ts +++ b/packages/core/types/src/fulfillment/mutations/shipping-option.ts @@ -1,7 +1,6 @@ import { CreateShippingOptionTypeDTO } from "./shipping-option-type" -import { ShippingOptionPriceType } from "../common" +import { CartPropsForFulfillment, ShippingOptionPriceType } from "../common" import { CreateShippingOptionRuleDTO } from "./shipping-option-rule" -import { CartDTO } from "../../cart" import { StockLocationDTO } from "../../stock-location" /** @@ -148,13 +147,17 @@ export interface CalculateShippingOptionPriceDTO { /** * The calculation context needed for the associated fulfillment provider to calculate the price of a shipping option. */ - context: CartDTO & { + context: CartPropsForFulfillment & { /** * The location that the items will be shipped from. */ from_location?: StockLocationDTO - } & Record< - string, - unknown - > + [k: string]: unknown + } } + +/** + * The calculation context needed for the associated fulfillment provider to calculate the price of a shipping option. + */ +export type CalculateShippingOptionPriceContext = + CalculateShippingOptionPriceDTO["context"] diff --git a/packages/core/types/src/fulfillment/provider.ts b/packages/core/types/src/fulfillment/provider.ts index 5fdbe94c16273..ee4e55f2821ee 100644 --- a/packages/core/types/src/fulfillment/provider.ts +++ b/packages/core/types/src/fulfillment/provider.ts @@ -1,4 +1,15 @@ -import { CalculateShippingOptionPriceDTO } from "./mutations" +import { StockLocationDTO } from "../stock-location" +import { + CartPropsForFulfillment, + FulfillmentDTO, + FulfillmentItemDTO, + FulfillmentOrderDTO, +} from "./common" +import { + CalculateShippingOptionPriceContext, + CalculateShippingOptionPriceDTO, + CreateShippingOptionDTO, +} from "./mutations" export type FulfillmentOption = { /** @@ -28,6 +39,37 @@ export type CalculatedShippingOptionPrice = { is_calculated_price_tax_inclusive: boolean } +export type ValidateFulfillmentDataContext = CartPropsForFulfillment & { + /** + * Details about the location that items are being shipped from. + */ + from_location: StockLocationDTO + [k: string]: unknown +} + +export type CreateFulfillmentResult = { + /** + * Additional fulfillment data from provider + */ + data: Record + labels: { + /** + * The tracking number of the fulfillment label. + */ + tracking_number: string + + /** + * The tracking URL of the fulfillment label. + */ + tracking_url: string + + /** + * The label's URL. + */ + label_url: string + }[] +} + export interface IFulfillmentProvider { /** * @@ -46,7 +88,7 @@ export interface IFulfillmentProvider { validateFulfillmentData( optionData: Record, data: Record, - context: Record + context: ValidateFulfillmentDataContext ): Promise /** * @@ -57,7 +99,7 @@ export interface IFulfillmentProvider { * * Check if the provider can calculate the fulfillment price. */ - canCalculate(data: Record): Promise + canCalculate(data: CreateShippingOptionDTO): Promise /** * * Calculate the price for the given fulfillment option. @@ -65,18 +107,18 @@ export interface IFulfillmentProvider { calculatePrice( optionData: CalculateShippingOptionPriceDTO["optionData"], data: CalculateShippingOptionPriceDTO["data"], - context: CalculateShippingOptionPriceDTO["context"] + context: CalculateShippingOptionPriceContext ): Promise /** * * Create a fulfillment for the given data. */ createFulfillment( - data: object, - items: object[], - order: object | undefined, - fulfillment: Record - ): Promise> + data: Record, + items: Partial>[], + order: Partial | undefined, + fulfillment: Partial> + ): Promise /** * * Cancel the given fulfillment. @@ -91,7 +133,9 @@ export interface IFulfillmentProvider { * * Create a return for the given data. */ - createReturnFulfillment(fromData: Record): Promise + createReturnFulfillment( + fromData: Record + ): Promise /** * * Get the documents for the given return data. diff --git a/packages/core/types/src/fulfillment/service.ts b/packages/core/types/src/fulfillment/service.ts index 316e295a847e0..b7b063bac6a74 100644 --- a/packages/core/types/src/fulfillment/service.ts +++ b/packages/core/types/src/fulfillment/service.ts @@ -45,7 +45,10 @@ import { CreateShippingProfileDTO, UpsertShippingProfileDTO, } from "./mutations/shipping-profile" -import { CalculatedShippingOptionPrice } from "./provider" +import { + CalculatedShippingOptionPrice, + ValidateFulfillmentDataContext, +} from "./provider" /** * The main service interface for the Fulfillment Module. @@ -2595,7 +2598,7 @@ export interface IFulfillmentModuleService extends IModuleService { * @param {string} providerId - The fulfillment provider's ID. * @param {Record} optionData - The fulfillment option data to validate. * @param {Record} data - The fulfillment data to validate. - * @param {Record} context - The context to validate the fulfillment option data in. + * @param {ValidateFulfillmentDataContext} context - The context to validate the fulfillment option data in. * @returns {Promise} Whether the fulfillment option data is valid with the specified provider. * * @example @@ -2615,7 +2618,7 @@ export interface IFulfillmentModuleService extends IModuleService { providerId: string, optionData: Record, data: Record, - context: Record + context: ValidateFulfillmentDataContext ): Promise> /** diff --git a/packages/core/utils/src/fulfillment/provider.ts b/packages/core/utils/src/fulfillment/provider.ts index 46c7ed4b9300d..9524c6f611980 100644 --- a/packages/core/utils/src/fulfillment/provider.ts +++ b/packages/core/utils/src/fulfillment/provider.ts @@ -1,14 +1,20 @@ import { CalculatedShippingOptionPrice, CalculateShippingOptionPriceDTO, + CreateFulfillmentResult, + CreateShippingOptionDTO, + FulfillmentDTO, + FulfillmentItemDTO, FulfillmentOption, + FulfillmentOrderDTO, IFulfillmentProvider, + ValidateFulfillmentDataContext, } from "@medusajs/types" /** * ### constructor * - * The constructor allows you to access resources from the [module's container](https://docs.medusajs.com/learn/fundamentals/modules/container) + * The constructor allows you to access resources from the [module's container](https://docs.medusajs.com/learn/fundamentals/modules/container) * using the first parameter, and the module's options using the second parameter. * * :::note @@ -48,7 +54,7 @@ import { * * this.logger_ = logger * this.options_ = options - * + * * // TODO initialize your client * } * } @@ -96,7 +102,7 @@ export class AbstractFulfillmentProviderService * This method retrieves a list of fulfillment options that this provider supports. Admin users will then choose from these options when * they're creating a shipping option. The chosen fulfillment option's object is then stored within the created shipping option's `data` property. * The `data` property is useful to store data relevant for the third-party provider to later process the fulfillment. - * + * * This method is useful if your third-party provider allows you to retrieve support options, carriers, or services from an API. You can then * retrieve those and return then in the method, allowing the admin user to choose from the services provided by the third-party provider. * @@ -112,7 +118,7 @@ export class AbstractFulfillmentProviderService * async getFulfillmentOptions(): Promise { * // assuming you have a client * const services = await this.client.getServices() - * + * * return services.map((service) => ({ * id: service.service_id, * name: service.name, @@ -161,7 +167,7 @@ export class AbstractFulfillmentProviderService async validateFulfillmentData( optionData: Record, data: Record, - context: Record + context: ValidateFulfillmentDataContext ): Promise { throw Error("validateFulfillmentData must be overridden by the child class") } @@ -190,7 +196,7 @@ export class AbstractFulfillmentProviderService /** * This method validates whether a shippin option's price can be calculated during checkout. It's executed when the admin user creates a shipping * option of type `calculated`. If this method returns `false`, an error is thrown as the shipping option's price can't be calculated. - * + * * You can perform the checking using the third-party provider if applicable. The `data` parameter will hold the shipping option's `data` property, which * includes the data of a fulfillment option returned by {@link getFulfillmentOptions}. * @@ -200,26 +206,26 @@ export class AbstractFulfillmentProviderService * @example * class MyFulfillmentProviderService extends AbstractFulfillmentProviderService { * // ... - * async canCalculate(data: Record): Promise { + * async canCalculate(data: CreateShippingOptionDTO): Promise { * // assuming you have a client * return await this.client.hasRates(data.id) * } * } */ - async canCalculate(data: Record): Promise { + async canCalculate(data: CreateShippingOptionDTO): Promise { throw Error("canCalculate must be overridden by the child class") } /** * This method calculates the price of a shipping method when it's created or its cart is refreshed. - * - * In this method, you can send a request to your third-party provider to retrieve the prices. The first - * parameters holds the `data` property of the shipping method's shipping option, which has fulfillment + * + * In this method, you can send a request to your third-party provider to retrieve the prices. The first + * parameters holds the `data` property of the shipping method's shipping option, which has fulfillment * object data returned by {@link getFulfillmentOptions}. - * + * * The second parameter holds the `data` property of the shipping method, which has data returned by {@link validateFulfillmentData}. * It can also hold custom data passed from the frontend during checkout. - * + * * So, using both of these data, assuming you're storing in them data related to the third-party service, * you can retrieve the calculated price of the shipping method. * @@ -281,7 +287,7 @@ export class AbstractFulfillmentProviderService * items: any, * order: any, * fulfillment: any - * ): Promise { + * ): Promise { * // assuming the client creates a fulfillment * // in the third-party service * const externalData = await this.client.create( @@ -299,11 +305,11 @@ export class AbstractFulfillmentProviderService * } */ async createFulfillment( - data: object, - items: object[], - order: object | undefined, - fulfillment: Record - ): Promise { + data: Record, + items: Partial>[], + order: Partial | undefined, + fulfillment: Partial> + ): Promise { throw Error("createFulfillment must be overridden by the child class") } @@ -362,12 +368,12 @@ export class AbstractFulfillmentProviderService * purchasing a label for the return fulfillment. * * @param fulfillment - The fulfillment's details. - * @returns An object whose `data` property is stored in the fulfillment's `data` property. + * @returns An object containing `data` which is stored in the fulfillment's `data` property and `labels` array which is used to create FulfillmentLabels. * * @example * class MyFulfillmentProviderService extends AbstractFulfillmentProviderService { * // ... - * async createReturnFulfillment(fulfillment: Record): Promise { + * async createReturnFulfillment(fulfillment: Record): Promise { * // assuming the client creates a fulfillment for a return * // in the third-party service * const externalData = await this.client.createReturn( @@ -385,7 +391,7 @@ export class AbstractFulfillmentProviderService */ async createReturnFulfillment( fulfillment: Record - ): Promise { + ): Promise { throw Error("createReturn must be overridden by the child class") } diff --git a/packages/modules/fulfillment/src/services/fulfillment-module-service.ts b/packages/modules/fulfillment/src/services/fulfillment-module-service.ts index f5f8652bbd239..936aa337cfead 100644 --- a/packages/modules/fulfillment/src/services/fulfillment-module-service.ts +++ b/packages/modules/fulfillment/src/services/fulfillment-module-service.ts @@ -17,6 +17,7 @@ import { SoftDeleteReturn, UpdateFulfillmentSetDTO, UpdateServiceZoneDTO, + ValidateFulfillmentDataContext, } from "@medusajs/framework/types" import { arrayDifference, @@ -650,7 +651,7 @@ export default class FulfillmentModuleService fulfillmentData || {}, items.map((i) => i), order, - fulfillmentRest + fulfillmentRest as unknown as Partial ) await this.fulfillmentService_.update( { @@ -710,11 +711,22 @@ export default class FulfillmentModuleService sharedContext ) + const shippingOption = await this.shippingOptionService_.retrieve( + fulfillment.shipping_option_id!, + { + select: ["id", "name", "data", "metadata"], + }, + sharedContext + ) + try { const providerResult = await this.fulfillmentProviderService_.createReturn( fulfillment.provider_id!, // TODO: should we add a runtime check on provider_id being provided?, - fulfillment as Record + { + ...fulfillment, + shipping_option: shippingOption, + } as Record ) await this.fulfillmentService_.update( { @@ -2002,7 +2014,7 @@ export default class FulfillmentModuleService providerId: string, optionData: Record, data: Record, - context: Record + context: ValidateFulfillmentDataContext ): Promise> { return await this.fulfillmentProviderService_.validateFulfillmentData( providerId, @@ -2012,6 +2024,7 @@ export default class FulfillmentModuleService ) } + // TODO: seems not to be used, what is the purpose of this method? async validateFulfillmentOption( providerId: string, data: Record @@ -2058,10 +2071,7 @@ export default class FulfillmentModuleService } const promises = shippingOptionsData.map((option) => - this.fulfillmentProviderService_.canCalculate( - option.provider_id, - option as unknown as Record - ) + this.fulfillmentProviderService_.canCalculate(option.provider_id, option) ) return await promiseAll(promises) diff --git a/packages/modules/fulfillment/src/services/fulfillment-provider.ts b/packages/modules/fulfillment/src/services/fulfillment-provider.ts index f61a6625b473f..f667ed29454de 100644 --- a/packages/modules/fulfillment/src/services/fulfillment-provider.ts +++ b/packages/modules/fulfillment/src/services/fulfillment-provider.ts @@ -1,11 +1,17 @@ import { CalculateShippingOptionPriceDTO, Constructor, + CreateFulfillmentResult, + CreateShippingOptionDTO, DAL, + FulfillmentDTO, + FulfillmentItemDTO, FulfillmentOption, + FulfillmentOrderDTO, FulfillmentTypes, IFulfillmentProvider, Logger, + ValidateFulfillmentDataContext, } from "@medusajs/framework/types" import { MedusaError, @@ -91,7 +97,7 @@ export default class FulfillmentProviderService extends ModulesSdkUtils.MedusaIn providerId: string, optionData: Record, data: Record, - context: Record + context: ValidateFulfillmentDataContext ) { const provider = this.retrieveProviderRegistration(providerId) return await provider.validateFulfillmentData(optionData, data, context) @@ -102,7 +108,7 @@ export default class FulfillmentProviderService extends ModulesSdkUtils.MedusaIn return await provider.validateOption(data) } - async canCalculate(providerId: string, data: Record) { + async canCalculate(providerId: string, data: CreateShippingOptionDTO) { const provider = this.retrieveProviderRegistration(providerId) return await provider.canCalculate(data) } @@ -119,11 +125,11 @@ export default class FulfillmentProviderService extends ModulesSdkUtils.MedusaIn async createFulfillment( providerId: string, - data: object, - items: object[], - order: object | undefined, - fulfillment: Record - ): Promise> { + data: Record, + items: Partial>[], + order: Partial | undefined, + fulfillment: Partial> + ): Promise { const provider = this.retrieveProviderRegistration(providerId) return await provider.createFulfillment(data, items, order, fulfillment) } diff --git a/packages/modules/providers/fulfillment-manual/src/services/manual-fulfillment.ts b/packages/modules/providers/fulfillment-manual/src/services/manual-fulfillment.ts index d560a4e051d80..814e1cf40543b 100644 --- a/packages/modules/providers/fulfillment-manual/src/services/manual-fulfillment.ts +++ b/packages/modules/providers/fulfillment-manual/src/services/manual-fulfillment.ts @@ -1,7 +1,10 @@ import { AbstractFulfillmentProviderService } from "@medusajs/framework/utils" import { CalculatedShippingOptionPrice, + CalculateShippingOptionPriceContext, + CreateFulfillmentResult, FulfillmentOption, + ValidateFulfillmentDataContext, } from "@medusajs/types" // TODO rework type and DTO's @@ -28,7 +31,7 @@ export class ManualFulfillmentService extends AbstractFulfillmentProviderService async validateFulfillmentData( optionData: Record, data: Record, - context: Record + context: ValidateFulfillmentDataContext ): Promise { return data } @@ -36,7 +39,7 @@ export class ManualFulfillmentService extends AbstractFulfillmentProviderService async calculatePrice( optionData: Record, data: Record, - context: Record + context: CalculateShippingOptionPriceContext ): Promise { throw new Error("Manual fulfillment does not support price calculation") } @@ -49,16 +52,22 @@ export class ManualFulfillmentService extends AbstractFulfillmentProviderService return true } - async createFulfillment(): Promise> { + async createFulfillment(): Promise { // No data is being sent anywhere - return {} + return { + data: {}, + labels: [], + } } async cancelFulfillment(): Promise { return {} } - async createReturnFulfillment(): Promise { - return {} + async createReturnFulfillment(): Promise { + return { + data: {}, + labels: [], + } } }