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

Commit

Permalink
feat: made getEligibleShippingServices codecs and added more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
justinemmanuelmercado committed Jul 1, 2020
1 parent 9726bf9 commit d2b577a
Show file tree
Hide file tree
Showing 10 changed files with 464 additions and 75 deletions.
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export * from './sections/feeds'
export * from './sections/finances/finances'
export * from './sections/finances/codec'
export * from './sections/fulfillment-inventory'
export * from './sections/merchant-fulfillment'
export * from './sections/merchant-fulfillment/merchant-fulfillment'
export * from './sections/subscriptions'
export * from './sections/orders'
export * from './sections/products/products'
Expand Down
2 changes: 1 addition & 1 deletion src/mws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { HttpClient } from './http'
import { Feeds } from './sections/feeds'
import { Finances } from './sections/finances/finances'
import { FulfillmentInventory } from './sections/fulfillment-inventory'
import { MerchantFulfillment } from './sections/merchant-fulfillment'
import { MerchantFulfillment } from './sections/merchant-fulfillment/merchant-fulfillment'
import { Orders } from './sections/orders'
import { Products } from './sections/products/products'
import { Reports } from './sections/reports'
Expand Down
10 changes: 10 additions & 0 deletions src/sections/codec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Codec, number, optional, string } from 'purify-ts'

/**
* Shared codecs
*/

export const CurrencyAmount = Codec.interface({
CurrencyCode: optional(string),
CurrencyAmount: optional(number),
})
6 changes: 1 addition & 5 deletions src/sections/finances/codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from 'purify-ts'

import { ensureArray, ensureString, mwsDate, nextToken as nextTokenCodec } from '../../parsing'
import { CurrencyAmount } from '../codec'
import { FulfillmentChannelEnum } from '../types'

