From b1aae3304b922f0dccc63b477f6aec13854270f1 Mon Sep 17 00:00:00 2001 From: eduardoestevao-appsoluti Date: Wed, 10 Sep 2025 16:56:11 -0300 Subject: [PATCH 1/2] Add endpoint to retrieve similar products and implement corresponding service method --- src/sales/sales/sales.controller.ts | 14 +++++++ src/sales/sales/sales.service.ts | 60 +++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/sales/sales/sales.controller.ts b/src/sales/sales/sales.controller.ts index 0e01487..a67bf88 100644 --- a/src/sales/sales/sales.controller.ts +++ b/src/sales/sales/sales.controller.ts @@ -176,6 +176,20 @@ export class SalesController { } } + + @Get('product/simil/:id') + @ApiOperation({ summary: 'Get products similar' }) + @ApiParam({ name: 'id', description: 'Product ID' }) + async getProductSimil(@Headers() headers, @Param('id') id: number) { + try { + const { store } = this.extractPaginationParams(headers); + return await this.salesService.GetProductsSimil(store, id); + } catch (e) { + throw new HttpException(e.message, HttpStatus.BAD_REQUEST); + } + } + + @Get('stock/:storeid/:id') @ApiOperation({ summary: 'Get product stock information' }) @ApiParam({ name: 'storeid', description: 'Store ID' }) diff --git a/src/sales/sales/sales.service.ts b/src/sales/sales/sales.service.ts index a9ffd36..c0ac921 100644 --- a/src/sales/sales/sales.service.ts +++ b/src/sales/sales/sales.service.ts @@ -851,6 +851,66 @@ export class SalesService { } } + async GetProductsSimil(store: string, id: number) { + const connectionDb = new Connection(connectionOptions); + await connectionDb.connect(); + const queryRunner = connectionDb.createQueryRunner(); + await queryRunner.connect(); + try { + const sql = `SELECT esvlistaprodutos.CODPROD as "idProduct" + ,esvlistaprodutos.SEQ as "seq" + ,esvlistaprodutos.DESCRICAO as "smallDescription" + ,esvlistaprodutos.NOMEECOMMERCE as "title" + ,esvlistaprodutos.CODFAB as "idProvider" + ,esvlistaprodutos.CODAUXILIAR as "ean" + ,esvlistaprodutos.TIPOPRODUTO as "productType" + ,esvlistaprodutos.DADOSTECNICOS as "technicalData" + ,esvlistaprodutos.INFORMACOESTECNICAS as "description" + ,esvlistaprodutos.URLIMAGEM as "urlImage" + ,esvlistaprodutos.NOMEMARCA as "brand" + ,esvlistaprodutos.NOMEDEPARTAMENTO as "department" + ,esvlistaprodutos.NOMESECAO as "section" + ,esvlistaprodutos.NOMECATEGORIA as "category" + ,esvlistaprodutos.NOMEFORNECEDOR as "supplier" + ,esvlistaprodutos.CODIGOFILIAL as "store" + ,esvlistaprodutos.CLASSEVENDA as "saleAbc" + ,esvlistaprodutos.CLASSEESTOQUE as "stockAbc" + ,esvlistaprodutos.FORALINHA as "outLine" + ,esvlistaprodutos.PRECOVENDA as "listPrice" + ,esvlistaprodutos.PRECOPROMOCIONAL as "salePrice" + ,esvlistaprodutos.PRECOPROMOCIONAL as "salePromotion" + ,esvlistaprodutos.PERCENTUALDESCONTO as"offPercent" + ,esvlistaprodutos.QTESTOQUE_DISPONIVEL as "stock" + ,esvlistaprodutos.QTCAIXAS as "boxStock" + ,esvlistaprodutos.ESTOQUE_DISP_LOJA as "store_stock" + ,esvlistaprodutos.ESTOQUE_DISP_CAIXA_LOJA as "store_boxStock" + ,esvlistaprodutos.ESTOQUE_DISP_LOJA as "store_stock" + ,esvlistaprodutos.ESTOQUE_DISP_CAIXA_LOJA as "store_boxStock" + ,esvlistaprodutos.MULTIPLO as "mutiple" + ,esvlistaprodutos.UNIDADE as "unity" + ,esvlistaprodutos.URLDEPARTAMENTO as "urlDepartment" + ,esvlistaprodutos.URLSECAO as "urlSection" + ,esvlistaprodutos.PRODUTO_COM_REDUCAO_PRECO as "downPrice" + ,esvlistaprodutos.PRODUTO_EM_CAMPANHA as "compaing" + ,esvlistaprodutos.BASETINTOMETRICO as "base" + ,esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock" + FROM ESVLISTAPRODUTOS, PCPRODSIMIL + WHERE ESVLISTAPRODUTOS.CODPROD = PCPRODSIMIL.CODSIMIL + AND PCPRODSIMIL.CODPROD = ${id} + AND ESVLISTAPRODUTOS.CODFILIAL = '${store}' + ORDER BY REPLACE(esvlistaprodutos.DESCRICAO,'#', '')`; + let products: SalesProduct[] = await queryRunner.query(sql); + + products = this.createListImages(products); + return products; + } catch (error) { + throw error; + } finally { + await queryRunner.release(); + await connectionDb.close(); + } + } + async GetStocks(storeId: string, id: number) { const connectionDb = new Connection(connectionOptions); await connectionDb.connect(); From f32a3fd40f490bf24bf2877ab3b463eac8437c7b Mon Sep 17 00:00:00 2001 From: eduardoestevao-appsoluti Date: Wed, 17 Sep 2025 09:48:07 -0300 Subject: [PATCH 2/2] Add 'similar' product selection to sales queries in SalesService --- src/sales/sales/sales.service.ts | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/sales/sales/sales.service.ts b/src/sales/sales/sales.service.ts index c0ac921..5d410e0 100644 --- a/src/sales/sales/sales.service.ts +++ b/src/sales/sales/sales.service.ts @@ -77,7 +77,8 @@ export class SalesService { esvlistaprodutos.LETRABASETINTOMETRICO as "letter", esvlistaprodutos.LINHATINTOMETRICO as "line", esvlistaprodutos.LITRAGEM as "can", - esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock" + esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock", + esvlistaprodutos.TEM_PRODUTO_SIMILAR as "similar" FROM ESVLISTAPRODUTOS WHERE 1 = 1`; @@ -127,6 +128,7 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line") .addSelect("\"esvlistaprodutos\".LITRAGEM", "can") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("UPPER(\"esvlistaprodutos\".CODFAB) LIKE '%'||REPLACE(:description, '@', '%')||'%'", { description }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')", @@ -184,6 +186,7 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line") .addSelect("\"esvlistaprodutos\".LITRAGEM", "can") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("UPPER(\"esvlistaprodutos\".descricao) LIKE '%'||REPLACE(:description, '@', '%')||'%'", { description }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')", @@ -260,6 +263,7 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line") .addSelect("\"esvlistaprodutos\".LITRAGEM", "can") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("esvlistaprodutos.brand in (" + xbrands + ")") .andWhere("\"esvlistaprodutos\".URLCATEGORIA LIKE :urlCategoria||'%'", { urlCategoria: filter.urlCategory }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) @@ -324,6 +328,7 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line") .addSelect("\"esvlistaprodutos\".LITRAGEM", "can") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')", { produtoComReducaoPreco: (filter.markdown.toString() == 'true') ? 'S' : 'N' }) @@ -562,6 +567,7 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("esvlistaprodutos.idProduct = :id", { id: numbers }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .limit(pageSize) @@ -608,7 +614,8 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".PRODUTO_COM_REDUCAO_PRECO", "downPrice") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") - .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("esvlistaprodutos.CODAUXILIAR = :id", { id: numbers }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .limit(pageSize) @@ -657,7 +664,8 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".PRODUTO_COM_REDUCAO_PRECO", "downPrice") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") - .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("UPPER(esvlistaprodutos.CODFAB) like REPLACE(:description, '@', '%')", { description }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .limit(pageSize) @@ -703,7 +711,8 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".PRODUTO_COM_REDUCAO_PRECO", "downPrice") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") - .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("UPPER(esvlistaprodutos.DESCRICAO) like REPLACE(:description, '@', '%')", { description }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .limit(pageSize) @@ -772,7 +781,8 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".PRODUTO_COM_REDUCAO_PRECO", "downPrice") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") - .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") + .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .where("esvlistaprodutos.idProduct = :id", { id: id }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial", { codfilial: store }) .orderBy("REPLACE(\"esvlistaprodutos\".DESCRICAO,'#', '')", "ASC") @@ -834,6 +844,7 @@ export class SalesService { ,esvlistaprodutos.PRODUTO_EM_CAMPANHA as "compaing" ,esvlistaprodutos.BASETINTOMETRICO as "base" ,esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock" + ,esvlistaprodutos.TEM_PRODUTO_SIMILAR as "similar" FROM ESVLISTAPRODUTOS, ESTCOMPREJUNTO WHERE ESVLISTAPRODUTOS.CODPROD = ESTCOMPREJUNTO.CODPROD AND ESTCOMPREJUNTO.CODPRODVENDA = ${id} @@ -894,6 +905,7 @@ export class SalesService { ,esvlistaprodutos.PRODUTO_EM_CAMPANHA as "compaing" ,esvlistaprodutos.BASETINTOMETRICO as "base" ,esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock" + ,esvlistaprodutos.TEM_PRODUTO_SIMILAR as "similar" FROM ESVLISTAPRODUTOS, PCPRODSIMIL WHERE ESVLISTAPRODUTOS.CODPROD = PCPRODSIMIL.CODSIMIL AND PCPRODSIMIL.CODPROD = ${id} @@ -1325,6 +1337,7 @@ export class SalesService { ' ,esvlistaprodutos.LINHATINTOMETRICO "line" ' + ' ,esvlistaprodutos.LITRAGEM "can" ' + ' ,esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL "full_stock" ' + + ' ,esvlistaprodutos.TEM_PRODUTO_SIMILAR "similar" ' + ' FROM esvlistaprodutos ' + ' WHERE 1 = 1';