diff --git a/README.md b/README.md index cb9c11d..4962f6d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Pacote de integração com a [API v3 do ERP Bling](https://developer.bling.com.br) para Javascript/TypeScript. O mais completo existente. -Atualizado com a versão `v291` da API ([veja o registro de alterações](https://developer.bling.com.br/changelogs#2024-01-31)). +Atualizado com a versão `v292` da API ([veja o registro de alterações](https://developer.bling.com.br/changelogs#2024-01-31)). **Atenção**: a versão 5.0.0+ do `bling-erp-api` para Javascript/TypeScript utiliza a API v3 do Bling. Caso deseja utilizar a API v2 do Bling, diff --git a/package.json b/package.json index 3ca4a11..620cfb1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bling-erp-api", - "version": "5.2.0", + "version": "5.3.0", "description": "Pacote de integração com a API do Bling ERP", "main": "lib/bling.js", "directories": { @@ -67,4 +67,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/src/entities/nfces/__tests__/index.spec.ts b/src/entities/nfces/__tests__/index.spec.ts index 46c986e..c517ce2 100644 --- a/src/entities/nfces/__tests__/index.spec.ts +++ b/src/entities/nfces/__tests__/index.spec.ts @@ -1,11 +1,19 @@ import { Chance } from 'chance' import { Nfces } from '..' import { InMemoryBlingRepository } from '../../../repositories/bling-in-memory.repository' +import { ICreateResponse } from '../interfaces/create.interface' +import { IFindResponse } from '../interfaces/find.interface' +import { IGetResponse } from '../interfaces/get.interface' +import { ISendResponse } from '../interfaces/send.interface' +import { IUpdateResponse } from '../interfaces/update.interface' import createResponse, { createRequestBody } from './create-response' import findResponse from './find-response' import getResponse from './get-response' import postAccountsResponse from './post-accounts-response' +import postStockResponse from './post-stock-response' +import postStockToDepositResponse from './post-stock-to-deposit-response' import reverseAccountsResponse from './reverse-accounts-response' +import reverseStockResponse from './reverse-stock-response' import sendResponse from './send-response' import updateResponse, { updateRequestBody } from './update-response' @@ -41,6 +49,9 @@ describe('NFC-es entity', () => { } }) expect(response).toBe(getResponse) + + const typingResponseTest: IGetResponse = getResponse + expect(typingResponseTest).toBe(getResponse) }) it('should find successfully', async () => { @@ -55,6 +66,9 @@ describe('NFC-es entity', () => { id: String(idNotaFiscalConsumidor) }) expect(response).toBe(findResponse) + + const typingResponseTest: IFindResponse = findResponse + expect(typingResponseTest).toBe(findResponse) }) it('should create successfully', async () => { @@ -68,6 +82,9 @@ describe('NFC-es entity', () => { body: createRequestBody }) expect(response).toBe(createResponse) + + const typingResponseTest: ICreateResponse = createResponse + expect(typingResponseTest).toBe(createResponse) }) it('should send successfully', async () => { @@ -82,6 +99,9 @@ describe('NFC-es entity', () => { body: {} }) expect(response).toBe(sendResponse) + + const typingResponseTest: ISendResponse = sendResponse + expect(typingResponseTest).toBe(sendResponse) }) it('should post accounts successfully', async () => { @@ -96,6 +116,9 @@ describe('NFC-es entity', () => { body: {} }) expect(response).toBe(postAccountsResponse) + + const typingResponseTest: null = postAccountsResponse + expect(typingResponseTest).toBe(postAccountsResponse) }) it('should reverse accounts successfully', async () => { @@ -110,6 +133,64 @@ describe('NFC-es entity', () => { body: {} }) expect(response).toBe(reverseAccountsResponse) + + const typingResponseTest: null = reverseAccountsResponse + expect(typingResponseTest).toBe(reverseAccountsResponse) + }) + + it('should post stock successfully', async () => { + const spy = jest.spyOn(repository, 'store') + const idNotaFiscalConsumidor = chance.natural() + repository.setResponse(postStockResponse) + + const response = await entity.postStock({ idNotaFiscalConsumidor }) + + expect(spy).toHaveBeenCalledWith({ + endpoint: `nfce/${idNotaFiscalConsumidor}/lancar-estoque`, + body: {} + }) + expect(response).toBe(postStockResponse) + + const typingResponseTest: null = postStockResponse + expect(typingResponseTest).toBe(postStockResponse) + }) + + it('should post stock to deposit successfully', async () => { + const spy = jest.spyOn(repository, 'store') + const idNotaFiscalConsumidor = chance.natural() + const idDeposito = chance.natural() + repository.setResponse(postStockToDepositResponse) + + const response = await entity.postStockToDeposit({ + idNotaFiscalConsumidor, + idDeposito + }) + + expect(spy).toHaveBeenCalledWith({ + endpoint: `nfce/${idNotaFiscalConsumidor}/lancar-estoque/${idDeposito}`, + body: {} + }) + expect(response).toBe(postStockToDepositResponse) + + const typingResponseTest: null = postStockToDepositResponse + expect(typingResponseTest).toBe(postStockToDepositResponse) + }) + + it('should reverse stock successfully', async () => { + const spy = jest.spyOn(repository, 'store') + const idNotaFiscalConsumidor = chance.natural() + repository.setResponse(reverseStockResponse) + + const response = await entity.reverseStock({ idNotaFiscalConsumidor }) + + expect(spy).toHaveBeenCalledWith({ + endpoint: `nfce/${idNotaFiscalConsumidor}/estornar-estoque`, + body: {} + }) + expect(response).toBe(reverseStockResponse) + + const typingResponseTest: null = reverseStockResponse + expect(typingResponseTest).toBe(reverseStockResponse) }) it('should update successfully', async () => { @@ -128,5 +209,8 @@ describe('NFC-es entity', () => { body: updateRequestBody }) expect(response).toBe(updateResponse) + + const typingResponseTest: IUpdateResponse = updateResponse + expect(typingResponseTest).toBe(updateResponse) }) }) diff --git a/src/entities/nfces/__tests__/post-stock-response.ts b/src/entities/nfces/__tests__/post-stock-response.ts new file mode 100644 index 0000000..7b85954 --- /dev/null +++ b/src/entities/nfces/__tests__/post-stock-response.ts @@ -0,0 +1 @@ +export default null diff --git a/src/entities/nfces/__tests__/post-stock-to-deposit-response.ts b/src/entities/nfces/__tests__/post-stock-to-deposit-response.ts new file mode 100644 index 0000000..7b85954 --- /dev/null +++ b/src/entities/nfces/__tests__/post-stock-to-deposit-response.ts @@ -0,0 +1 @@ +export default null diff --git a/src/entities/nfces/__tests__/reverse-stock-response.ts b/src/entities/nfces/__tests__/reverse-stock-response.ts new file mode 100644 index 0000000..7b85954 --- /dev/null +++ b/src/entities/nfces/__tests__/reverse-stock-response.ts @@ -0,0 +1 @@ +export default null diff --git a/src/entities/nfces/__tests__/update-response.ts b/src/entities/nfces/__tests__/update-response.ts index 2da8797..811dd57 100644 --- a/src/entities/nfces/__tests__/update-response.ts +++ b/src/entities/nfces/__tests__/update-response.ts @@ -1,6 +1,11 @@ export default { data: { - id: 12345678 + id: 12345678, + numero: '6541', + serie: '1', + contato: { + nome: 'Contato do Bling' + } } } diff --git a/src/entities/nfces/index.ts b/src/entities/nfces/index.ts index 2b29c1d..2ef58c5 100644 --- a/src/entities/nfces/index.ts +++ b/src/entities/nfces/index.ts @@ -3,7 +3,10 @@ import { ICreateBody, ICreateResponse } from './interfaces/create.interface' import { IFindParams, IFindResponse } from './interfaces/find.interface' import { IGetParams, IGetResponse } from './interfaces/get.interface' import { IPostAccountsParams } from './interfaces/post-accounts.interface' +import { IPostStockToDepositParams } from './interfaces/post-stock-to-deposit.interface' +import { IPostStockParams } from './interfaces/post-stock.interface' import { IReverseAccountsParams } from './interfaces/reverse-accounts.interface' +import { IReverseStockParams } from './interfaces/reverse-stock.interface' import { ISendParams, ISendResponse } from './interfaces/send.interface' import { IUpdateBody, @@ -129,6 +132,59 @@ export class Nfces extends Entity { }) } + /** + * Lança o estoque de uma nota fiscal no depósito padrão. + * + * @param {IPostStockParams} params O conteúdo para o lançamento. + * + * @returns {Promise} + * @throws {BlingApiException|BlingInternalException} + * + * @see https://developer.bling.com.br/referencia#/Notas%20Fiscais%20de%20Consumidor%20Eletr%C3%B4nicas/post_nfce__idNotaFiscalConsumidor__lancar_estoque + */ + public async postStock(params: IPostStockParams): Promise { + return await this.repository.store({ + endpoint: `nfce/${params.idNotaFiscalConsumidor}/lancar-estoque`, + body: {} + }) + } + + /** + * Lança o estoque de uma nota fiscal especificando o depósito. + * + * @param {IPostStockToDepositParams} params O conteúdo para o lançamento. + * + * @returns {Promise} + * @throws {BlingApiException|BlingInternalException} + * + * @see https://developer.bling.com.br/referencia#/Notas%20Fiscais%20de%20Consumidor%20Eletr%C3%B4nicas/post_nfce__idNotaFiscalConsumidor__lancar_estoque__idDeposito_ + */ + public async postStockToDeposit( + params: IPostStockToDepositParams + ): Promise { + return await this.repository.store({ + endpoint: `nfce/${params.idNotaFiscalConsumidor}/lancar-estoque/${params.idDeposito}`, + body: {} + }) + } + + /** + * Estorna o estoque de uma nota fiscal. + * + * @param {IReverseStockParams} params O conteúdo para o estorno. + * + * @returns {Promise} + * @throws {BlingApiException|BlingInternalException} + * + * @see https://developer.bling.com.br/referencia#/Notas%20Fiscais%20de%20Consumidor%20Eletr%C3%B4nicas/post_nfce__idNotaFiscalConsumidor__estornar_estoque + */ + public async reverseStock(params: IReverseStockParams): Promise { + return await this.repository.store({ + endpoint: `nfce/${params.idNotaFiscalConsumidor}/estornar-estoque`, + body: {} + }) + } + /** * Altera uma nota fiscal de consumidor. * diff --git a/src/entities/nfces/interfaces/post-stock-to-deposit.interface.ts b/src/entities/nfces/interfaces/post-stock-to-deposit.interface.ts new file mode 100644 index 0000000..e498e63 --- /dev/null +++ b/src/entities/nfces/interfaces/post-stock-to-deposit.interface.ts @@ -0,0 +1,10 @@ +export interface IPostStockToDepositParams { + /** + * ID da nota fiscal de consumidor + */ + idNotaFiscalConsumidor: number + /** + * ID do depósito + */ + idDeposito: number +} diff --git a/src/entities/nfces/interfaces/post-stock.interface.ts b/src/entities/nfces/interfaces/post-stock.interface.ts new file mode 100644 index 0000000..30ec078 --- /dev/null +++ b/src/entities/nfces/interfaces/post-stock.interface.ts @@ -0,0 +1,6 @@ +export interface IPostStockParams { + /** + * ID da nota fiscal de consumidor + */ + idNotaFiscalConsumidor: number +} diff --git a/src/entities/nfces/interfaces/reverse-stock.interface.ts b/src/entities/nfces/interfaces/reverse-stock.interface.ts new file mode 100644 index 0000000..e07235a --- /dev/null +++ b/src/entities/nfces/interfaces/reverse-stock.interface.ts @@ -0,0 +1,6 @@ +export interface IReverseStockParams { + /** + * ID da nota fiscal de consumidor + */ + idNotaFiscalConsumidor: number +} diff --git a/src/entities/nfes/__tests__/index.spec.ts b/src/entities/nfes/__tests__/index.spec.ts index 752ccc2..c90d99f 100644 --- a/src/entities/nfes/__tests__/index.spec.ts +++ b/src/entities/nfes/__tests__/index.spec.ts @@ -1,12 +1,21 @@ import { Chance } from 'chance' import { Nfes } from '..' import { InMemoryBlingRepository } from '../../../repositories/bling-in-memory.repository' +import { ICreateResponse } from '../interfaces/create.interface' +import { IDeleteResponse } from '../interfaces/delete.interface' +import { IFindResponse } from '../interfaces/find.interface' +import { IGetResponse } from '../interfaces/get.interface' +import { ISendResponse } from '../interfaces/send.interface' +import { IUpdateResponse } from '../interfaces/update.interface' import createResponse, { createRequestBody } from './create-response' import deleteResponse from './delete-response' import findResponse from './find-response' import getResponse from './get-response' import postAccountsResponse from './post-accounts-response' +import postStockResponse from './post-stock-response' +import postStockToDepositResponse from './post-stock-to-deposit-response' import reverseAccountsResponse from './reverse-accounts-response' +import reverseStockResponse from './reverse-stock-response' import sendResponse from './send-response' import updateResponse, { updateRequestBody } from './update-response' @@ -41,6 +50,9 @@ describe('NF-es entity', () => { params: { idsNotas } }) expect(response).toBe(deleteResponse) + + const typingResponseTest: IDeleteResponse = deleteResponse + expect(typingResponseTest).toBe(deleteResponse) }) it('should get successfully', async () => { @@ -62,6 +74,9 @@ describe('NF-es entity', () => { } }) expect(response).toBe(getResponse) + + const typingResponseTest: IGetResponse = getResponse + expect(typingResponseTest).toBe(getResponse) }) it('should find successfully', async () => { @@ -76,6 +91,9 @@ describe('NF-es entity', () => { id: String(idNotaFiscal) }) expect(response).toBe(findResponse) + + const typingResponseTest: IFindResponse = findResponse + expect(typingResponseTest).toBe(findResponse) }) it('should create successfully', async () => { @@ -89,6 +107,9 @@ describe('NF-es entity', () => { body: createRequestBody }) expect(response).toBe(createResponse) + + const typingResponseTest: ICreateResponse = createResponse + expect(typingResponseTest).toBe(createResponse) }) it('should send successfully', async () => { @@ -103,6 +124,9 @@ describe('NF-es entity', () => { body: {} }) expect(response).toBe(sendResponse) + + const typingResponseTest: ISendResponse = sendResponse + expect(typingResponseTest).toBe(sendResponse) }) it('should post accounts successfully', async () => { @@ -117,6 +141,9 @@ describe('NF-es entity', () => { body: {} }) expect(response).toBe(postAccountsResponse) + + const typingResponseTest: null = postAccountsResponse + expect(typingResponseTest).toBe(postAccountsResponse) }) it('should reverse accounts successfully', async () => { @@ -131,6 +158,64 @@ describe('NF-es entity', () => { body: {} }) expect(response).toBe(reverseAccountsResponse) + + const typingResponseTest: null = reverseAccountsResponse + expect(typingResponseTest).toBe(reverseAccountsResponse) + }) + + it('should post stock successfully', async () => { + const spy = jest.spyOn(repository, 'store') + const idNotaFiscal = chance.natural() + repository.setResponse(postStockResponse) + + const response = await entity.postStock({ idNotaFiscal }) + + expect(spy).toHaveBeenCalledWith({ + endpoint: `nfe/${idNotaFiscal}/lancar-estoque`, + body: {} + }) + expect(response).toBe(postStockResponse) + + const typingResponseTest: null = postStockResponse + expect(typingResponseTest).toBe(postStockResponse) + }) + + it('should post stock to deposit successfully', async () => { + const spy = jest.spyOn(repository, 'store') + const idNotaFiscal = chance.natural() + const idDeposito = chance.natural() + repository.setResponse(postStockToDepositResponse) + + const response = await entity.postStockToDeposit({ + idNotaFiscal, + idDeposito + }) + + expect(spy).toHaveBeenCalledWith({ + endpoint: `nfe/${idNotaFiscal}/lancar-estoque/${idDeposito}`, + body: {} + }) + expect(response).toBe(postStockToDepositResponse) + + const typingResponseTest: null = postStockToDepositResponse + expect(typingResponseTest).toBe(postStockToDepositResponse) + }) + + it('should reverse stock successfully', async () => { + const spy = jest.spyOn(repository, 'store') + const idNotaFiscal = chance.natural() + repository.setResponse(reverseStockResponse) + + const response = await entity.reverseStock({ idNotaFiscal }) + + expect(spy).toHaveBeenCalledWith({ + endpoint: `nfe/${idNotaFiscal}/estornar-estoque`, + body: {} + }) + expect(response).toBe(reverseStockResponse) + + const typingResponseTest: null = reverseStockResponse + expect(typingResponseTest).toBe(reverseStockResponse) }) it('should update successfully', async () => { @@ -149,5 +234,8 @@ describe('NF-es entity', () => { body: updateRequestBody }) expect(response).toBe(updateResponse) + + const typingResponseTest: IUpdateResponse = updateResponse + expect(typingResponseTest).toBe(updateResponse) }) }) diff --git a/src/entities/nfes/__tests__/post-stock-response.ts b/src/entities/nfes/__tests__/post-stock-response.ts new file mode 100644 index 0000000..7b85954 --- /dev/null +++ b/src/entities/nfes/__tests__/post-stock-response.ts @@ -0,0 +1 @@ +export default null diff --git a/src/entities/nfes/__tests__/post-stock-to-deposit-response.ts b/src/entities/nfes/__tests__/post-stock-to-deposit-response.ts new file mode 100644 index 0000000..7b85954 --- /dev/null +++ b/src/entities/nfes/__tests__/post-stock-to-deposit-response.ts @@ -0,0 +1 @@ +export default null diff --git a/src/entities/nfes/__tests__/reverse-stock-response.ts b/src/entities/nfes/__tests__/reverse-stock-response.ts new file mode 100644 index 0000000..7b85954 --- /dev/null +++ b/src/entities/nfes/__tests__/reverse-stock-response.ts @@ -0,0 +1 @@ +export default null diff --git a/src/entities/nfes/index.ts b/src/entities/nfes/index.ts index c2ced83..4840e5c 100644 --- a/src/entities/nfes/index.ts +++ b/src/entities/nfes/index.ts @@ -4,7 +4,10 @@ import { IDeleteParams, IDeleteResponse } from './interfaces/delete.interface' import { IFindParams, IFindResponse } from './interfaces/find.interface' import { IGetParams, IGetResponse } from './interfaces/get.interface' import { IPostAccountsParams } from './interfaces/post-accounts.interface' +import { IPostStockToDepositParams } from './interfaces/post-stock-to-deposit.interface' +import { IPostStockParams } from './interfaces/post-stock.interface' import { IReverseAccountsParams } from './interfaces/reverse-accounts.interface' +import { IReverseStockParams } from './interfaces/reverse-stock.interface' import { ISendParams, ISendResponse } from './interfaces/send.interface' import { IUpdateBody, @@ -121,7 +124,7 @@ export class Nfes extends Entity { /** * Lança as contas de uma nota fiscal. * - * @param {IPostAccountsParams} params O conteúdo para a criação. + * @param {IPostAccountsParams} params O conteúdo para o lançamento. * * @returns {Promise} * @throws {BlingApiException|BlingInternalException} @@ -138,7 +141,7 @@ export class Nfes extends Entity { /** * Estorna as contas de uma nota fiscal. * - * @param {IReverseAccountsParams} params O conteúdo para a criação. + * @param {IReverseAccountsParams} params O conteúdo para o estorno. * * @returns {Promise} * @throws {BlingApiException|BlingInternalException} @@ -152,6 +155,59 @@ export class Nfes extends Entity { }) } + /** + * Lança o estoque de uma nota fiscal no depósito padrão. + * + * @param {IPostStockParams} params O conteúdo para o lançamento. + * + * @returns {Promise} + * @throws {BlingApiException|BlingInternalException} + * + * @see https://developer.bling.com.br/referencia#/Notas%20Fiscais%20Eletr%C3%B4nicas/post_nfe__idNotaFiscal__lancar_estoque + */ + public async postStock(params: IPostStockParams): Promise { + return await this.repository.store({ + endpoint: `nfe/${params.idNotaFiscal}/lancar-estoque`, + body: {} + }) + } + + /** + * Lança o estoque de uma nota fiscal especificando o depósito. + * + * @param {IPostStockToDepositParams} params O conteúdo para o lançamento. + * + * @returns {Promise} + * @throws {BlingApiException|BlingInternalException} + * + * @see https://developer.bling.com.br/referencia#/Notas%20Fiscais%20Eletr%C3%B4nicas/post_nfe__idNotaFiscal__lancar_estoque__idDeposito_ + */ + public async postStockToDeposit( + params: IPostStockToDepositParams + ): Promise { + return await this.repository.store({ + endpoint: `nfe/${params.idNotaFiscal}/lancar-estoque/${params.idDeposito}`, + body: {} + }) + } + + /** + * Estorna o estoque de uma nota fiscal. + * + * @param {IReverseStockParams} params O conteúdo para o estorno. + * + * @returns {Promise} + * @throws {BlingApiException|BlingInternalException} + * + * @see https://developer.bling.com.br/referencia#/Notas%20Fiscais%20Eletr%C3%B4nicas/post_nfe__idNotaFiscal__estornar_estoque + */ + public async reverseStock(params: IReverseStockParams): Promise { + return await this.repository.store({ + endpoint: `nfe/${params.idNotaFiscal}/estornar-estoque`, + body: {} + }) + } + /** * Altera uma nota fiscal. * diff --git a/src/entities/nfes/interfaces/post-stock-to-deposit.interface.ts b/src/entities/nfes/interfaces/post-stock-to-deposit.interface.ts new file mode 100644 index 0000000..cb94031 --- /dev/null +++ b/src/entities/nfes/interfaces/post-stock-to-deposit.interface.ts @@ -0,0 +1,10 @@ +export interface IPostStockToDepositParams { + /** + * ID da nota fiscal + */ + idNotaFiscal: number + /** + * ID do depósito + */ + idDeposito: number +} diff --git a/src/entities/nfes/interfaces/post-stock.interface.ts b/src/entities/nfes/interfaces/post-stock.interface.ts new file mode 100644 index 0000000..57ba84e --- /dev/null +++ b/src/entities/nfes/interfaces/post-stock.interface.ts @@ -0,0 +1,6 @@ +export interface IPostStockParams { + /** + * ID da nota fiscal + */ + idNotaFiscal: number +} diff --git a/src/entities/nfes/interfaces/reverse-stock.interface.ts b/src/entities/nfes/interfaces/reverse-stock.interface.ts new file mode 100644 index 0000000..f21850f --- /dev/null +++ b/src/entities/nfes/interfaces/reverse-stock.interface.ts @@ -0,0 +1,6 @@ +export interface IReverseStockParams { + /** + * ID da nota fiscal + */ + idNotaFiscal: number +}