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

Commit

Permalink
feat: create createInboundShipment
Browse files Browse the repository at this point in the history
  • Loading branch information
justinemmanuelmercado committed Jul 9, 2020
1 parent ca3b458 commit e7d650b
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 5 deletions.
104 changes: 103 additions & 1 deletion src/sections/fulfillment-inbound-shipment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ interface AddressFIS {
[key: string]: string | undefined
}

type LabelPrepPreference = 'SELLER_LABEL' | 'AMAZON_LABEL_ONLY' | 'AMAZON_LABEL_PREFERRED'
export type LabelPrepPreference = 'SELLER_LABEL' | 'AMAZON_LABEL_ONLY' | 'AMAZON_LABEL_PREFERRED'
type ConditionFIS =
| 'NewItem'
| 'NewWithWarranty'
Expand Down Expand Up @@ -235,9 +235,111 @@ const CreateInboundShipmentPlanResponse = Codec.interface({
}),
})

export type ShipmentStatus = 'WORKING' | 'SHIPPED' | 'CANCELLED'

type IntendedBoxContentsSource = 'NONE' | 'FEED' | '2D_BARCODE'

export interface InboundShipmentHeader {
ShipmentName: string
ShipFromAddress: AddressFIS
DestinationFulfillmentCenterId: string
LabelPrepPreference: LabelPrepPreference
AreCasesRequired?: boolean
ShipmentStatus: ShipmentStatus
IntendedBoxContentsSource?: IntendedBoxContentsSource
[key: string]: string | undefined | boolean | AddressFIS
}

interface InboundShipmentItem {
ShipmentId?: string
SellerSKU: string
FulfillmentNetworkSKU?: string
QuantityShipped: number
QuantityReceived?: number
QuantityInCase?: number
PrepDetailsList?: PrepDetails[]
ReleaseDate?: Date // convert to YYYY-MM-DD format
}

export interface CreateInboundShipmentParameters {
ShipmentId: string
InboundShipmentHeader: InboundShipmentHeader
InboundShipmentItems: InboundShipmentItem[]
}

const canonicalizeInboundShipmentItem = (item: InboundShipmentItem) => {
let releaseDateString
if (item.ReleaseDate) {
// 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
}

return {
ShipmentId: item.ShipmentId,
SellerSKU: item.SellerSKU,
FulfillmentNetworkSKU: item.FulfillmentNetworkSKU,
QuantityShipped: item.QuantityShipped,
QuantityReceived: item.QuantityReceived,
QuantityInCase: item.QuantityInCase,
/**
* Note: // C# library has this field as 'PrepDetailsList.PrepDetails'
* but documentation says it's 'PrepDetailsList.member'.
* Following C# because docs is unreliable
*/
'PrepDetailsList.PrepDetails': item.PrepDetailsList,
ReleaseDate: releaseDateString,
}
}

const canonicalizeParametersCreateInboundShipment = (
parameters: CreateInboundShipmentParameters,
) => {
const shipmentItemsCanonicalized = parameters.InboundShipmentItems.map((item) =>
canonicalizeInboundShipmentItem(item),
)
return {
ShipmentId: parameters.ShipmentId,
InboundShipmentHeader: parameters.InboundShipmentHeader,
'InboundShipmentItems.member': shipmentItemsCanonicalized,
}
}

const CreateInboundShipment = Codec.interface({
ShipmentId: string,
})

type CreateInboundShipment = GetInterface<typeof CreateInboundShipment>

const CreateInboundShipmentResponse = Codec.interface({
CreateInboundShipmentResponse: Codec.interface({
CreateInboundShipmentResult: CreateInboundShipment,
}),
})

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

async createInboundShipment(
parameters: CreateInboundShipmentParameters,
): Promise<[CreateInboundShipment, RequestMeta]> {
const [response, meta] = await this.httpClient.request('POST', {
resource: Resource.FulfillmentInboundShipment,
version: FULFILLMENT_INBOUND_SHIPMENT_API_VERSION,
action: 'CreateInboundShipment',
parameters: canonicalizeParametersCreateInboundShipment(parameters),
})

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

async createInboundShipmentPlan(
parameters: CreateInboundShipmentPlanParameters,
): Promise<[CreateInboundShipmentPlan, RequestMeta]> {
Expand Down
15 changes: 15 additions & 0 deletions test/unit/__snapshots__/fulfillment-inbound-shipment.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`fulfillmentInboundShipment createInboundShipment returns the shipment ID if succesful 1`] = `
Array [
Object {
"ShipmentId": "FBA2F50GYX",
},
Object {
"quotaMax": 1000,
"quotaRemaining": 999,
"quotaResetOn": 2020-04-06T10:22:23.582Z,
"requestId": "0",
"timestamp": 2020-05-06T09:22:23.582Z,
},
]
`;

exports[`fulfillmentInboundShipment createInboundShipmentPlan returns inbound shipment plans if succesful 1`] = `
Array [
Object {
Expand Down
8 changes: 4 additions & 4 deletions test/unit/fulfillment-inbound-shipment.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ParsingError } from '../../src'
import { CreateInboundShipmentParameters, InboundShipmentHeader, ParsingError } from '../../src'
import { createMockHttpClient, mockMwsFail, mockMwsServiceStatus, parsingError } from '../utils'

function mockFunctions() {
Expand Down Expand Up @@ -51,15 +51,15 @@ describe('fulfillmentInboundShipment', () => {
QuantityShipped: 1,
}

const mockInboundShipmentHeader = {
const mockInboundShipmentHeader: InboundShipmentHeader = {
ShipmentName: '',
ShipFromAddress: mockAddress,
DestinationFulfillmentCenterId: '',
LabelPrePreference: 'SELLER_LABEL',
LabelPrepPreference: 'SELLER_LABEL',
ShipmentStatus: 'WORKING',
}

const parameters = {
const parameters: CreateInboundShipmentParameters = {
ShipmentId: '',
InboundShipmentHeader: mockInboundShipmentHeader,
InboundShipmentItems: [mockInboundShipmentItem],
Expand Down

0 comments on commit e7d650b

Please sign in to comment.