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

Commit

Permalink
feat: create putTransportContent
Browse files Browse the repository at this point in the history
  • Loading branch information
justinemmanuelmercado committed Jul 13, 2020
1 parent 6eafbe4 commit 4f88d6a
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 8 deletions.
29 changes: 29 additions & 0 deletions src/sections/fulfillment-inbound-shipment/codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,32 @@ export const GetPrepInstructionsForASINResponse = Codec.interface({
GetPrepInstructionsForASINResult: GetPrepInstructionsForASIN,
}),
})

enum TransportStatusEnum {
WORKING = 'WORKING',
ERROR_ON_ESTIMATING = 'ERROR_ON_ESTIMATING',
ESTIMATING = 'ESTIMATING',
ESTIMATED = 'ESTIMATED',
ERROR_ON_CONFIRMING = 'ERROR_ON_CONFIRMING',
CONFIRMING = 'CONFIRMING',
CONFIRMED = 'CONFIRMED',
VOIDING = 'VOIDING',
VOIDED = 'VOIDED',
ERROR_IN_VOIDING = 'ERROR_IN_VOIDING',
}

const TransportStatus = enumeration(TransportStatusEnum)

const PutTransportContent = Codec.interface({
TransportResult: Codec.interface({
TransportStatus,
}),
})

export type PutTransportContent = GetInterface<typeof PutTransportContent>

