Skip to content
This repository has been archived by the owner on Feb 6, 2024. It is now read-only.

Commit

Permalink
feat: create createShipment method
Browse files Browse the repository at this point in the history
  • Loading branch information
justinemmanuelmercado committed Jul 2, 2020
1 parent a653451 commit 927d10a
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 69 deletions.
74 changes: 54 additions & 20 deletions src/sections/merchant-fulfillment/codec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import {
boolean,
Codec,
enumeration,
GetInterface,
number,
optional,
string,
unknown,
} from 'purify-ts'
import { boolean, Codec, enumeration, GetInterface, number, optional, string } from 'purify-ts'

import { ensureArray, ensureString, mwsDate } from '../../parsing'
import { CurrencyAmount } from '../codec'
Expand All @@ -19,7 +10,7 @@ export const TemporarilyUnavailableCarrier = Codec.interface({

export const RejectedShippingService = Codec.interface({
CarrierName: string,
ShippingServiceId: string,
ShippingServiceId: ensureString,
RejectionReasonCode: string,
RejectionReasonMessage: string,
ShippingServiceName: string,
Expand Down Expand Up @@ -52,7 +43,7 @@ export const ShippingService = Codec.interface({
Rate: CurrencyAmount,
ShippingServiceOptions,
AvailableLabelFormats: optional(ensureArray('LabelFormat', string)),
RequiresAdditionalSellerInputs: boolean,
RequiresAdditionalSellerInputs: optional(boolean),
})

export const GetEligibleShippingServices = Codec.interface({
Expand Down Expand Up @@ -118,9 +109,9 @@ export const Address = Codec.interface({
Email: string,
City: string,
StateOrProvinceCode: optional(string),
PostalCode: string,
PostalCode: ensureString,
CountryCode: string,
Phone: string,
Phone: ensureString,
})

export const Weight = Codec.interface({
Expand Down Expand Up @@ -209,12 +200,51 @@ enum StatusEnum {
RefundApplied = 'RefundApplied ',
}

const ItemLevelSellerInputsList = Codec.interface({
DataType,
ValueAsString: optional(string),
ValueAsBoolean: optional(boolean),
ValueAsInteger: optional(number),
ValueAsTimestamp: optional(mwsDate),
ValueAsAddress: optional(Address),
ValueAsWeight: optional(Weight),
ValueAsDimension: optional(PackageDimensions),
ValueAsCurrency: optional(CurrencyAmount),
})

const Status = enumeration(StatusEnum)
const Item = unknown
const Item = Codec.interface({
OrderItemId: ensureString,
Quantity: number,
ItemWeight: optional(Weight),
ItemDescription: optional(string),
transparencyCodeList: optional(ensureArray('member', string)),
ItemLevelSellerInputsList: optional(ensureArray('member', ItemLevelSellerInputsList)),
})

const LabelDimensions = Codec.interface({
Length: number,
Width: number,
Unit: DimensionsUnit,
})

const FileContents = Codec.interface({
Contents: string,
FileType: string,
Checksum: string,
})

const Label = Codec.interface({
CustomTextForLabel: optional(string),
Dimensions: LabelDimensions,
FileContents,
LabelFormat: optional(string),
StandardIdForLabel: optional(string),
})

export const Shipment = Codec.interface({
ShipmentId: string,
AmazonOrderId: string,
ShipmentId: ensureString,
AmazonOrderId: ensureString,
SellerOrderId: optional(string),
ItemList: ensureArray('Item', Item),
ShipFromAddress: Address,
Expand All @@ -223,9 +253,9 @@ export const Shipment = Codec.interface({
Weight,
Insurance: CurrencyAmount,
ShippingService,
Label: unknown,
Label,
Status,
TrackingId: optional(string),
TrackingId: optional(ensureString),
CreatedDate: mwsDate,
LastUpdatedDate: optional(mwsDate),
})
Expand All @@ -234,6 +264,10 @@ export const CreateShipment = Codec.interface({
Shipment,
})

export type CreateShipment = GetInterface<typeof CreateShipment>

export const CreateShipmentResponse = Codec.interface({
CreateShipmentResult: CreateShipment,
CreateShipmentResponse: Codec.interface({
CreateShipmentResult: CreateShipment,
}),
})
4 changes: 3 additions & 1 deletion src/sections/merchant-fulfillment/merchant-fulfillment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import {
GetEligibleShippingServicesResponse,
} from './codec'
import {
canonicalizeCreateShipmentParameters,
canonicalizeParametersGetEligibleShippingServiceParameters,
CreateShipmentParameters,
GetAdditionalSellerInputsParameters,
GetEligibleShippingServicesParameters,
} from './type'
Expand All @@ -27,7 +29,7 @@ export class MerchantFulfillment {
resource: Resource.MerchantFulfillment,
version: MERCHANT_FULFILLMENT_API_VERSION,
action: 'CreateShipment',
parameters,
parameters: canonicalizeCreateShipmentParameters(parameters),
})

return CreateShipmentResponse.decode(response).caseOf({
Expand Down
154 changes: 110 additions & 44 deletions src/sections/merchant-fulfillment/type.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,68 @@
// @todo define output on canonicalize functions

// @todo unit test both of these
export const canonicalizeAdditionalSellerInputs = (
inputList: AdditionalSellerInputs[] | undefined,
) => {
return inputList?.map((input) => {
return {
AdditionalInputFieldName: input.AdditionalInputFieldName,
AdditionalSellerInput: {
...input.AdditionalSellerInput,
ValueAsTimestamp: input.AdditionalSellerInput.ValueAsTimestamp?.toISOString(),
},
}
})
}

// @todo unit test both of these
export const canonicalizeShipmentRequestDetails = (
shipmentRequestDetails: ShipmentRequestDetails,
) => {
const {
AmazonOrderId,
SellerOrderId,
ShipFromAddress,
PackageDimensions,
Weight,
MustArriveByDate,
ShipDate,
ShippingServiceOptions,
LabelCustomization,
} = shipmentRequestDetails

const itemsList = shipmentRequestDetails?.ItemList.map((item) => {
const fixedInputsList = canonicalizeAdditionalSellerInputs(item.ItemLevelSellerInputsList)

return {
...item,
TransparencyCodeList: undefined,
'transparencyCodeList.member': item.TransparencyCodeList, // Lower case 't' because that's what' in the C# lib
ItemLevelSellerInputsList: undefined,
'ItemLevelSellerInputsList.member': fixedInputsList,
}
})

return {
AmazonOrderId,
SellerOrderId,
'ItemList.Item': itemsList,
ShipFromAddress,
PackageDimensions,
Weight,
MustArriveByDate: MustArriveByDate?.toISOString(),
ShipDate: ShipDate?.toISOString(),
ShippingServiceOptions,
LabelCustomization,
}
}

/**
* END common functions
*/

/**
* START GetEligibleShippingServicesParameters
* AS OF July 1 2020, this hasn't been battle tested,
* but I would like to
*/

export type WeightUnit = 'ounces' | 'grams'
Expand Down Expand Up @@ -180,56 +241,16 @@ export interface GetEligibleShippingServicesParameters {
ShippingOfferingFilter?: ShippingOfferingFilter
}

// @todo unit test
export const canonicalizeParametersGetEligibleShippingServiceParameters = (
parameters: GetEligibleShippingServicesParameters,
) => {
const { ShipmentRequestDetails, ShippingOfferingFilter } = parameters
const {
AmazonOrderId,
SellerOrderId,
ShipFromAddress,
PackageDimensions,
Weight,
MustArriveByDate,
ShipDate,
ShippingServiceOptions,
LabelCustomization,
} = ShipmentRequestDetails
const itemsList = ShipmentRequestDetails?.ItemList.map((item) => {
const fixedInputsList = item.ItemLevelSellerInputsList?.map((input) => {
return {
AdditionalInputFieldName: input.AdditionalInputFieldName,
AdditionalSellerInput: {
...input.AdditionalSellerInput,
ValueAsTimestamp: input.AdditionalSellerInput.ValueAsTimestamp?.toISOString(),
},
}
})

return {
...item,
TransparencyCodeList: undefined,
'transparencyCodeList.member': item.TransparencyCodeList, // Lower case 't' because that's what' in the C# lib
ItemLevelSellerInputsList: undefined,
'ItemLevelSellerInputsList.member': fixedInputsList,
}
})
return {
ShippingOfferingFilter: {
IncludeComplexShippingOptions: ShippingOfferingFilter?.IncludeComplexShippingOptions,
},
ShipmentRequestDetails: {
AmazonOrderId,
SellerOrderId,
'ItemList.Item': itemsList,
ShipFromAddress,
PackageDimensions,
Weight,
MustArriveByDate: MustArriveByDate?.toISOString(),
ShipDate: ShipDate?.toISOString(),
ShippingServiceOptions,
LabelCustomization,
},
ShipmentRequestDetails: canonicalizeShipmentRequestDetails(ShipmentRequestDetails),
}
}

Expand All @@ -243,3 +264,48 @@ export interface GetAdditionalSellerInputsParameters {
ShipFromAddress: Address
[key: string]: string | Address
}

/**
* START CreateShipmentParameters
*/

export type HazmatType = 'None' | 'LQHazmat'

export interface LabelFormatOption {
IncludePackingSlipWithLabel: boolean
[key: string]: boolean
}
export interface CreateShipmentParameters {
ShipmentRequestDetails: ShipmentRequestDetails
ShippingServiceId: string
ShippingServiceOfferId?: string
HazmatType?: HazmatType
LabelFormatOption?: LabelFormatOption
ShipmentLevelSellerInputsList?: AdditionalSellerInputs[]
}

// @todo unit test
export const canonicalizeCreateShipmentParameters = (parameters: CreateShipmentParameters) => {
const {
ShipmentRequestDetails,
ShippingServiceId,
ShippingServiceOfferId,
HazmatType,
LabelFormatOption,
ShipmentLevelSellerInputsList,
} = parameters
return {
ShipmentRequestDetails: canonicalizeShipmentRequestDetails(ShipmentRequestDetails),
ShippingServiceId,
ShippingServiceOfferId,
HazmatType,
LabelFormatOption,
'ShipmentLevelSellerInputsList.member': canonicalizeAdditionalSellerInputs(
ShipmentLevelSellerInputsList,
),
}
}

/**
* END CreateShipmentParameters
*/
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<CreatedDate>2015-09-23T20:11:12.908Z</CreatedDate>
<ShipFromAddress>
<City>Seattle</City>
<Email>String</Email>
<Phone>2061234567</Phone>
<CountryCode>US</CountryCode>
<PostalCode>98121</PostalCode>
Expand All @@ -80,7 +81,11 @@
<Item>
<OrderItemId>40525960574974</OrderItemId>
<Quantity>1</Quantity>
<ItemWeight>200</ItemWeight>
<!-- <ItemWeight>200</ItemWeight> Looks like amazon's examples are unreliable again -->
<ItemWeight>
<Value>100</Value>
<Unit>gram</Unit>
</ItemWeight>
<ItemDescription>Poster</ItemDescription>
</Item>
</ItemList>
Expand Down

0 comments on commit 927d10a

Please sign in to comment.