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

Commit

Permalink
feat: add products and get my fees estimate
Browse files Browse the repository at this point in the history
  • Loading branch information
justinemmanuelmercado committed May 28, 2020
1 parent 21a9c69 commit 011e4a3
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/mws.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { HttpClient } from './http'
import { FulfillmentInventory } from './sections/fulfillment-inventory'
import { Orders } from './sections/orders'
import { Products } from './sections/products'
import { Sellers } from './sections/sellers'

export class MWS {
Expand All @@ -10,6 +11,8 @@ export class MWS {

private _fulfillmentInventory!: FulfillmentInventory

private _products!: Products

constructor(private httpClient: HttpClient) {}

get sellers() {
Expand All @@ -35,4 +38,12 @@ export class MWS {

return this._fulfillmentInventory
}

get products() {
if (!this._products) {
this._products = new Products(this.httpClient)
}

return this._products
}
}
161 changes: 161 additions & 0 deletions src/sections/products.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { boolean, Codec, exactly, GetInterface, number, oneOf, optional, string } from 'purify-ts'

import { ParsingError } from '../error'
import { HttpClient, RequestMeta, Resource } from '../http'
import { ensureArray, mwsDate } from '../parsing'
// import { getServiceStatusByResource } from './shared'

const PRODUCTS_API_VERSION = '2011-10-01'

type CurrencyCode = 'USD' | 'EUR' | 'GBP' | 'RMB' | 'INR' | 'JPY' | 'CAD' | 'MXN'

enum CurrencyCodeEnum {
USD = 'USD',
EUR = 'EUR',
GBP = 'GBP',
RMB = 'RMB',
INR = 'INR',
JPY = 'JPY',
CAD = 'CAD',
MXN = 'MXN',
}

enum Status {
Success = 'Success',
ClientError = 'ClientError',
ServiceError = 'ServiceError',
}

const MoneyType = Codec.interface({
Amount: optional(number),
CurrencyCode: oneOf(Object.values(CurrencyCodeEnum).map((x) => exactly(x))),
})

interface MoneyType {
Amount?: number
CurrencyCode?: CurrencyCode
}

const Points = Codec.interface({
PointsNumber: number,
PointsMonetaryValue: MoneyType,
})

interface Points {
PointsNumber: number
PointsMonetaryValue: MoneyType
}

interface PriceToEstimateFees {
ListingPrice: MoneyType
Shipping?: MoneyType
Points?: Points
}

interface FeeEstimateRequest {
MarketplaceId: string
IdType: string
IdValue: string
PriceToEstimateFees: PriceToEstimateFees
Identifier: string
IsAmazonFulfilled: boolean
}

interface GetMyFeesEstimateParameters {
FeesEstimateRequestList: FeeEstimateRequest[]
[key: string]: FeeEstimateRequest[]
}

const ErrorType = Codec.interface({
Type: string,
Code: string,
Message: string,
})

enum IdType {
ASIN = 'ASIN',
SKU = 'SKU',
}

const PriceToEstimateFees = Codec.interface({
ListingPrice: MoneyType,
Shipping: optional(MoneyType),
Points: optional(Points),
})

const FeesEstimateIdentifier = Codec.interface({
MarketplaceId: string,
IdType: oneOf(Object.values(IdType).map((x) => exactly(x))),
IdValue: string,
PriceToEstimateFees,
SellerInputIdentifier: string,
IsAmazonFulfilled: boolean,
})

enum FeeType {
ReferralFee = 'ReferralFee',
VariableClosingFee = 'VariableClosingFee',
PerItemFee = 'PerItemFee',
FBAFees = 'FBAFees',
FBAPickAndPack = 'FBAPickAndPack',
FBAWeightHandling = 'FBAWeightHandling',
FBAOrderHandling = 'FBAOrderHandling',
FBADeliveryServicesFee = 'FBADeliveryServicesFee',
}

const FeeDetail = Codec.interface({
FeeType: oneOf(Object.values(FeeType).map((x) => exactly(x))),
FeeAmount: MoneyType,
FeePromotion: optional(MoneyType),
TaxAmount: optional(MoneyType),
FinalFee: MoneyType,
// IncludedFeeDetailList: optional(ensureArray('IncludedFeeDetail', FeeDetail)) // Need to think about how to get around this
})

const FeesEstimate = Codec.interface({
TimeOfFeesEstimation: mwsDate,
TotalFeesEstimate: MoneyType,
FeeDetailList: ensureArray('FeeDetail', FeeDetail),
})

const FeesEstimateResult = Codec.interface({
FeesEstimateIdentifier,
FeesEstimate: optional(FeesEstimate),
Status: oneOf(Object.values(Status).map((x) => exactly(x))),
Error: optional(ErrorType),
})

const GetMyFeesEstimate = Codec.interface({
FeesEstimateResultList: ensureArray('FeesEstimateResult', FeesEstimateResult),
})

const GetMyFeesEstimateResponse = Codec.interface({
GetMyFeesEstimateResponse: Codec.interface({
GetMyFeesEstimateResult: GetMyFeesEstimate,
}),
})

type GetMyFeesEstimateResponse = GetInterface<typeof GetMyFeesEstimate>

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

async getMyFeesEstimate(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_parameters: GetMyFeesEstimateParameters,
): Promise<[GetMyFeesEstimateResponse, RequestMeta]> {
const [response, meta] = await this.httpClient.request('POST', {
resource: Resource.Products,
version: PRODUCTS_API_VERSION,
action: 'GetMyFeesEstimate',
parameters: {}, // Patch after pushing fix to clean dependencies to master
})

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

0 comments on commit 011e4a3

Please sign in to comment.