export const PutTransportContentResponse = Codec.interface({
PutTransportContentResponse: Codec.interface({
PutTransportContentResult: PutTransportContent,
}),
})
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ import {
GetPrepInstructionsForASINResponse,
GetPrepInstructionsForSKU,
GetPrepInstructionsForSKUResponse,
PutTransportContent,
PutTransportContentResponse,
UpdateInboundShipment,
UpdateInboundShipmentParameters,
UpdateInboundShipmentResponse,
} from './codec'
import {
canonicalizeParametersCreateInboUpdateundShipmentPlan,
canonicalizeParametersCreateUpdateInboundShipment,
canonicalizePutTransportContentParameters,
ConfirmPreorderParameters,
CreateInboundShipmentParameters,
CreateInboundShipmentPlanParameters,
Expand All @@ -33,13 +36,32 @@ import {
GetPreorderInfoParameters,
GetPrepInstructionsForASINParameters,
GetPrepInstructionsForSKUParameters,
PutTransportContentParameters,
} from './type'

const FULFILLMENT_INBOUND_SHIPMENT_API_VERSION = '2010-10-01'

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

async putTransportContent(
parameters: PutTransportContentParameters,
): Promise<[PutTransportContent, RequestMeta]> {
const [response, meta] = await this.httpClient.request('POST', {
resource: Resource.FulfillmentInboundShipment,
version: FULFILLMENT_INBOUND_SHIPMENT_API_VERSION,
action: 'PutTransportContent',
parameters: canonicalizePutTransportContentParameters(parameters),
})

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

async getPrepInstructionsForAsin(
parameters: GetPrepInstructionsForASINParameters,
): Promise<[GetPrepInstructionsForASIN, RequestMeta]> {
Expand Down
162 changes: 155 additions & 7 deletions src/sections/fulfillment-inbound-shipment/type.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { Parameters, ParameterTypes } from '../../http'
import { RequireOnlyOne } from '../types'

export const canonicalizeInboundShipmentPlanRequestItems = (
requestItem: InboundShipmentPlanRequestItem,
) => {
Expand Down Expand Up @@ -26,15 +29,18 @@ export const canonicalizeParametersCreateInboUpdateundShipmentPlan = (
}
}

export const canonicalizeInboundShipmentItem = (item: InboundShipmentItem) => {
let releaseDateString
if (item.ReleaseDate) {
const canonicalizeDate = (date: Date | undefined): string | undefined => {
if (date) {
// convert releaseDate to YYYY-MM-DD
const offset = item.ReleaseDate.getTimezoneOffset()
const releaseDate = new Date(item.ReleaseDate.getTime() + offset * 60 * 1000)
const [newDate] = releaseDate.toISOString().split('T')
releaseDateString = newDate
const offset = date.getTimezoneOffset()
const releaseDate = new Date(date.getTime() + offset * 60 * 1000)
return releaseDate.toISOString().split('T')[0]
}
return undefined
}

export const canonicalizeInboundShipmentItem = (item: InboundShipmentItem) => {
const releaseDateString = canonicalizeDate(item.ReleaseDate)

return {
ShipmentId: item.ShipmentId,
Expand Down Expand Up @@ -199,3 +205,145 @@ export interface GetPrepInstructionsForASINParameters {
ASINList: string[]
ShipToCountryCode: string
}

interface Amount {
CurrencyCode: string
Value: string
}
interface PartneredEstimate {
Amount?: Amount
ConfirmDeadline?: Date
VoidDeadline?: Date
}

type DimensionsUnit = 'inches' | 'centimeters'

interface FIBDimensions {
Unit: DimensionsUnit
Length: number
Width: number
Height: number
}

type WeightUnit = 'pounds' | 'kilograms'

interface FIBWeight {
Unit: WeightUnit
Value: number
}

type PackageStatus = 'SHIPPED' | 'IN_TRANSIT' | 'DELIVERED' | 'CHECKED_IN' | 'RECEIVING' | 'CLOSED'

export interface PartneredSmallParcelPackageInput {
Dimensions: FIBDimensions
Weight: FIBWeight
}

interface PartneredSmallParcelDataInput {
CarrierName: string
PackageList: PartneredSmallParcelPackageInput[]
}

interface NonPartneredSmallParcelPackageOutput {
TrackingId: string
}

interface NonPartneredSmallParcelDataInput {
CarrierName: string
PackageList: NonPartneredSmallParcelPackageOutput[]
}

interface Contact {
Name: string
Phone: string
Email: string
Fax: string
}

interface Pallet {
Dimension: FIBDimensions
Weight?: FIBWeight
IsStacked: boolean
}

interface PartneredLtlDataInput {
Contact: Contact
BoxCount: number
SellerFreightClass?: string
FreightReadyDate: Date // YYYY-MM-DD
PalletList?: Pallet[]
TotalWeight?: FIBWeight
SellerDeclaredValue?: Amount
}

interface NonPartneredLtlDataInput {
CarrierName: string
ProNumber: string
}

export interface PutTransportContentParameters {
ShipmentId: string
IsPartnered: boolean
ShipmentType: string
TransportDetails: RequireOnlyOne<
{
PartneredSmallParcelData?: PartneredSmallParcelDataInput
NonPartneredSmallParcelData?: NonPartneredSmallParcelDataInput
PartneredLtlData?: PartneredLtlDataInput
NonPartneredLtlData?: NonPartneredLtlDataInput
},
| 'PartneredSmallParcelData'
| 'NonPartneredSmallParcelData'
| 'PartneredLtlData'
| 'NonPartneredLtlData'
>
}

export const canonicalizePutTransportContentParameters = (
parameters: PutTransportContentParameters,
): Parameters => {
const { TransportDetails } = parameters
const {
PartneredSmallParcelData,
NonPartneredSmallParcelData,
PartneredLtlData,
NonPartneredLtlData,
} = TransportDetails
const transportDetails: ParameterTypes = {
PartneredSmallParcelData: PartneredSmallParcelData
? {
'PackageList.member': PartneredSmallParcelData?.PackageList,
CarrierName: PartneredSmallParcelData?.CarrierName,
}
: undefined,
NonPartneredSmallParcelData: NonPartneredSmallParcelData
? {
CarrierName: NonPartneredSmallParcelData.CarrierName,
'PackageList.member': NonPartneredSmallParcelData.PackageList,
}
: undefined,
PartneredLtlData: PartneredLtlData
? {
Contact: PartneredLtlData.Contact,
BoxCount: PartneredLtlData.BoxCount,
SellerFreightClass: PartneredLtlData.SellerFreightClass,
FreightReadyDate: canonicalizeDate(PartneredLtlData.FreightReadyDate),
'PalletList.member': PartneredLtlData.PalletList,
TotalWeight: PartneredLtlData.TotalWeight,
SellerDeclaredValue: PartneredLtlData.SellerDeclaredValue,
}
: undefined,
NonPartneredLtlData: NonPartneredLtlData
? {
CarrierName: NonPartneredLtlData.CarrierName,
ProNumber: NonPartneredLtlData.ProNumber,
}
: undefined,
} as { [key: string]: undefined | Record<string, ParameterTypes> }
return {
ShipmentId: parameters.ShipmentId,
IsPartnered: parameters.IsPartnered,
ShipmentType: parameters.ShipmentType,
TransportDetails: transportDetails,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<PutTransportContentResponse xmlns="http://mws.amazonaws.com/FulfillmentInboundShipment/2010-10-01/">
<PutTransportContentResult>
<TransportResult>
<TransportStatus>WORKING</TransportStatus>
</TransportResult>
</PutTransportContentResult>
<ResponseMetadata>
<RequestId>616f4f53-973e-4bb3-8dd3-0b46978a45c5</RequestId>
</ResponseMetadata>
</PutTransportContentResponse>
17 changes: 17 additions & 0 deletions test/unit/__snapshots__/fulfillment-inbound-shipment.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,23 @@ Array [
]
`;

exports[`fulfillmentInboundShipment putTransportContent returns tranport result if succesful 1`] = `
Array [
Object {
"TransportResult": Object {
"TransportStatus": "WORKING",
},
},
Object {
"quotaMax": 1000,
"quotaRemaining": 999,
"quotaResetOn": 2020-04-06T10:22:23.582Z,
"requestId": "0",
"timestamp": 2020-05-06T09:22:23.582Z,
},
]
`;

exports[`fulfillmentInboundShipment updateInboundShipment return the shipment id if succesful 1`] = `
Array [
Object {
Expand Down
56 changes: 55 additions & 1 deletion test/unit/fulfillment-inbound-shipment.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { CreateInboundShipmentParameters, InboundShipmentHeader, ParsingError } from '../../src'
import {
CreateInboundShipmentParameters,
InboundShipmentHeader,
ParsingError,
PartneredSmallParcelPackageInput,
} from '../../src'
import { createMockHttpClient, mockMwsFail, mockMwsServiceStatus, parsingError } from '../utils'

function mockFunctions() {
Expand Down Expand Up @@ -58,6 +63,55 @@ const mockInboundShipmentHeader: InboundShipmentHeader = {
}

describe('fulfillmentInboundShipment', () => {
describe('putTransportContent', () => {
const mockPartneredSmallParcelPackageInput: PartneredSmallParcelPackageInput = {
Dimensions: {
Unit: 'inches',
Length: 1,
Width: 1,
Height: 1,
},
Weight: {
Unit: 'pounds',
Value: 1,
},
}

const mockTransportDetailInput = {
PartneredSmallParcelData: {
CarrierName: '',
PackageList: [mockPartneredSmallParcelPackageInput],
},
}

const parameters = {
ShipmentId: '',
IsPartnered: true,
ShipmentType: 'SP',
TransportDetails: mockTransportDetailInput,
}

it('returns tranport result if succesful', async () => {
expect.assertions(1)

const mockPutTransportContent = createMockHttpClient(
'fulfillment_inbound_shipment_put_transport_content',
)

expect(
await mockPutTransportContent.fulfillmentInboundShipment.putTransportContent(parameters),
).toMatchSnapshot()
})

it('throws a parsing error when the status response i snt valid', async () => {
expect.assertions(1)

await expect(() =>
mockMwsFail.fulfillmentInboundShipment.putTransportContent(parameters),
).rejects.toStrictEqual(new ParsingError(parsingError))
})
})

describe('getPrepInstructionsForAsin', () => {
const parameters = {
ASINList: [''],
Expand Down

0 comments on commit 4f88d6a

Please sign in to comment.