diff --git a/package.json b/package.json index aacb306..80e6305 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "license": "JURUNENSE HOME CENTER", "scripts": { "prebuild": "rimraf dist", - "build": "nest build", + "build": "nest build && node scripts/rewrite-dist-src-aliases.js", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev": "nest start --watch", diff --git a/scripts/rewrite-dist-src-aliases.js b/scripts/rewrite-dist-src-aliases.js new file mode 100644 index 0000000..9354509 --- /dev/null +++ b/scripts/rewrite-dist-src-aliases.js @@ -0,0 +1,40 @@ +const fs = require('fs'); +const path = require('path'); + +const distDir = path.resolve(__dirname, '..', 'dist'); + +function walk(dir) { + if (!fs.existsSync(dir)) { + return []; + } + + return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + return walk(fullPath); + } + return fullPath.endsWith('.js') ? [fullPath] : []; + }); +} + +function toRequirePath(fromFile, srcImport) { + const target = path.join(distDir, srcImport.replace(/^src[\\/]/, '')); + let relative = path.relative(path.dirname(fromFile), target).replace(/\\/g, '/'); + + if (!relative.startsWith('.')) { + relative = `./${relative}`; + } + + return relative; +} + +for (const file of walk(distDir)) { + const source = fs.readFileSync(file, 'utf8'); + const rewritten = source.replace(/require\((['"])src\/([^'"]+)\1\)/g, (_match, quote, importPath) => { + return `require(${quote}${toRequirePath(file, `src/${importPath}`)}${quote})`; + }); + + if (rewritten !== source) { + fs.writeFileSync(file, rewritten); + } +} diff --git a/src/main.ts b/src/main.ts index e448676..bf51b32 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,3 +1,4 @@ +import './polyfills/node-util'; import { NestFactory } from '@nestjs/core'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; const compression = require('compression'); diff --git a/src/polyfills/node-util.ts b/src/polyfills/node-util.ts new file mode 100644 index 0000000..0adeb0b --- /dev/null +++ b/src/polyfills/node-util.ts @@ -0,0 +1,9 @@ +const util = require('util'); + +if (typeof util.isNullOrUndefined !== 'function') { + util.isNullOrUndefined = (value: any) => value === null || value === undefined; +} + +if (typeof util.isObject !== 'function') { + util.isObject = (value: any) => value !== null && typeof value === 'object'; +} diff --git a/src/sales/order/order.service.ts b/src/sales/order/order.service.ts index 554b5b6..7b77b85 100644 --- a/src/sales/order/order.service.ts +++ b/src/sales/order/order.service.ts @@ -28,11 +28,38 @@ export class OrderService { ) { } async create(cart: Cart) { - const shopping = await this.findShopping(cart.id); - if (shopping == null) - throw new HttpException("Carrinho de compras não localizado.", HttpStatus.NOT_FOUND); - const order = await this.createOrder(cart); - return order; + const lockKey = `lock:order:create:${cart.id}`; + const lockValue = `${Date.now()}:${Math.random()}`; + const lockTimeout = 120; + let acquiredLock: string | null = null; + + try { + acquiredLock = await this.redisClient.set(lockKey, lockValue, 'NX', 'EX', lockTimeout); + } catch (err) { + console.error('Erro ao adquirir lock no Redis (createOrder):', err?.message || err); + acquiredLock = 'OK'; + } + + if (acquiredLock !== 'OK') { + throw new HttpException('Venda em processamento para este carrinho. Aguarde a finalizacao e tente novamente.', HttpStatus.CONFLICT); + } + + try { + const shopping = await this.findShopping(cart.id); + if (shopping == null) + throw new HttpException("Carrinho de compras não localizado.", HttpStatus.NOT_FOUND); + const order = await this.createOrder(cart); + return order; + } finally { + try { + const currentLockValue = await this.redisClient.get(lockKey); + if (currentLockValue === lockValue) { + await this.redisClient.del(lockKey); + } + } catch (lockErr) { + console.error('Erro ao liberar lock no Redis (createOrder):', lockErr?.message || lockErr); + } + } } async deleteOrdersDelivery(orderId: number, userId: number) { @@ -57,7 +84,7 @@ export class OrderService { } } catch (erro) { if (queryRunner.isTransactionActive) { - await queryRunner.commitTransaction(); + await queryRunner.rollbackTransaction(); } throw erro; } finally { @@ -125,7 +152,7 @@ export class OrderService { } if (queryRunner.isTransactionActive) { - queryRunner.commitTransaction(); + await queryRunner.commitTransaction(); } await queryRunner.startTransaction(); @@ -320,7 +347,7 @@ export class OrderService { }; } catch (err) { console.log(err); - this.deletePreOrder(idPreOrder); + await this.deletePreOrder(idPreOrder); throw err; // since we have errors let's rollback changes we made } finally { @@ -743,16 +770,15 @@ export class OrderService { const queryRunner = connection.createQueryRunner(); await queryRunner.connect(); console.log('Consultando usuario ' + idSeller); - let sql = 'SELECT NVL(PROXNUMPEDWEB,0) as "proxnumpedweb" FROM PCUSUARI ' + - ' WHERE PCUSUARI.CODUSUR = :1 FOR UPDATE'; - const seller = await queryRunner.query(sql, [idSeller]); - - const idOrder = seller[0].proxnumpedweb; - console.log(idOrder); - await queryRunner.startTransaction(); try { + let sql = 'SELECT NVL(PROXNUMPEDWEB,0) as "proxnumpedweb" FROM PCUSUARI ' + + ' WHERE PCUSUARI.CODUSUR = :1 FOR UPDATE'; + const seller = await queryRunner.query(sql, [idSeller]); + + const idOrder = seller[0].proxnumpedweb; + console.log(idOrder); sql = 'UPDATE PCUSUARI SET PROXNUMPEDWEB = NVL(PROXNUMPEDWEB,0) + 1 ' + ' WHERE PCUSUARI.CODUSUR = :1'; diff --git a/src/sales/sales/sales.service.ts b/src/sales/sales/sales.service.ts index 735f7f3..c9721ee 100644 --- a/src/sales/sales/sales.service.ts +++ b/src/sales/sales/sales.service.ts @@ -69,7 +69,7 @@ export class SalesService { pageNumber = 1; const offSet = (pageNumber - 1) * pageSize; - if (filter && filter.text.length > 0) { + if (filter && filter.text && filter.text.length > 0) { const description = filter.text.toUpperCase(); console.log('consultando por texto: ' + description); @@ -116,7 +116,7 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .addSelect("\"esvlistaprodutos\".TIPO_CAMPANHA", "type_campaing") - .where("(UPPER(\"esvlistaprodutos\".CODFAB) LIKE '%'||REPLACE(:description, '@', '%')||'%' OR UPPER(\"esvlistaprodutos\".descricao) LIKE '%'||REPLACE(:description, '@', '%')||'%')", { description }) + .where("(\"esvlistaprodutos\".CODFAB LIKE REPLACE(:description, '@', '%')||'%' OR \"esvlistaprodutos\".descricao LIKE REPLACE(:description, '@', '%')||'%' OR \"esvlistaprodutos\".NOMEECOMMERCE LIKE REPLACE(:description, '@', '%')||'%')", { description }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')", { produtoComReducaoPreco: (filter.markdown) ? 'S' : 'N' }) @@ -450,8 +450,18 @@ export class SalesService { } async searchProduct(store: string, search: string, pageSize: number, pageNumber: number) { - const connectionDb = new Connection(connectionOptions); - await connectionDb.connect(); + const cacheKey = `searchProduct:${store}:${pageSize}:${pageNumber}:${search}`; + try { + const cachedProducts = await this.redisClient.get(cacheKey); + if (cachedProducts) { + console.log('searchProduct - Retornando produtos do cache'); + return JSON.parse(cachedProducts); + } + } catch (err) { + console.error('Erro ao acessar o Redis no searchProduct:', err?.message || err); + } + + const connectionDb = getConnection(); const queryRunner = connectionDb.createQueryRunner(); await queryRunner.connect(); try { @@ -509,7 +519,7 @@ export class SalesService { .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .limit(pageSize) .offset(offSet) - .orderBy("REPLACE(\"esvlistaprodutos\".DESCRICAO,'#', '')", "ASC") + .orderBy("\"esvlistaprodutos\".DESCRICAO", "ASC") .getRawMany(); if (products.length === 0) { @@ -558,12 +568,12 @@ export class SalesService { .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .limit(pageSize) .offset(offSet) - .orderBy("REPLACE(\"esvlistaprodutos\".DESCRICAO,'#', '')", "ASC") + .orderBy("\"esvlistaprodutos\".DESCRICAO", "ASC") .getRawMany(); } } else { - const description = '%' + search.toUpperCase() + '%'; + const description = search.toUpperCase().replace('@', '%') + '%'; console.log('consultando por codigo de fabrica'); products = await queryRunner.manager .getRepository(SalesProduct) @@ -605,11 +615,11 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .addSelect("\"esvlistaprodutos\".TIPO_CAMPANHA", "type_campaing") - .where("UPPER(esvlistaprodutos.CODFAB) like REPLACE(:description, '@', '%')", { description }) + .where("esvlistaprodutos.CODFAB like :description", { description }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .limit(pageSize) .offset(offSet) - .orderBy("REPLACE(\"esvlistaprodutos\".DESCRICAO,'#', '')", "ASC") + .orderBy("\"esvlistaprodutos\".DESCRICAO", "ASC") .getRawMany(); if (products.length == 0) { @@ -653,11 +663,11 @@ export class SalesService { .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar") .addSelect("\"esvlistaprodutos\".TIPO_CAMPANHA", "type_campaing") - .where("UPPER(esvlistaprodutos.DESCRICAO) like REPLACE(:description, '@', '%')", { description }) + .where("(esvlistaprodutos.DESCRICAO like :description OR esvlistaprodutos.NOMEECOMMERCE like :description)", { description }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .limit(pageSize) .offset(offSet) - .orderBy("REPLACE(\"esvlistaprodutos\".DESCRICAO,'#', '')", "ASC") + .orderBy("\"esvlistaprodutos\".DESCRICAO", "ASC") .getRawMany(); } @@ -665,6 +675,7 @@ export class SalesService { products = this.createListImages(products); console.log(products.length); + try { await this.redisClient.set(cacheKey, JSON.stringify(products), 'EX', 900); } catch (cacheErr) { console.error('Erro ao salvar cache searchProduct:', cacheErr?.message || cacheErr); } return products; } catch (error) { @@ -672,7 +683,7 @@ export class SalesService { throw error; } finally { await queryRunner.release(); - await connectionDb.close(); + // Nao fecha a conexao global; ela e reutilizada pelo pool do TypeORM. } } @@ -1237,12 +1248,42 @@ export class SalesService { async searchProduct2(store: string, pageSize: number, pageNumber: number, filter: FilterProduct) { console.log('searchProduct2'); - const cacheKey = `searchProduct2:${store}:${pageSize}:${pageNumber}:${JSON.stringify(filter)}`; + filter = filter || new FilterProduct(); + if (pageSize == 0) + pageSize = 500; + if (pageNumber == 0) + pageNumber = 1; - const cachedProducts = await this.redisClient.get(cacheKey); - if (cachedProducts) { - console.log('Retornando produtos do cache'); - return JSON.parse(cachedProducts); + const toBoolean = (value: any) => value === true || value === 'true' || value === 'S'; + const escapeSqlText = (value: string) => value.replace(/'/g, "''"); + const orderByColumns = { + DESCRICAO: 'DESCRICAO', + PRECOVENDA: 'PRECOVENDA', + PRECOPROMOCIONAL: 'PRECOPROMOCIONAL', + PERCENTUALDESCONTO: 'PERCENTUALDESCONTO', + NOMEMARCA: 'NOMEMARCA', + }; + + const normalizedFilter = { + ...filter, + text: filter.text ? filter.text.trim() : null, + markdown: toBoolean(filter.markdown), + offers: toBoolean(filter.offers), + oportunity: toBoolean(filter.oportunity), + promotion: toBoolean(filter.promotion), + onlyWithStock: toBoolean(filter.onlyWithStock), + brands: filter.brands || [], + }; + const cacheKey = `searchProduct2:${store}:${pageSize}:${pageNumber}:${JSON.stringify(normalizedFilter)}`; + + try { + const cachedProducts = await this.redisClient.get(cacheKey); + if (cachedProducts) { + console.log('Retornando produtos do cache'); + return JSON.parse(cachedProducts); + } + } catch (err) { + console.error('Erro ao acessar o Redis no searchProduct2:', err?.message || err); } const sql = 'SELECT esvlistaprodutos.CODPROD "idProduct" ' + @@ -1290,59 +1331,73 @@ export class SalesService { ' WHERE 1 = 1 '; let where = ""; - if (filter.text != null) { - where += ` AND ( ESF_REMOVE_ACENTUACAO(UPPER(esvlistaprodutos.descricao)) LIKE ` + - ` ESF_REMOVE_ACENTUACAO(REPLACE('${filter.text}', '@', '%'))||'%' ` + - ` OR ESF_REMOVE_ACENTUACAO(UPPER(esvlistaprodutos.nomeecommerce)) LIKE ` + - ` ESF_REMOVE_ACENTUACAO(REPLACE('${filter.text}', '@', '%'))||'%' ` + - ` OR esvlistaprodutos.codprod = REGEXP_REPLACE('${filter.text}', '[^0-9]', '') ` + - ` OR esvlistaprodutos.codauxiliar = REGEXP_REPLACE('${filter.text}', '[^0-9]', '') ` + - ` OR esvlistaprodutos.nomemarca = REPLACE('${filter.text}', '@', '%') ` + - ` OR esvlistaprodutos.codfab LIKE '${filter.text}%' )`; + if (normalizedFilter.text != null && normalizedFilter.text.length > 0) { + const textSearch = escapeSqlText(normalizedFilter.text.toUpperCase()).replace('@', '%'); + const numbers = normalizedFilter.text.replace(/[^0-9]/g, ''); + if (numbers.length > 0 && numbers === normalizedFilter.text) { + where += ` AND ( esvlistaprodutos.codprod = ${numbers} ` + + ` OR esvlistaprodutos.codauxiliar = '${numbers}' )`; + } else { + where += ` AND ( esvlistaprodutos.descricao LIKE '${textSearch}%' ` + + ` OR esvlistaprodutos.nomeecommerce LIKE '${textSearch}%' ` + + ` OR esvlistaprodutos.nomemarca = '${textSearch}' ` + + ` OR esvlistaprodutos.codfab LIKE '${textSearch}%' `; + if (numbers.length > 0) { + where += ` OR esvlistaprodutos.codprod = ${numbers} ` + + ` OR esvlistaprodutos.codauxiliar = '${numbers}' `; + } + where += ` )`; + } } - if (filter.urlCategory != null) { - where += ` AND esvlistaprodutos.urlcategoria like '${filter.urlCategory}%'`; + if (filter.urlCategory != null && filter.urlCategory.length > 0) { + where += ` AND esvlistaprodutos.urlcategoria like '${escapeSqlText(filter.urlCategory)}%'`; + } + if (store !== '99') { + where += ` AND esvlistaprodutos.codfilial = '${escapeSqlText(store)}' `; + } + if (normalizedFilter.markdown) { + where += ` AND esvlistaprodutos.produto_com_reducao_preco = 'S' `; + } + if (normalizedFilter.offers) { + where += ` AND esvlistaprodutos.produto_em_campanha = 'D' `; + } + if (normalizedFilter.oportunity) { + where += ` AND esvlistaprodutos.produto_oportunidade = 'O' `; + } + if (normalizedFilter.promotion) { + where += ` AND esvlistaprodutos.produto_em_promocao = 'S' `; } - where += ` AND (esvlistaprodutos.codfilial = '${store}' OR '${store}' = '99') `; - where += ` AND (esvlistaprodutos.produto_com_reducao_preco = '${(filter.markdown ? 'S' : 'N')}' OR '${(filter.markdown ? 'S' : 'N')}' = 'N') `; - where += ` AND (esvlistaprodutos.produto_em_campanha = '${(filter.offers ? 'D' : 'N')}' OR '${(filter.offers ? 'S' : 'N')}' = 'N') `; - where += ` AND (esvlistaprodutos.produto_em_campanha = '${(filter.oportunity ? 'O' : 'N')}' OR '${(filter.oportunity ? 'O' : 'N')}' = 'N') `; - where += ` AND (esvlistaprodutos.produto_em_promocao = '${(filter.promotion ? 'S' : 'N')}' OR '${(filter.promotion ? 'S' : 'N')}' = 'N') `; - if (filter.onlyWithStock) { + if (normalizedFilter.onlyWithStock) { if (filter.storeStock == '' || filter.storeStock == null) { where += ` AND EXISTS( SELECT P.CODPROD FROM ESVLISTAPRODUTOS P ` + ` WHERE P.CODPROD = ESVLISTAPRODUTOS.CODPROD ` + ` AND P.QTESTOQUE_DISPONIVEL > 0 ) `; } else { where += ` AND EXISTS( SELECT P.CODPROD FROM ESVLISTAPRODUTOS P ` + - ` WHERE P.CODPROD = ESVLISTAPRODUTOS.CODPROD AND P.CODFILIAL = '${filter.storeStock}' ` + + ` WHERE P.CODPROD = ESVLISTAPRODUTOS.CODPROD AND P.CODFILIAL = '${escapeSqlText(filter.storeStock)}' ` + ` AND P.ESTOQUE_DISP_LOJA > 0 ) `; } } - if (filter.percentOffMin > 0) { - where += ` AND esvlistaprodutos.PERCENTUALDESCONTO >= ${filter.percentOffMin}`; + if (Number(filter.percentOffMin) > 0) { + where += ` AND esvlistaprodutos.PERCENTUALDESCONTO >= ${Number(filter.percentOffMin)}`; } - if (filter.percentOffMax > 0) { - where += ` AND esvlistaprodutos.PERCENTUALDESCONTO <= ${filter.percentOffMax}`; + if (Number(filter.percentOffMax) > 0) { + where += ` AND esvlistaprodutos.PERCENTUALDESCONTO <= ${Number(filter.percentOffMax)}`; } - let xbrands = ''; - if (filter && filter.brands && filter.brands.length > 0) { - const brands = filter.brands; - brands.forEach(b => { - if (xbrands.length > 0) { - xbrands += ', ' + '\'' + b + '\''; - } else { - xbrands = '\'' + b + '\''; - } - }); + if (normalizedFilter.brands.length > 0) { + const xbrands = normalizedFilter.brands + .filter(b => b != null && b.length > 0) + .map(b => `'${escapeSqlText(b)}'`) + .join(', '); where += ` AND esvlistaprodutos.nomemarca in ( ${xbrands} )`; } - const orderBy = `ORDER BY esvlistaprodutos.${(filter.orderBy == null) ? 'DESCRICAO' : filter.orderBy}`; + const orderByColumn = orderByColumns[filter.orderBy] || 'DESCRICAO'; + const orderBy = `ORDER BY esvlistaprodutos.${orderByColumn}`; const skipReg = ((pageNumber - 1) * pageSize); const pagination = ` OFFSET ${skipReg} ROWS FETCH NEXT ${pageSize} ROWS ONLY`; @@ -1352,11 +1407,14 @@ export class SalesService { await queryRunner.connect(); try { + console.log("hora de buscar produtos: " + new Date().toISOString()) let products = await queryRunner.manager.query(sql + where + orderBy + pagination) as SalesProduct[]; + console.log("hora final de buscar produtos: " + new Date().toISOString()) products = this.createListImages(products); + console.log("hora de buscar imagens: " + new Date().toISOString()) console.log("Total de produtos: " + products.length); - await this.redisClient.set(cacheKey, JSON.stringify(products), 'EX', 900); + try { await this.redisClient.set(cacheKey, JSON.stringify(products), 'EX', 900); } catch (cacheErr) { console.error('Erro ao salvar cache searchProduct2:', cacheErr?.message || cacheErr); } return products; } catch (err) { diff --git a/src/sales/shopping/shopping.service.ts b/src/sales/shopping/shopping.service.ts index 32360f8..d8b7463 100644 --- a/src/sales/shopping/shopping.service.ts +++ b/src/sales/shopping/shopping.service.ts @@ -149,16 +149,25 @@ export class ShoppingService { await this.createShopping(idCart, itemShopping.invoiceStore, itemShopping.seller, queryRunner); } console.log('Incluindo item 04 - ' + Date.now().toString()); - const item = await this.getItemCartById(itemShopping.idCart, itemShopping.id); + const item = await queryRunner.manager + .getRepository(ShoppingItens) + .createQueryBuilder('estprevendai') + .where("\"estprevendai\".idcart = :idcart", { idcart: idCart }) + .andWhere("\"estprevendai\".id = :id", { id: itemShopping.id }) + .andWhere("\"estprevendai\".dtcancel is null") + .getOne(); console.log('Incluindo item 05 - ' + Date.now().toString()); if (item) { itemShopping.id = item.id; - this.updateItem(itemShopping); - return await this.getItemCartById(itemShopping.idCart, itemShopping.id); + await this.updateItemCart(itemShopping, queryRunner); + await this.calculateProfitShoppping(idCart, queryRunner); + await this.updateTotalShopping(idCart, queryRunner); + await queryRunner.commitTransaction(); + return itemShopping; } console.log('Incluindo item 06 - ' + Date.now().toString()); - const recordItens = await queryRunner.query(`SELECT COUNT(1) as "recordNo" FROM ESTPREVENDAI WHERE IDCART = '${itemShopping.idCart}'`); + const recordItens = await queryRunner.query(`SELECT COUNT(1) as "recordNo" FROM ESTPREVENDAI WHERE IDCART = :1`, [idCart]); let numSeq = 1; if (recordItens != null && recordItens.length > 0) { numSeq = recordItens[0].recordNo + 1; @@ -266,10 +275,10 @@ export class ShoppingService { console.log('Incluindo item 07 - ' + Date.now().toString()); // await queryRunner.manager.save(createItemShopping); console.log('Incluindo item 08 - ' + Date.now().toString()); + await this.calculateProfitShoppping(idCart, queryRunner); + await this.updateTotalShopping(idCart, queryRunner); await queryRunner.commitTransaction(); console.log('Incluindo item 09 - ' + Date.now().toString()); - await this.calculateProfitShoppping(idCart, queryRunner); - await this.updateTotalShopping(idCart); return createItemShopping; @@ -300,36 +309,19 @@ export class ShoppingService { } - async updateTotalShopping(idCart: string) { + async updateTotalShopping(idCart: string, activeQueryRunner?: QueryRunner) { + if (activeQueryRunner) { + await this.updateTotalShoppingWithRunner(idCart, activeQueryRunner); + return; + } + const connection = new Connection(connectionOptions); await connection.connect(); const queryRunner = connection.createQueryRunner(); await queryRunner.connect(); await queryRunner.startTransaction(); try { - const prevenda = await queryRunner - .query('SELECT SUM(ESTPREVENDAI.PTABELA * ESTPREVENDAI.QT) as "vltabela" ' + - ' ,SUM(ESTPREVENDAI.PVENDA * ESTPREVENDAI.QT) as "vlatend" ' + - ' ,SUM(ESTPREVENDAI.VLDESCONTO * ESTPREVENDAI.QT) as "vldesconto" ' + - ' ,SUM(PCPRODUT.PESOBRUTO * ESTPREVENDAI.QT) as "totpeso" ' + - ' FROM ESTPREVENDAI, PCPRODUT ' + - ' WHERE ESTPREVENDAI.CODPROD = PCPRODUT.CODPROD ' + - ' AND ESTPREVENDAI.IDCART = :1', [idCart]); - if (prevenda != null) { - const sql = ` UPDATE ESTPREVENDAC SET ` + - ` VLPEDIDO = :1 ` + - ` ,VLDESCONTO = :2 ` + - ` ,TOTPESO = :3 ` + - ` ,VLTABELA = :4 ` + - ` WHERE ID = :5 `; - await queryRunner.query(sql, [ - prevenda[0].vlatend, - prevenda[0].vldesconto, - prevenda[0].totpeso, - prevenda[0].vltabela, - idCart - ]); - } + await this.updateTotalShoppingWithRunner(idCart, queryRunner); await queryRunner.commitTransaction(); } catch (error) { @@ -342,6 +334,55 @@ export class ShoppingService { } + private async updateTotalShoppingWithRunner(idCart: string, queryRunner: QueryRunner) { + const prevenda = await queryRunner + .query('SELECT SUM(ESTPREVENDAI.PTABELA * ESTPREVENDAI.QT) as "vltabela" ' + + ' ,SUM(ESTPREVENDAI.PVENDA * ESTPREVENDAI.QT) as "vlatend" ' + + ' ,SUM(ESTPREVENDAI.VLDESCONTO * ESTPREVENDAI.QT) as "vldesconto" ' + + ' ,SUM(PCPRODUT.PESOBRUTO * ESTPREVENDAI.QT) as "totpeso" ' + + ' FROM ESTPREVENDAI, PCPRODUT ' + + ' WHERE ESTPREVENDAI.CODPROD = PCPRODUT.CODPROD ' + + ' AND ESTPREVENDAI.IDCART = :1', [idCart]); + if (prevenda != null) { + const sql = ` UPDATE ESTPREVENDAC SET ` + + ` VLPEDIDO = :1 ` + + ` ,VLDESCONTO = :2 ` + + ` ,TOTPESO = :3 ` + + ` ,VLTABELA = :4 ` + + ` WHERE ID = :5 `; + await queryRunner.query(sql, [ + prevenda[0].vlatend, + prevenda[0].vldesconto, + prevenda[0].totpeso, + prevenda[0].vltabela, + idCart + ]); + } + } + + private async updateItemCart(itemShopping: ShoppingItem, queryRunner: QueryRunner) { + const sql = ' UPDATE ESTPREVENDAI SET ' + + ' PVENDA = :1 ' + + ' ,PTABELA = :2 ' + + ' ,QT = :3 ' + + ' ,TIPOENTREGA = :4 ' + + ' ,CODFILIALRETIRA = :5 ' + + ' ,DESCRICAOAUXILIAR = :6 ' + + ' ,AMBIENTE = :7 ' + + ' WHERE ID = :8 '; + + await queryRunner.query(sql, [ + itemShopping.price, + itemShopping.listPrice, + itemShopping.quantity, + itemShopping.deliveryType, + itemShopping.stockStore, + itemShopping.auxDescription, + itemShopping.environment, + itemShopping.id + ]); + } + async updateItem(itemShopping: ShoppingItem) { const connection = new Connection(connectionOptions); await connection.connect(); @@ -350,31 +391,10 @@ export class ShoppingService { await queryRunner.startTransaction(); try { - const sql = ' UPDATE ESTPREVENDAI SET ' + - ' PVENDA = :1 ' + - ' ,PTABELA = :2 ' + - ' ,QT = :3 ' + - ' ,TIPOENTREGA = :4 ' + - ' ,CODFILIALRETIRA = :5 ' + - ' ,DESCRICAOAUXILIAR = :6 ' + - ' ,AMBIENTE = :7 ' + - ' WHERE ID = :8 '; - - await queryRunner.query(sql, [ - itemShopping.price, - itemShopping.listPrice, - itemShopping.quantity, - itemShopping.deliveryType, - itemShopping.stockStore, - itemShopping.auxDescription, - itemShopping.environment, - itemShopping.id - ]); - - await queryRunner.commitTransaction(); - - await this.updateTotalShopping(itemShopping.idCart); + await this.updateItemCart(itemShopping, queryRunner); + await this.updateTotalShopping(itemShopping.idCart, queryRunner); await this.calculateProfitShoppping(itemShopping.idCart, queryRunner); + await queryRunner.commitTransaction(); } catch (erro) { await queryRunner.rollbackTransaction(); @@ -419,9 +439,9 @@ export class ShoppingService { // }) // .where("\"ESTPREVENDAI\".id = :id", { id: itemShopping.id }) // .execute(); - await queryRunner.commitTransaction(); await this.calculateProfitShoppping(itemShopping.idCart, queryRunner); - await this.updateTotalShopping(itemShopping.idCart); + await this.updateTotalShopping(itemShopping.idCart, queryRunner); + await queryRunner.commitTransaction(); return itemShopping; } catch (erro) { await queryRunner.rollbackTransaction(); @@ -450,9 +470,11 @@ export class ShoppingService { id ]); } + if (item != null) { + await this.updateTotalShopping(item.idCart, queryRunner); + await this.calculateProfitShoppping(item.idCart, queryRunner); + } await queryRunner.commitTransaction(); - await this.updateTotalShopping(item.idCart); - await this.calculateProfitShoppping(item.idCart, queryRunner); } catch (erro) { await queryRunner.rollbackTransaction(); throw erro; @@ -484,30 +506,29 @@ export class ShoppingService { ' ,VLDESCONTO = :3 ' + ' ,CODFUNCDESC = :4 ' + ' WHERE ID = :5 '; - items.filter(item => item.promotion == null || item.promotion == 0) - .forEach(async (item) => { - const price = (item.listPrice * (1 - (order.percentDiscount / 100))).toFixed(2); - listPriceTotal += (item.listPrice * item.quantity); - discountTotal += ((Number.parseFloat(item.listPrice.toFixed(2)) - Number.parseFloat(price)) * item.quantity); - await queryRunner.query(sql, [ - Number.parseFloat(price), - order.percentDiscount, - (item.listPrice - Number.parseFloat(price)), - order.idUserAuth, - item.id - ]); - // await queryRunner.manager - // .createQueryBuilder() - // .update(ShoppingItens) - // .set({ - // price: Number.parseFloat(price), - // discount: order.percentDiscount, - // discountValue: (item.listPrice - Number.parseFloat(price)), - // userDiscount: order.idUserAuth - // }) - // .where("\"ESTPREVENDAI\".id = :id", { id: item.id }) - // .execute(); - }); + for (const item of items.filter(item => item.promotion == null || item.promotion == 0)) { + const price = (item.listPrice * (1 - (order.percentDiscount / 100))).toFixed(2); + listPriceTotal += (item.listPrice * item.quantity); + discountTotal += ((Number.parseFloat(item.listPrice.toFixed(2)) - Number.parseFloat(price)) * item.quantity); + await queryRunner.query(sql, [ + Number.parseFloat(price), + order.percentDiscount, + (item.listPrice - Number.parseFloat(price)), + order.idUserAuth, + item.id + ]); + // await queryRunner.manager + // .createQueryBuilder() + // .update(ShoppingItens) + // .set({ + // price: Number.parseFloat(price), + // discount: order.percentDiscount, + // discountValue: (item.listPrice - Number.parseFloat(price)), + // userDiscount: order.idUserAuth + // }) + // .where("\"ESTPREVENDAI\".id = :id", { id: item.id }) + // .execute(); + } console.log('total de desconto: ' + discountTotal); const sqlOrder = 'UPDATE ESTPREVENDAC SET ' + ' VLPEDIDO = :1 ' + @@ -529,9 +550,9 @@ export class ShoppingService { // }) // .where("\"ESTPREVENDAC\".id = :id", { id: order.id }) // .execute(); - await queryRunner.commitTransaction(); await this.calculateProfitShoppping(order.id, queryRunner); - await this.updateTotalShopping(order.id); + await this.updateTotalShopping(order.id, queryRunner); + await queryRunner.commitTransaction(); } catch (err) { console.log(err); await queryRunner.rollbackTransaction();