diff --git a/.gitignore b/.gitignore index 1a49fc9..328aa57 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ node_modules coverage/ package-lock.json *.xml +.env +.DS_Store diff --git a/lib/main.js b/lib/main.js index b83a779..ca9840e 100644 --- a/lib/main.js +++ b/lib/main.js @@ -50,7 +50,7 @@ function Client( /** * Check api version for w2 documents * @private - * @throws if api_version is different to v8 + * @throws error when api_version is different to v8 */ Client.prototype._check_w2_version = function () { if (this.api_version !== "v8") throw Error("w2 is only supported on v8") @@ -64,7 +64,7 @@ Client.prototype._check_w2_version = function () { */ Client.prototype._get_headers = function (has_files = false) { let final_headers = { - "User-Agent": "Node.js Veryfi-Nodejs/1.2.0", + "User-Agent": "Node.js Veryfi-Nodejs/1.2.3", "Accept": "application/json", "Content-Type": "application/json", "Client-Id": this.client_id, @@ -211,7 +211,7 @@ Client.prototype.process_document = async function ( if (!categories) { categories = this.CATEGORIES; } - let file_name = path.basename(file_path) + let file_name = path.basename(file_path); const image_file = fs.readFileSync(file_path, {encoding: 'base64'}); const base64_encoded_string = Buffer.from(image_file).toString('utf-8'); let request_arguments = { @@ -220,8 +220,8 @@ Client.prototype.process_document = async function ( "categories": categories, "auto_delete": delete_after_processing, }; - request_arguments = Object.assign(request_arguments, kwargs) - let document = await this._request("POST", endpoint_name, request_arguments) + request_arguments = Object.assign(request_arguments, kwargs); + let document = await this._request("POST", endpoint_name, request_arguments); return document['data']; } @@ -260,8 +260,8 @@ Client.prototype.process_document_buffer = async function ( "categories": categories, "auto_delete": delete_after_processing, }; - request_arguments = Object.assign(request_arguments, kwargs) - let document = await this._request("POST", endpoint_name, request_arguments) + request_arguments = Object.assign(request_arguments, kwargs); + let document = await this._request("POST", endpoint_name, request_arguments); return document['data']; } @@ -304,7 +304,7 @@ Client.prototype.process_document_url = async function ( "file_urls": file_urls, "max_pages_to_process": max_pages_to_process, }; - request_arguments = Object.assign(request_arguments, kwargs) + request_arguments = Object.assign(request_arguments, kwargs); let response = await this._request("POST", endpoint_name, request_arguments); return response['data']; } @@ -344,15 +344,15 @@ Client.prototype.update_document = async function (document_id, {...kwargs} = {} * @return {Array} An array of JSON with all w2 documents. */ Client.prototype.get_w2_documents = async function (page = null) { - this._check_w2_version() - let endpoint_name = "/w2s/" - let request_arguments = {} - let params = {} + this._check_w2_version(); + let endpoint_name = "/w2s/"; + let request_arguments = {}; + let params = {}; if (page !== null) { - params = {"page": page} + params = {"page": page}; } - let response = await this._request("GET", endpoint_name, request_arguments, params) - return response['data']['results'] + let response = await this._request("GET", endpoint_name, request_arguments, params); + return response['data']['results']; } /** @@ -364,11 +364,11 @@ Client.prototype.get_w2_documents = async function (page = null) { Client.prototype.get_w2_document = async function ( document_id, ) { - this._check_w2_version() - let endpoint_name = `/w2s/${document_id}/` - let request_arguments = {"id": document_id} - let response = await this._request("GET", endpoint_name, request_arguments) - return response['data'] + this._check_w2_version(); + let endpoint_name = `/w2s/${document_id}/`; + let request_arguments = {"id": document_id}; + let response = await this._request("GET", endpoint_name, request_arguments); + return response['data']; } /** @@ -396,9 +396,9 @@ Client.prototype.process_w2_document_from_buffer = async function ( "auto_delete": delete_after_processing, "max_pages_to_process": max_pages_to_process, } - request_arguments = Object.assign(request_arguments, kwargs) - let response = await this._request("POST", endpoint_name, request_arguments) - return response['data'] + request_arguments = Object.assign(request_arguments, kwargs); + let response = await this._request("POST", endpoint_name, request_arguments); + return response['data']; } /** @@ -424,7 +424,7 @@ Client.prototype.process_w2_document = async function ( delete_after_processing, max_pages_to_process, kwargs - ) + ); } /** @@ -456,11 +456,38 @@ Client.prototype.process_w2_document_from_url = async function ( "file_urls": file_urls, "max_pages_to_process": max_pages_to_process } - request_arguments = Object.assign(request_arguments, kwargs) - let response = await this._request("POST", endpoint_name, request_arguments) - return response['data'] + request_arguments = Object.assign(request_arguments, kwargs); + let response = await this._request("POST", endpoint_name, request_arguments); + return response['data']; +} + +/** + * Add a new tag on an existing document + * + * @param {number} document_id ID of the document you'd like to add a Tag + * @param {string} tag name to add + * @return {JSON} response about tag added. + */ +Client.prototype.add_tag = async function (document_id, tag) { + let endpoint_name = `/documents/${document_id}/tags/`; + let request_arguments = {"name": tag}; + let response = await this._request("PUT", endpoint_name, request_arguments); + return response['data']; +} + +/** + * Delete all the tags on an existing document + * + * @param {number} document_id ID of the document you'd like to delete tags + * @return {JSON} response about deleted tags. + */ +Client.prototype.delete_tags = async function (document_id) { + let endpoint_name = `/documents/${document_id}/tags/`; + let request_arguments = {}; + return this._request("DELETE", endpoint_name, request_arguments); } + // Exports module.exports = Client; diff --git a/lib/types/main.d.ts b/lib/types/main.d.ts index ed41f49..920f1fb 100644 --- a/lib/types/main.d.ts +++ b/lib/types/main.d.ts @@ -122,6 +122,11 @@ declare type Payment = { type?: null | string; }; +declare type Tag = { + id?: null | number; + name?: null | string; +}; + export declare class Client { /** * Create instance of a Client @@ -234,10 +239,10 @@ export declare class Client { * @param {string} document_id ID of the document you'd like to delete * @returns {Promise} Object of data extracted from the document */ - public delete_document(document_id: string): Promise; + public delete_document(document_id: string): Promise; /** - * Update data for a previously processed document, including almost any field like `vendor`, `date`, `notes` and etc. + * Update data for a previously processed document, including almost any field like `vendor`, `date`, `notes` etc. * @example * veryfi_client.update_document( * id, @@ -252,6 +257,24 @@ export declare class Client { document_id: string, { ...kwargs }?: VeryfiExtraArgs ): Promise; + + /** + * Add a new tag on an existing document + * + * @param {number} document_id ID of the document you'd like to add a Tag + * @param {string} tag name to add + * @return {Promise} response about tag added. + */ + public add_tag(document_id: string, tag: string): Promise; + + /** + * Delete all tags on an existing document + * + * @param {number} document_id ID of the document you'd like to delete all Tags + * @return {Promise} response about deleted tags. + */ + public delete_tags(document_id: string): Promise; + } /** diff --git a/package.json b/package.json index e921e2f..b5d27f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@veryfi/veryfi-sdk", - "version": "1.2.2", + "version": "1.2.3", "description": "Node.js module for communicating with the Veryfi OCR API", "main": "lib/main.js", "typings": "lib/types/main.d.ts", diff --git a/test/main.test.js b/test/main.test.js index de0361c..55322a2 100644 --- a/test/main.test.js +++ b/test/main.test.js @@ -11,7 +11,7 @@ const client_secret = process.env.VERYFI_CLIENT_SECRET; const username = process.env.VERYFI_USERNAME; const api_key = process.env.VERYFI_API_KEY; const base_url = process.env.VERYFI_URL; -const api_version = "v7" +const api_version = "v8" const timeout = 100000; //Creating the Client @@ -46,7 +46,7 @@ describe('Processing documents', () => { test('Process document from URL', async () => { try { let response = await veryfi_client.process_document_url('https://cdn.veryfi.com/receipts/92233902-c94a-491d-a4f9-0d61f9407cd2.pdf'); - expect(response['vendor']['name']).toBe('Rumpke Of Ohio'); + expect(response['vendor']['name']).toBe('Rumpke of Ohio'); } catch (error) { throw new Error(error); } @@ -57,7 +57,7 @@ describe('Managing documents', () => { test('Get documents', async () => { try { let docs = await veryfi_client.get_documents(); - expect(docs.length).toBeGreaterThan(0); + expect(docs.documents.length).toBeGreaterThan(0); } catch (error) { throw new Error(error); } @@ -66,9 +66,35 @@ describe('Managing documents', () => { test(`Get document with id `, async () => { try { let docs = await veryfi_client.get_documents(); - const doc_id = docs[0].id; + const doc_id = docs.documents[0].id; let doc = await veryfi_client.get_document(doc_id); - expect(doc['id']).toBe(doc_id) + expect(doc['id']).toBe(doc_id); + } catch (error) { + throw new Error(error); + } + }); +}); + +describe('Managing tags', () => { + test(`Delete all tags of a document`, async () => { + try { + let docs = await veryfi_client.get_documents(); + const doc_id = docs.documents[0].id; + let response = await veryfi_client.delete_tags(doc_id); + expect(response).toBeDefined() + } catch (error) { + throw new Error(error); + } + }); + + test(`Add tag to a document`, async () => { + try { + let tag_name = 'TEST_TAG' + let docs = await veryfi_client.get_documents(); + const doc_id = docs.documents[0].id; + await veryfi_client.delete_tags(doc_id); + let tag = await veryfi_client.add_tag(doc_id, tag_name); + expect(tag.name).toBe(tag_name) } catch (error) { throw new Error(error); } @@ -81,7 +107,7 @@ describe('Editing Documents', () => { let params = {'notes': randomString}; try { let docs = await veryfi_client.get_documents(); - const doc_id = docs[0].id; + const doc_id = docs.documents[0].id; let response = await veryfi_client.update_document(doc_id, params); expect(response).toEqual(expect.objectContaining(params)); } catch (error) { @@ -92,9 +118,9 @@ describe('Editing Documents', () => { test('Delete a document by id', async () => { try { let docs = await veryfi_client.get_documents(); - const doc_id = docs[0].id; + const doc_id = docs.documents[0].id; let response = await veryfi_client.delete_document(doc_id); - expect(response['status']).toBe(200) + expect(response['status']).toBeDefined(); } catch (error) { throw new Error(error); } @@ -102,7 +128,7 @@ describe('Editing Documents', () => { }) describe('Process w2 documents', () => { - test('Process a document from file_path', async () => { + test('Process a w2 document from file_path', async () => { try { await veryfi_client.process_w2_document('resources/w2.png', true); assert(false) @@ -110,7 +136,7 @@ describe('Process w2 documents', () => { assert(true) } }) - test('Get a documents and get a document by id', async () => { + test('Get a w2 documents and get a document by id', async () => { try { await veryfi_client.get_w2_documents() assert(false) @@ -118,7 +144,7 @@ describe('Process w2 documents', () => { assert(true) } }) - test('Process a document from url', async () => { + test('Process a w2 document from url', async () => { try{ await veryfi_client.process_w2_document_from_url( 'w2.png', diff --git a/tests/main.test.ts b/tests/main.test.ts index a5bd455..80610c7 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -20,7 +20,7 @@ let veryfi_client = new Client(client_id, client_secret, username, api_key, base jest.setTimeout(timeout); describe('Processing documents', () => { - test('Upload invoice for processing', async () => { + test('Upload receipt for processing', async () => { try { let response: VeryfiDocument = await veryfi_client.process_document('resources/receipt.png'); checkReceiptResponse(response); @@ -44,7 +44,7 @@ describe('Processing documents', () => { } }); - test('Process document from URL', async () => { + test('Process invoice document from URL', async () => { try { let response = await veryfi_client.process_document_url('https://cdn.veryfi.com/receipts/92233902-c94a-491d-a4f9-0d61f9407cd2.pdf'); checkInvoiceResponse(response); @@ -57,28 +57,27 @@ describe('Processing documents', () => { expect(response.vendor.name).toBe('The Home Depot'); expect(response.vendor.address).toBe('2250 Southgate Rd, Colorado Springs, CO 80906'); expect(response.date).toBe('2018-10-17 09:03:00'); - expect(response.invoice_number).toBe('17717'); expect(response.total).toBe(34.95); expect(response.tax).toBe(2.66); expect(response.subtotal).toBe(32.29); expect(response.category).toBe('Job Supplies'); expect(response.document_type).toBe("receipt"); - expect(response.document_reference_number).toBe('4341505054414'); + expect(response.document_reference_number).toBe('452050595341'); expect(response.line_items.length).toBe(4); expect(response.payment.card_number).toBe('7373'); expect(response.payment.type).toBe('visa'); } const checkInvoiceResponse = (response: VeryfiDocument) => { - expect(response.vendor.name).toBe('Rumpke Of Ohio'); - expect(response.vendor.address).toBe('3800 Struble Road, Cincinnati, Ohio 45251, United States'); + expect(response.vendor.name).toBe('Rumpke of Ohio'); + expect(response.vendor.address).toBe('10795 Hughes Rd, Cincinnati, OH, 45251, US'); expect(response.date).toBe('2020-08-04 00:00:00'); expect(response.due_date).toBe('2020-08-19'); expect(response.invoice_number).toBe('0998811'); expect(response.total).toBe(329.74); expect(response.tax).toBe(23.47); expect(response.subtotal).toBe(306.27); - expect(response.category).toBe('Repairs & Maintenance'); + expect(response.category).toBe('Utilities'); expect(response.document_type).toBe("invoice"); expect(response.line_items[0].total).toBe(116.32); expect(response.line_items[1].total).toBe(10); @@ -111,6 +110,32 @@ describe('Managing documents', () => { }); }); +describe('Managing tags', () => { + test(`Delete all tags of a document`, async () => { + try { + let docs = await veryfi_client.get_documents(); + const doc_id = docs.documents[0].id; + let response = await veryfi_client.delete_tags(doc_id); + expect(response).toBeDefined() + } catch (error) { + throw new Error(error); + } + }); + + test(`Add tag to a document`, async () => { + try { + let tag_name = 'TEST_TAG' + let docs = await veryfi_client.get_documents(); + const doc_id = docs.documents[0].id; + await veryfi_client.delete_tags(doc_id); + let tag = await veryfi_client.add_tag(doc_id, tag_name); + expect(tag.name).toBe(tag_name) + } catch (error) { + throw new Error(error); + } + }); +}); + describe('Editing Documents', () => { test('Update a document\'s entries', async () => { const randomString = (Math.random() + 1).toString(36).substring(7); @@ -138,7 +163,7 @@ describe('Editing Documents', () => { }); describe('Process w2 documents', () => { - test('Process a document from file_path', async () => { + test('Process a w2 document from file_path', async () => { try { let doc = await veryfi_client.process_w2_document('resources/w2.png', true); expect(doc['control_number']).toBe('A1B2'); @@ -147,7 +172,7 @@ describe('Process w2 documents', () => { throw new Error(error); } }) - test('Get documents and get a document by id', async () => { + test('Get w2 documents and get a w2 document by id', async () => { try { let docs = await veryfi_client.get_w2_documents(); expect(docs.length).toBeGreaterThan(1); @@ -158,15 +183,15 @@ describe('Process w2 documents', () => { throw new Error(error); } }) - test('Get documents with page', async () => { + test('Get w2 documents with page', async () => { try { - let docs = await veryfi_client.get_w2_documents(3); + let docs = await veryfi_client.get_w2_documents(1); expect(docs.length).toBeGreaterThan(1); } catch (error) { throw new Error(error) } }) - test('Process a document from url', async () => { + test('Process a w2 document from url', async () => { try{ let doc = await veryfi_client.process_w2_document_from_url( 'w2.png',