Feat(fulfillment): service provider registration + fulfillment management (#6524)

**What**
- Create the fulfillment manual package with a first iteration API 
- Create a new `AbstractFulfillmentProviderService` and `IFulfillmentProvider`
- Modify the module service interface to add new methods to manipulate the fulfillment and the communication with the external provider
  - create (no bulk)
  - cancel (no bulk)
  - update (no bulk)
  - list
  - listAndCount
  - retrieve
- Add new methods to the service provider service to include communication with the third party provider
  - get options
  - create
  - cancel
  - validate data
  - validate option
- Update/create interfaces and DTO's
- fix repository serializer to allow non entity to be passed without throwing
- split module tests into multiple files to simplify navigation
- Add integration tests to validate fulfillments manipulation and external provider loading + communication

FIXES CORE-1729
FIXES CORE-1785
FIXES CORE-1784
FIXES CORE-1766
This commit is contained in:
Adrien de Peretti
2024-03-05 11:11:14 +00:00
committed by GitHub
parent f9ef37a2f2
commit 62a7bcc30c
55 changed files with 4066 additions and 2749 deletions
@@ -3,6 +3,7 @@ import { ServiceProviderDTO } from "./service-provider"
import { FulfillmentAddressDTO } from "./address"
import { FulfillmentItemDTO } from "./fulfillment-item"
import { FulfillmentLabelDTO } from "./fulfillment-label"
import { BaseFilterable, OperatorMap } from "../../dal"
export interface FulfillmentDTO {
id: string
@@ -24,3 +25,17 @@ export interface FulfillmentDTO {
updated_at: Date
deleted_at: Date | null
}
export interface FilterableFulfillmentProps
extends BaseFilterable<FilterableFulfillmentProps> {
id?: string | string[] | OperatorMap<string | string[]>
location_id?: string | string[] | OperatorMap<string | string[]>
packed_at?: Date | OperatorMap<string | string[]>
shipped_at?: Date | OperatorMap<string | string[]>
delivered_at?: Date | OperatorMap<string | string[]>
canceled_at?: Date | OperatorMap<string | string[]>
provider_id?: string | string[] | OperatorMap<string | string[]>
shipping_option_id?: string | null
created_at?: Date | OperatorMap<string | string[]>
updated_at?: Date | OperatorMap<string | string[]>
}
+1
View File
@@ -1,3 +1,4 @@
export * from "./common"
export * from "./mutations"
export * from "./service"
export * from "./provider"
@@ -0,0 +1,14 @@
export interface CreateFulfillmentAddressDTO {
fulfillment_id: string
company?: string | null
first_name?: string | null
last_name?: string | null
address_1?: string | null
address_2?: string | null
city?: string | null
country_code?: string | null
province?: string | null
postal_code?: string | null
phone?: string | null
metadata?: Record<string, unknown> | null
}
@@ -0,0 +1,9 @@
export interface CreateFulfillmentItemDTO {
fulfillment_id: string
title: string
sku: string
quantity: number
barcode: string
line_item_id?: string | null
inventory_item_id?: string | null
}
@@ -0,0 +1,6 @@
export interface CreateFulfillmentLabelDTO {
tracking_number: string
tracking_url: string
label_url: string
fulfillment_id: string
}
@@ -0,0 +1,30 @@
import { CreateFulfillmentAddressDTO } from "./fulfillment-address"
import { CreateFulfillmentItemDTO } from "./fulfillment-item"
import { CreateFulfillmentLabelDTO } from "./fulfillment-label"
export interface CreateFulfillmentOrderDTO {}
export interface CreateFulfillmentDTO {
location_id: string
packed_at?: Date | null
shipped_at?: Date | null
delivered_at?: Date | null
canceled_at?: Date | null
data?: Record<string, unknown> | null
provider_id: string
shipping_option_id?: string | null
metadata?: Record<string, unknown> | null
delivery_address: Omit<CreateFulfillmentAddressDTO, "fulfillment_id">
items: Omit<CreateFulfillmentItemDTO, "fulfillment_id">[]
labels: Omit<CreateFulfillmentLabelDTO, "fulfillment_id">[]
order: CreateFulfillmentOrderDTO
}
export interface UpdateFulfillmentDTO {
location_id?: string
packed_at?: Date | null
shipped_at?: Date | null
delivered_at?: Date | null
data?: Record<string, unknown> | null
metadata?: Record<string, unknown> | null
}
@@ -5,3 +5,7 @@ export * from "./geo-zone"
export * from "./service-zone"
export * from "./shipping-option"
export * from "./fulfillment-set"
export * from "./fulfillment"
export * from "./fulfillment-address"
export * from "./fulfillment-label"
export * from "./fulfillment-item"
@@ -0,0 +1,96 @@
export interface IFulfillmentProvider {
/**
* @ignore
*
* Return a unique identifier to retrieve the fulfillment plugin provider
*/
getIdentifier(): string
/**
* @ignore
*
* Return the available fulfillment options for the given data.
*/
getFulfillmentOptions(): Promise<Record<string, unknown>[]>
/**
* @ignore
*
* Validate the given fulfillment data.
*/
validateFulfillmentData(
optionData: Record<string, unknown>,
data: Record<string, unknown>,
context: Record<string, unknown>
): Promise<any>
/**
* @ignore
*
* Validate the given option.
*/
validateOption(data: Record<string, unknown>): Promise<boolean>
/**
* @ignore
*
* Check if the provider can calculate the fulfillment price.
*/
canCalculate(data: Record<string, unknown>): Promise<any>
/**
* @ignore
*
* Calculate the price for the given fulfillment option.
*/
calculatePrice(
optionData: Record<string, unknown>,
data: Record<string, unknown>,
context: Record<string, unknown>
): Promise<any>
/**
* @ignore
*
* Create a fulfillment for the given data.
*/
createFulfillment(
data: object,
items: object[],
order: object,
fulfillment: Record<string, unknown>
): Promise<Record<string, unknown>>
/**
* @ignore
*
* Cancel the given fulfillment.
*/
cancelFulfillment(fulfillment: Record<string, unknown>): Promise<any>
/**
* @ignore
*
* Get the documents for the given fulfillment data.
*/
getFulfillmentDocuments(data: Record<string, unknown>): Promise<any>
/**
* @ignore
*
* Create a return for the given data.
*/
createReturnFulfillment(fromData: Record<string, unknown>): Promise<any>
/**
* @ignore
*
* Get the documents for the given return data.
*/
retrieveDocuments(
fulfillmentData: Record<string, unknown>,
documentType: string
): Promise<any>
/**
* @ignore
*
* Get the documents for the given return data.
*/
getReturnDocuments(data: Record<string, unknown>): Promise<any>
/**
* @ignore
*
* Get the documents for the given shipment data.
*/
getShipmentDocuments(data: Record<string, unknown>): Promise<any>
}
+77
View File
@@ -7,6 +7,7 @@ import {
FilterableShippingOptionRuleProps,
FilterableShippingOptionTypeProps,
FilterableShippingProfileProps,
FulfillmentDTO,
FulfillmentSetDTO,
GeoZoneDTO,
ServiceZoneDTO,
@@ -24,6 +25,7 @@ import {
CreateServiceZoneDTO,
CreateShippingOptionDTO,
CreateShippingOptionRuleDTO,
UpdateFulfillmentDTO,
UpdateFulfillmentSetDTO,
UpdateGeoZoneDTO,
UpdateServiceZoneDTO,
@@ -31,6 +33,7 @@ import {
UpdateShippingOptionRuleDTO,
} from "./mutations"
import { CreateShippingProfileDTO } from "./mutations/shipping-profile"
import { CreateFulfillmentDTO } from "./mutations/fulfillment"
export interface IFulfillmentModuleService extends IModuleService {
/**
@@ -202,6 +205,17 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context
): Promise<ShippingOptionRuleDTO>
/**
* Update a fulfillment
* @param data
* @param sharedContext
*/
updateFulfillment(
id: string,
data: UpdateFulfillmentDTO,
sharedContext?: Context
): Promise<FulfillmentDTO>
/**
* Delete a fulfillment set
* @param ids
@@ -337,6 +351,18 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context
): Promise<ShippingOptionTypeDTO>
/**
* Retrieve a fulfillment
* @param id
* @param config
* @param sharedContext
*/
retrieveFulfillment(
id: string,
config?: FindConfig<FulfillmentDTO>,
sharedContext?: Context
): Promise<FulfillmentDTO>
/**
* List fulfillment sets
* @param filters
@@ -421,6 +447,18 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context
): Promise<ShippingOptionTypeDTO[]>
/**
* List fulfillments
* @param filters
* @param config
* @param sharedContext
*/
listFulfillments(
filters?: FilterableFulfillmentSetProps,
config?: FindConfig<FulfillmentDTO>,
sharedContext?: Context
): Promise<FulfillmentDTO[]>
/**
* List and count fulfillment sets
* @param filters
@@ -505,6 +543,18 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context
): Promise<[ShippingOptionTypeDTO[], number]>
/**
* List and count fulfillments
* @param filters
* @param config
* @param sharedContext
*/
listAndCountFulfillments(
filters?: FilterableFulfillmentSetProps,
config?: FindConfig<FulfillmentDTO>,
sharedContext?: Context
): Promise<[FulfillmentDTO[], number]>
/**
* Soft delete fulfillment sets
* @param fulfillmentIds
@@ -572,4 +622,31 @@ export interface IFulfillmentModuleService extends IModuleService {
): Promise<Record<string, string[]> | void>
// TODO define needed soft delete/delete/restore methods
/**
* Retrieve the available fulfillment options for the given data.
*/
retrieveFulfillmentOptions(
providerId: string
): Promise<Record<string, unknown>[]>
/**
* Create a new fulfillment including into the third party provider
* @param data
* @param sharedContext
*/
createFulfillment(
data: CreateFulfillmentDTO,
sharedContext?: Context
): Promise<FulfillmentDTO>
/**
* Cancel the given fulfillment including into the third party provider
* @param id
* @param sharedContext
*/
cancelFulfillment(
id: string,
sharedContext?: Context
): Promise<FulfillmentDTO>
}