From 35c75597b9606ec395c438ec1c45a7c527ae2141 Mon Sep 17 00:00:00 2001 From: EJ Mercado Date: Thu, 18 Jun 2020 20:14:31 +0800 Subject: [PATCH] feat: prepare separate codec file to hold list of financial events --- src/index.ts | 2 +- src/mws.ts | 2 +- src/sections/finances/codec.ts | 61 ++++++ src/sections/{ => finances}/finances.ts | 98 +++++----- test/unit/__snapshots__/finances.test.ts.snap | 184 ++++++++++++++++++ test/unit/finances.test.ts | 2 +- 6 files changed, 292 insertions(+), 57 deletions(-) create mode 100644 src/sections/finances/codec.ts rename src/sections/{ => finances}/finances.ts (52%) diff --git a/src/index.ts b/src/index.ts index 36c48b00..1db06c1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ export * from './error' export * from './http' export * from './mws' -export * from './sections/finances' +export * from './sections/finances/finances' export * from './sections/fulfillment-inventory' export * from './sections/orders' export * from './sections/products/products' diff --git a/src/mws.ts b/src/mws.ts index e5f1dd2c..94088fd8 100644 --- a/src/mws.ts +++ b/src/mws.ts @@ -1,5 +1,5 @@ import { HttpClient } from './http' -import { Finances } from './sections/finances' +import { Finances } from './sections/finances/finances' import { FulfillmentInventory } from './sections/fulfillment-inventory' import { Orders } from './sections/orders' import { Products } from './sections/products/products' diff --git a/src/sections/finances/codec.ts b/src/sections/finances/codec.ts new file mode 100644 index 00000000..4b1ae149 --- /dev/null +++ b/src/sections/finances/codec.ts @@ -0,0 +1,61 @@ +import { Codec, enumeration, GetInterface, number, optional, string, unknown } from 'purify-ts' + +import { ensureArray, ensureString, mwsDate, nextToken as nextTokenCodec } from '../../parsing' + +enum ProcessingStatusEnum { + Open = 'Open', + Closed = 'Closed', +} + +const ProcessingStatus = enumeration(ProcessingStatusEnum) + +const CurrencyAmount = Codec.interface({ + CurrencyCode: optional(string), + CurrencyAmount: optional(number), +}) + +const FinancialEventGroup = Codec.interface({ + FinancialEventGroupId: optional(string), + ProcessingStatus: optional(ProcessingStatus), + FundTransferStatus: optional(string), + OriginalTotal: optional(CurrencyAmount), + ConvertedTotal: optional(CurrencyAmount), + FundTransferDate: optional(mwsDate), + TraceId: optional(ensureString), + AccountTail: optional(ensureString), + BeginningBalance: optional(CurrencyAmount), + FinancialEventGroupStart: optional(mwsDate), + FinancialEventGroupEnd: optional(mwsDate), +}) + +const ListFinancialEventGroups = Codec.interface({ + NextToken: optional(nextTokenCodec('ListFinancialEventGroups')), + FinancialEventGroupList: ensureArray('FinancialEventGroup', FinancialEventGroup), +}) + +export type ListFinancialEventGroups = GetInterface + +export const ListFinancialEventGroupsResponse = Codec.interface({ + ListFinancialEventGroupsResponse: Codec.interface({ + ListFinancialEventGroupsResult: ListFinancialEventGroups, + }), +}) + +export const ListFinancialEventGroupsByNextTokenResponse = Codec.interface({ + ListFinancialEventGroupsByNextTokenResponse: Codec.interface({ + ListFinancialEventGroupsByNextTokenResult: ListFinancialEventGroups, + }), +}) + +const ListFinancialEvents = Codec.interface({ + NextToken: optional(nextTokenCodec('ListFinancialEvents')), + FinancialEvents: unknown, +}) + +export type ListFinancialEvents = GetInterface + +export const ListFinancialEventsResponse = Codec.interface({ + ListFinancialEventsResponse: Codec.interface({ + ListFinancialEventsResult: ListFinancialEvents, + }), +}) diff --git a/src/sections/finances.ts b/src/sections/finances/finances.ts similarity index 52% rename from src/sections/finances.ts rename to src/sections/finances/finances.ts index 5d58cfdb..222431a5 100644 --- a/src/sections/finances.ts +++ b/src/sections/finances/finances.ts @@ -1,15 +1,15 @@ -import { Codec, enumeration, GetInterface, number, optional, string } from 'purify-ts' - -import { ParsingError } from '../error' -import { HttpClient, RequestMeta, Resource } from '../http' +import { ParsingError } from '../../error' +import { HttpClient, RequestMeta, Resource } from '../../http' +import { NextToken } from '../../parsing' +import { getServiceStatusByResource } from '../shared' +import { RequireOnlyOne } from '../types' import { - ensureArray, - ensureString, - mwsDate, - NextToken, - nextToken as nextTokenCodec, -} from '../parsing' -import { getServiceStatusByResource } from './shared' + ListFinancialEventGroups, + ListFinancialEventGroupsByNextTokenResponse, + ListFinancialEventGroupsResponse, + ListFinancialEvents, + ListFinancialEventsResponse, +} from './codec' const FINANCES_API_VERSION = '2015-05-01' @@ -19,54 +19,44 @@ interface ListFinancialEventGroupsParameters { FinancialEventGroupStartedBefore?: Date } -enum ProcessingStatusEnum { - Open = 'Open', - Closed = 'Closed', +interface ListFinancicalEventsParameters { + MaxResultsPerPage?: number + AmazonOrderId?: string + FinancialEventGroupId?: string + PostedAfter?: Date + PostedBefore?: Date } -const ProcessingStatus = enumeration(ProcessingStatusEnum) - -const CurrencyAmount = Codec.interface({ - CurrencyCode: optional(string), - CurrencyAmount: optional(number), -}) - -const FinancialEventGroup = Codec.interface({ - FinancialEventGroupId: optional(string), - ProcessingStatus: optional(ProcessingStatus), - FundTransferStatus: optional(string), - OriginalTotal: optional(CurrencyAmount), - ConvertedTotal: optional(CurrencyAmount), - FundTransferDate: optional(mwsDate), - TraceId: optional(ensureString), - AccountTail: optional(ensureString), - BeginningBalance: optional(CurrencyAmount), - FinancialEventGroupStart: optional(mwsDate), - FinancialEventGroupEnd: optional(mwsDate), -}) - -const ListFinancialEventGroups = Codec.interface({ - NextToken: optional(nextTokenCodec('ListFinancialEventGroups')), - FinancialEventGroupList: ensureArray('FinancialEventGroup', FinancialEventGroup), -}) - -type ListFinancialEventGroups = GetInterface - -const ListFinancialEventGroupsResponse = Codec.interface({ - ListFinancialEventGroupsResponse: Codec.interface({ - ListFinancialEventGroupsResult: ListFinancialEventGroups, - }), -}) - -const ListFinancialEventGroupsByNextTokenResponse = Codec.interface({ - ListFinancialEventGroupsByNextTokenResponse: Codec.interface({ - ListFinancialEventGroupsByNextTokenResult: ListFinancialEventGroups, - }), -}) - export class Finances { constructor(private httpClient: HttpClient) {} + async listFinancialEvents( + parameters: RequireOnlyOne< + ListFinancicalEventsParameters, + 'PostedAfter' | 'AmazonOrderId' | 'FinancialEventGroupId' + >, + ): Promise<[ListFinancialEvents, RequestMeta]> { + const [response, meta] = await this.httpClient.request('POST', { + resource: Resource.Finances, + version: FINANCES_API_VERSION, + action: 'ListFinancialEvents', + parameters: { + MaxResultsPerPage: parameters.MaxResultsPerPage, + AmazonOrderId: parameters.AmazonOrderId, + FinancialEventGroupId: parameters.FinancialEventGroupId, + PostedAfter: parameters.PostedAfter?.toISOString(), + PostedBefore: parameters.PostedBefore?.toISOString(), + }, + }) + + return ListFinancialEventsResponse.decode(response).caseOf({ + Right: (x) => [x.ListFinancialEventsResponse.ListFinancialEventsResult, meta], + Left: (error) => { + throw new ParsingError(error) + }, + }) + } + async listFinancialEventGroupsByNextToken( nextToken: NextToken<'ListFinancialEventGroups'>, ): Promise<[ListFinancialEventGroups, RequestMeta]> { diff --git a/test/unit/__snapshots__/finances.test.ts.snap b/test/unit/__snapshots__/finances.test.ts.snap index a8167c14..2e40fe7b 100644 --- a/test/unit/__snapshots__/finances.test.ts.snap +++ b/test/unit/__snapshots__/finances.test.ts.snap @@ -93,3 +93,187 @@ Array [ }, ] `; + +exports[`finances listFinancialEvents returns a next token and financial events list if succesful 1`] = ` +Array [ + Object { + "FinancialEvents": Object { + "AdjustmentEventList": "", + "AffordabilityExpenseEventList": Object { + "AffordabilityExpenseEvent": Object { + "AmazonOrderId": "931-2463294-5740665", + "BaseExpense": Object { + "CurrencyAmount": -100, + "CurrencyCode": "INR", + }, + "MarketplaceId": "A2XZLSVIQ0F4JT", + "PostedDate": "2018-02-08T13:17:15.000Z", + "TaxTypeCGST": Object { + "CurrencyAmount": 0, + "CurrencyCode": "INR", + }, + "TaxTypeIGST": Object { + "CurrencyAmount": -18, + "CurrencyCode": "INR", + }, + "TaxTypeSGST": Object { + "CurrencyAmount": 0, + "CurrencyCode": "INR", + }, + "TotalExpense": Object { + "CurrencyAmount": -118, + "CurrencyCode": "INR", + }, + "TransactionType": "Charge", + }, + }, + "AffordabilityExpenseReversalEventList": Object { + "AffordabilityExpenseReversalEvent": Object { + "AmazonOrderId": "931-2463294-5740665", + "BaseExpense": Object { + "CurrencyAmount": 100, + "CurrencyCode": "INR", + }, + "MarketplaceId": "A2XZLSVIQ0F4JT", + "PostedDate": "2018-02-08T13:17:15.000Z", + "TaxTypeCGST": Object { + "CurrencyAmount": 0, + "CurrencyCode": "INR", + }, + "TaxTypeIGST": Object { + "CurrencyAmount": 18, + "CurrencyCode": "INR", + }, + "TaxTypeSGST": Object { + "CurrencyAmount": 0, + "CurrencyCode": "INR", + }, + "TotalExpense": Object { + "CurrencyAmount": 118, + "CurrencyCode": "INR", + }, + "TransactionType": "Refund", + }, + }, + "ChargebackEventList": "", + "DebtRecoveryEventList": "", + "GuaranteeClaimEventList": "", + "LoanServicingEventList": "", + "PayWithAmazonEventList": "", + "PerformanceBondRefundEventList": "", + "ProductAdsPaymentEventList": Array [ + "", + Object { + "ProductAdsPaymentEvent": Object { + "PostedDate": "2017-01-11T13:17:15.000Z", + "baseValue": Object { + "CurrencyAmount": 115.34, + "CurrencyCode": "USD", + }, + "invoiceId": "TR1W0B4YB-6", + "taxValue": Object { + "CurrencyAmount": 21.91, + "CurrencyCode": "USD", + }, + "transactionType": "Charge", + "transactionValue": Object { + "CurrencyAmount": 137.25, + "CurrencyCode": "USD", + }, + }, + }, + ], + "RefundEventList": "", + "RentalTransactionEventList": "", + "RetrochargeEventList": "", + "SellerDealPaymentEventList": Object { + "SellerDealPaymentEvent": Object { + "DealDescription": "test fees", + "DealId": "fec11097c1f4379426a7de68bf938b684f677de2", + "EventType": "SellerDealComplete", + "FeeAmount": Object { + "CurrencyAmount": 16.38, + "CurrencyCode": "USD", + }, + "FeeType": "RunLightningDealFee", + "PostedDate": "2016-11-21T16:18:15.000Z", + "TaxAmount": Object { + "CurrencyAmount": 3.18, + "CurrencyCode": "USD", + }, + }, + }, + "ServiceFeeEventList": "", + "ServiceProviderCreditEventList": "", + "ShipmentEventList": Object { + "ShipmentEvent": Object { + "AmazonOrderId": "105-0457358-1245022", + "MarketplaceName": "Amazon.com", + "PostedDate": "2017-01-23T01:31:25Z", + "SellerOrderId": "105-0457358-1245022", + "ShipmentItemList": Object { + "ShipmentItem": Object { + "ItemChargeList": Object { + "ChargeComponent": Array [ + Object { + "ChargeAmount": Object { + "CurrencyAmount": 25.99, + "CurrencyCode": "USD", + }, + "ChargeType": "Principal", + }, + Object { + "ChargeAmount": Object { + "CurrencyAmount": 0, + "CurrencyCode": "USD", + }, + "ChargeType": "Tax", + }, + ], + }, + "ItemFeeList": Object { + "FeeComponent": Array [ + Object { + "FeeAmount": Object { + "CurrencyAmount": 0, + "CurrencyCode": "USD", + }, + "FeeType": "ShippingChargeback", + }, + Object { + "FeeAmount": Object { + "CurrencyAmount": 0, + "CurrencyCode": "USD", + }, + "FeeType": "VariableClosingFee", + }, + ], + }, + "OrderItemId": 46432915698730, + "QuantityShipped": 1, + "SellerSKU": "HS223A-C00", + }, + }, + }, + }, + "TDSReimbursementEventList": Object { + "TDSReimbursementEvent": Object { + "PostedDate": "2019-08-01T16:18:15.000Z", + "ReimbursedAmount": Object { + "CurrencyAmount": 3.98, + "CurrencyCode": "INR", + }, + "TdsOrderId": "TDS-1235", + }, + }, + }, + }, + Object { + "quotaMax": 1000, + "quotaRemaining": 999, + "quotaResetOn": 2020-04-06T10:22:23.582Z, + "requestId": "0", + "timestamp": 2020-05-06T09:22:23.582Z, + }, +] +`; diff --git a/test/unit/finances.test.ts b/test/unit/finances.test.ts index f9b69caa..4e43b43d 100644 --- a/test/unit/finances.test.ts +++ b/test/unit/finances.test.ts @@ -38,7 +38,7 @@ const parsingError = 'Expected an object, but received a string with value ""' describe('finances', () => { describe('listFinancialEvents', () => { const parameters = { - PostedBefore: new Date(), + PostedAfter: new Date(), } it('returns a next token and financial events list if succesful', async () => {