export enum ProcessingStatusEnum {
Expand All @@ -19,11 +20,6 @@ export enum ProcessingStatusEnum {

const ProcessingStatus = enumeration(ProcessingStatusEnum)

const CurrencyAmount = Codec.interface({
CurrencyCode: optional(string),
CurrencyAmount: optional(number),
})

const FinancialEventGroup = Codec.interface({
FinancialEventGroupId: optional(string),
ProcessingStatus: optional(ProcessingStatus),
Expand Down
106 changes: 106 additions & 0 deletions src/sections/merchant-fulfillment/merchant-fulfillment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { boolean, Codec, enumeration, GetInterface, optional, string } from 'purify-ts'

import { ParsingError } from '../../error'
import { HttpClient, RequestMeta, Resource } from '../../http'
import { ensureArray, ensureString, mwsDate } from '../../parsing'
import { CurrencyAmount } from '../codec'
import { getServiceStatusByResource } from '../shared'
import {
canonicalizeParametersGetEligibleShippingServiceParameters,
GetEligibleShippingServicesParameters,
} from './type'

const MERCHANT_FULFILLMENT_API_VERSION = '2015-06-01'

const TemporarilyUnavailableCarrier = Codec.interface({
CarrierName: string,
})

const RejectedShippingService = Codec.interface({
CarrierName: string,
ShippingServiceId: string,
RejectionReasonCode: string,
RejectionReasonMessage: string,
ShippingServiceName: string,
})

enum DeliveryExperienceEnum {
DeliveryConfirmationWithAdultSignature = 'DeliveryConfirmationWithAdultSignature',
DeliveryConfirmationWithSignature = 'DeliveryConfirmationWithSignature',
DeliveryConfirmationWithoutSignature = 'DeliveryConfirmationWithoutSignature',
NoTracking = 'NoTracking',
}

const DeliveryExperience = enumeration(DeliveryExperienceEnum)

const ShippingServiceOptions = Codec.interface({
DeliveryExperience,
DeclaredValue: optional(CurrencyAmount),
CarrierWillPickUp: boolean,
LabelFormat: optional(string),
})

const ShippingService = Codec.interface({
ShippingServiceName: string,
CarrierName: string,
ShippingServiceId: ensureString,
ShippingServiceOfferId: ensureString,
ShipDate: mwsDate,
EarliestEstimatedDeliveryDate: optional(mwsDate),
LatestEstimatedDeliveryDate: optional(mwsDate),
Rate: CurrencyAmount,
ShippingServiceOptions,
AvailableLabelFormats: optional(ensureArray('LabelFormat', string)),
RequiresAdditionalSellerInputs: boolean,
})

const GetEligibleShippingServices = Codec.interface({
ShippingServiceList: ensureArray('ShippingService', ShippingService),
RejectedShippingServiceList: ensureArray('RejectedShippingService', RejectedShippingService),
TemporarilyUnavailableCarrierList: ensureArray(
'TemporarilyUnavailableCarrier',
TemporarilyUnavailableCarrier,
),
TermsAndConditionsNotAcceptedCarrierList: ensureArray(
'TermsAndConditionsNotAcceptedCarrier',
TemporarilyUnavailableCarrier,
),
})

type GetEligibleShippingServices = GetInterface<typeof GetEligibleShippingServices>

const GetEligibleShippingServicesResponse = Codec.interface({
GetEligibleShippingServicesResponse: Codec.interface({
GetEligibleShippingServicesResult: GetEligibleShippingServices,
}),
})

export class MerchantFulfillment {
constructor(private httpClient: HttpClient) {}

async getEligibleShippingServices(
parameters: GetEligibleShippingServicesParameters,
): Promise<[GetEligibleShippingServices, RequestMeta]> {
const [response, meta] = await this.httpClient.request('POST', {
resource: Resource.MerchantFulfillment,
version: MERCHANT_FULFILLMENT_API_VERSION,
action: 'GetEligibleShippingServices',
parameters: canonicalizeParametersGetEligibleShippingServiceParameters(parameters),
})

return GetEligibleShippingServicesResponse.decode(response).caseOf({
Right: (x) => [x.GetEligibleShippingServicesResponse.GetEligibleShippingServicesResult, meta],
Left: (error) => {
throw new ParsingError(error)
},
})
}

async getServiceStatus() {
return getServiceStatusByResource(
this.httpClient,
Resource.MerchantFulfillment,
MERCHANT_FULFILLMENT_API_VERSION,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { record, string, unknown } from 'purify-ts'

import { ParsingError } from '../error'
import { HttpClient, Resource } from '../http'
import { getServiceStatusByResource } from './shared'
/**
* START GetEligibleShippingServicesParameters
* AS OF July 1 2020, this hasn't been battle tested,
* but I would like to
*/

const MERCHANT_FULFILLMENT_API_VERSION = '2015-06-01'
export type WeightUnit = 'ounces' | 'grams'

export interface Weight {
Value: number
Unit: 'ounces' | 'grams'
Unit: WeightUnit
[key: string]: string | number
}

Expand Down Expand Up @@ -50,8 +50,8 @@ export type PredefinedPackageDimensions =
| 'FedEx_Box_Small_2'
| 'FedEx_Envelope'
| 'FedEx_Padded_Pak'
| 'FedEx_Pak_1'
| 'FedEx_Pak_2'
| 'FedEx_Pak_1'
| 'FedEx_Tube'
| 'FedEx_XL_Pak'
| 'UPS_Box_10kg'
Expand Down Expand Up @@ -108,27 +108,22 @@ export interface AdditionalSellerInput {
ValueAsString?: string
ValueAsBoolean?: boolean
ValueAsInteger?: number
// @todo
// ValueAsTimestamp?: Date // this needs an issue. "parameters should be able to handle Date objects"
ValueAsTimestamp?: string
ValueAsTimestamp?: Date
ValueAsAddress?: Address
ValueAsWeight?: Weight
ValueAsDimension?: PackageDimensions
ValueAsCurrency?: CurrencyAmount
}

interface AdditionalSellerInputs {
AdditionalInputFieldName: string
AdditionalSellerInput: AdditionalSellerInput
[key: string]: undefined | string | boolean | number | object
}

/**
* Needs clarification
* @todo
* http://docs.developer.amazonservices.com/en_CA/merch_fulfill/MerchFulfill_Datatypes.html#ItemLevelSellerInputs
*/
export interface ItemLevelSellerInputsList {
AdditionalSellerInputs: AdditionalSellerInputs[]
interface AdditionalSellerInputs {
AdditionalInputFieldName: string
AdditionalSellerInput: AdditionalSellerInput
}

export interface Item {
Expand All @@ -137,7 +132,7 @@ export interface Item {
ItemWeight?: Weight
ItemDescription?: string
TransparencyCodeList?: string[]
// ItemLevelSellerInputsList?: ItemLevelSellerInputsList // Need to do more research on this
ItemLevelSellerInputsList?: AdditionalSellerInputs[] // Need to do more research on this
}

export type DeliveryExperience =
Expand Down Expand Up @@ -180,7 +175,7 @@ export interface GetEligibleShippingServicesParameters {
ShippingOfferingFilter?: ShippingOfferingFilter
}

const canonicalizeParametersGetEligibleShippingServiceParameters = (
export const canonicalizeParametersGetEligibleShippingServiceParameters = (
parameters: GetEligibleShippingServicesParameters,
) => {
const { ShipmentRequestDetails, ShippingOfferingFilter } = parameters
Expand All @@ -195,19 +190,33 @@ const canonicalizeParametersGetEligibleShippingServiceParameters = (
ShippingServiceOptions,
LabelCustomization,
} = ShipmentRequestDetails
const ItemsList = ShipmentRequestDetails?.ItemList.map((item) => ({
...item,
TransparencyCodeList: undefined,
'TransparemcyCodeList.TransparencyCode': item.TransparencyCodeList,
}))
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,
'ItemList.Item': itemsList,
ShipFromAddress,
PackageDimensions,
Weight,
Expand All @@ -219,33 +228,6 @@ const canonicalizeParametersGetEligibleShippingServiceParameters = (
}
}

// @todo
const GetEligibleShippingServicesResponse = record(string, unknown)

export class MerchantFulfillment {
constructor(private httpClient: HttpClient) {}

async getEligibleShippingServices(parameters: GetEligibleShippingServicesParameters) {
const [response, meta] = await this.httpClient.request('POST', {
resource: Resource.MerchantFulfillment,
version: MERCHANT_FULFILLMENT_API_VERSION,
action: 'GetEligibleShippingServices',
parameters: canonicalizeParametersGetEligibleShippingServiceParameters(parameters),
})

return GetEligibleShippingServicesResponse.decode(response).caseOf({
Right: (x) => [x.GetEligibleShippingServicesResponse.GetEligibleShippingServicesResult, meta],
Left: (error) => {
throw new ParsingError(error)
},
})
}

async getServiceStatus() {
return getServiceStatusByResource(
this.httpClient,
Resource.MerchantFulfillment,
MERCHANT_FULFILLMENT_API_VERSION,
)
}
}
/**
* END GetEligibleShippingServicesParameters
*/
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
</Rate>
<ShippingServiceOptions>
<DeliveryExperience>DeliveryConfirmationWithoutSignature</DeliveryExperience>
<CarrierWillPickUp>False</CarrierWillPickUp>
<!-- For some reason this was capitalized previously, mistake on the doc writer? -->
<CarrierWillPickUp>false</CarrierWillPickUp>
</ShippingServiceOptions>
<AvailableLabelFormats>
<LabelFormat>ZPL203</LabelFormat>
<LabelFormat>ShippingServiceDefault</LabelFormat>
<LabelFormat>PDF</LabelFormat>
<LabelFormat>PNG</LabelFormat>
</AvailableLabelFormats>
<RequiresAdditionalSellerInputs>False</RequiresAdditionalSellerInputs>
<RequiresAdditionalSellerInputs>false</RequiresAdditionalSellerInputs>
</ShippingService>
</ShippingServiceList>
<RejectedShippingServiceList>
Expand Down

0 comments on commit d2b577a

Please sign in to comment.