avadev / AvaTax-REST-V2-JS-SDK

Sales Tax API SDK for Javascript / Node and AvaTax REST
https://developer.avalara.com/sdk/
Apache License 2.0
28 stars 37 forks source link

`createTransaction` returns its `type` property as a `string` instead of the numeric `enum` #249

Closed BioSurienDG closed 1 year ago

BioSurienDG commented 1 year ago

The typescript for the SDK says that when you call .createTransaction it should return a transaction model where type is an enum as defined here: https://github.com/avadev/AvaTax-REST-V2-JS-SDK/blob/master/lib/models/TransactionModel.ts#L56-L60

export declare enum DocumentType {
    SalesOrder = 0,
    SalesInvoice = 1,
    PurchaseOrder = 2,
    PurchaseInvoice = 3,
    ReturnOrder = 4,
    ReturnInvoice = 5,
    InventoryTransferOrder = 6,
    InventoryTransferInvoice = 7,
    ReverseChargeOrder = 8,
    ReverseChargeInvoice = 9,
    CustomsInvoice = 10,
    CustomsOrder = 11,
    Any = -1
}

As you can see the return type of the function createTransaction should populate type as a number. However, from inspecting the result in the debugger it is actually a string not a number (see screenshot).

This should be fixed (either the type needs to change or the API result should change to match the expected enum).

image

Same issue for status field on the returned transaction (i.e. it uses the string representation instead of the numeric value from the DocumentStatus enum)

svc-developer commented 1 year ago

Fixed in release 23.3.0 Please give it a try and let us know if you have any further issues https://github.com/avadev/AvaTax-REST-V2-JS-SDK/releases/tag/23.3.0 You'll have to opt-in to the feature by passing in enableStrictTypeConversion: true to the constructor for the SDK.

robobeau commented 1 year ago

There's still a problem, here, @svc-developer.

The typing for createTransaction is expecting a model that has a type property defined as

    /**
     * @type {Enums.DocumentType}
     * @memberof CreateTransactionModel
     */
    type?: Enums.DocumentType | undefined;

But the documentation suggests that we need to be using a string, for example "SalesInvoice" instead of the enum value for DocumentType.SalesInvoice, which is 1.

BioSurienDG commented 1 year ago

@robobeau I think the actual API accepts either the numerical enum value or the string from my testing?

svc-developer commented 1 year ago

@BioSurienDG Correct, @robobeau Let us know if that doesn't work for you

uwitdat commented 1 year ago

I have to convert the type to unknown before I can type it when using a string here.

  const taxDocument = formatTaxDocument({
    type: 'SalesInvoice' as unknown as CreateTransactionModel['type'],
    shippingAddress: formattedShippingAddress,
    items,
    customerId,
    commit: false,
    currencyCode: 'USD',
  })
export function formatTaxDocument(params: TaxDocumentParams) {
  const taxDocument: CreateTransactionModel = {
    type: params.type,
    companyCode: process.env.AVATAX_COMPANY_CODE,
    date: new Date(),
    customerCode: params.customerId || 'N/A',
    addresses: {
      shipTo: params.shippingAddress,
      shipFrom: {
        locationCode: process.env.AVATAX_LOCATION_CODE,
      },
    },
    lines: params.items,
    commit: params.commit,
    currencyCode: params.currencyCode,
  }

  return taxDocument
}

If I remove the parsing I get this TS error

Type 'string' is not assignable to type 'DocumentType | undefined'.ts(2322)
index.ts(43, 3): The expected type comes from property 'type' which is declared here on type 'TaxDocumentParams'

What's the best practice here? Is it using DocumentType.SalesInvoice?

svc-developer commented 1 year ago

@uwitdat Yes, use the enums directly and it should work

oleg-codaio commented 1 year ago

Just ran into this issue as well. Maybe you could make enableStrictTypeConversion: true required in TypeScript in the AvaTaxClient constructor? That way for folks using TypeScript, they'll get the correct behavior. Those using JS can fall back to the default of string enums. (Side note, I do think numeric enums by default are a mistake and strings would be much more friendly.)

Also could you export enums and models from the top-level avatax module so we don't need to reach into the import and have to write import * as AvaTaxEnums from 'avatax/lib/enums/index';?