Cache departamento

This commit is contained in:
JurTI-BR
2025-03-14 09:26:28 -03:00
parent 0c517800e0
commit b43af08d04
5 changed files with 223 additions and 136 deletions

View File

@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/camelcase */
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { HttpException, HttpStatus, Injectable,Inject } from '@nestjs/common';
import { ShoppingItens } from 'src/domain/entity/tables/estprevendai.entity';
import { Sale } from 'src/domain/entity/tables/estvenda.entity';
import { Pcpedctemp } from 'src/domain/entity/tables/pcpedctemp.entity';
@@ -13,11 +13,14 @@ import { ListsService } from 'src/backoffice/lists/lists.service';
import { CustomerService } from '../customer/customer.service';
import { AddressCustomerService } from '../address-customer/address-customer.service';
import { ShoppingService } from '../shopping/shopping.service';
import Redis = require('ioredis');
@Injectable()
export class OrderService {
constructor(
@Inject('REDIS_CLIENT') private readonly redisClient: Redis.Redis,
private readonly listsService: ListsService,
private readonly customerService: CustomerService,
private readonly addressCustomerService: AddressCustomerService,
@@ -669,7 +672,6 @@ export class OrderService {
numeroSeq = numeroSeq + 1;
}
// execute some operations on this transaction:
await queryRunner.manager
.createQueryBuilder()
.insert()
@@ -687,7 +689,7 @@ export class OrderService {
await queryRunner.release();
await connection.close();
}
//const idOrder = await this.getIdOrder(cart.idSeller);
}
@@ -742,15 +744,10 @@ export class OrderService {
let sql = 'SELECT NVL(PROXNUMPEDWEB,0) as "proxnumpedweb" FROM PCUSUARI ' +
' WHERE PCUSUARI.CODUSUR = :1 FOR UPDATE';
const seller = await queryRunner.query(sql, [idSeller]);
/* const seller = await queryRunner.manager
.getRepository(Pcusuari)
.createQueryBuilder('pcusuari')
.where("\"pcusuari\".codusur = :idseller", { idseller: idSeller })
.getOne(); */
const idOrder = seller[0].proxnumpedweb;
console.log(idOrder);
// lets now open a new transaction:
await queryRunner.startTransaction();
try {
@@ -759,27 +756,18 @@ export class OrderService {
' WHERE PCUSUARI.CODUSUR = :1';
await queryRunner.query(sql, [idSeller]);
// await queryRunner.manager
// .createQueryBuilder()
// .update(Pcusuari)
// .set({ proxnumpedweb: idOrder + 1 })
// .where("\"PCUSUARI\".codusur = :idseller", { idseller: idSeller })
// .execute();
// commit transaction now:
await queryRunner.commitTransaction();
return idOrder;
} catch (err) {
// since we have errors let's rollback changes we made
await queryRunner.rollbackTransaction();
console.log(err);
return -1;
} finally {
// you need to release query runner which is manually created:
await queryRunner.release();
await connection.close();
}
@@ -807,77 +795,160 @@ export class OrderService {
}
}
async getOrders(store: string, initialDate: Date, finalDate: Date,
document: string, name: string, sellerId: number, idOrder: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
let sqlWhere = '';
let sql = '';
async getOrders(
store: string,
initialDate: any,
finalDate: any,
document: string,
name: string,
sellerId: number,
idOrder: string
): Promise<any[]> {
const initialDateObj = initialDate instanceof Date ? initialDate : new Date(initialDate);
const finalDateObj = finalDate instanceof Date ? finalDate : new Date(finalDate);
const cacheKey =
'getOrders:' +
store +
'_' +
initialDateObj.toISOString() +
'_' +
finalDateObj.toISOString() +
'_' +
document +
'_' +
name +
'_' +
sellerId +
'_' +
idOrder;
const lockKey = 'lock:' + cacheKey;
const lockTimeout = 30; // lock expira em 30 segundos
try {
const cachedResult = await this.redisClient.get(cacheKey);
if (cachedResult) {
console.log('Retornando resultado do cache (getOrders)');
return JSON.parse(cachedResult);
}
} catch (err) {
console.error('Erro ao acessar o Redis no getOrders:', err?.message || err);
}
const lockValue = Date.now() + lockTimeout * 1000 + 1;
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 (getOrders):', err?.message || err);
}
if (acquiredLock === 'OK') {
sql = ` SELECT TO_CHAR(PCPEDC.DATA, \'DD/MM/YYYY\') as "createDate" ` +
` ,PCPEDC.NUMPED as "orderId" ` +
` ,PCPEDC.CODFILIAL as "store" ` +
` ,CASE WHEN PCPEDC.POSICAO = 'B' THEN 'BLOQUEADO' ` +
` WHEN PCPEDC.POSICAO = 'P' THEN 'PENDENTE' ` +
` WHEN PCPEDC.POSICAO = 'L' THEN 'LIBERADO' ` +
` WHEN PCPEDC.POSICAO = 'M' THEN 'MONTADO' ` +
` WHEN PCPEDC.POSICAO = 'F' THEN 'FATURADO' END as "status" ` +
` ,PCPEDC.CODCLI as "customerId" ` +
` ,PCPEDC.CODUSUR as "sellerId" ` +
` ,PCCLIENT.CLIENTE as "customerName" ` +
` ,PCPEDC.VLATEND as "orderValue" ` +
` ,PCPEDC.NUMITENS as "itens" ` +
` ,CASE WHEN ( SELECT COUNT(1) FROM ESTPIX WHERE ESTPIX.NUMPED = PCPEDC.NUMPED ) > 0 THEN 'S' ELSE 'N' END as "pixCreate" ` +
` FROM PCPEDC, PCCLIENT ` +
` WHERE PCPEDC.CODCLI = PCCLIENT.CODCLI ` +
` AND PCPEDC.CONDVENDA IN (1,7) ` +
` AND PCPEDC.DTCANCEL IS NULL AND PCPEDC.POSICAO NOT IN ('C') `;
` AND PCPEDC.ROTINALANC = 'VENDAWEB' `;
if (store != null && store != '') {
sqlWhere += ` AND PCPEDC.CODFILIAL = '${store}' `;
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
let sqlWhere = '';
let sql = '';
try {
sql = ` SELECT TO_CHAR(PCPEDC.DATA, 'DD/MM/YYYY') as "createDate",
PCPEDC.NUMPED as "orderId",
PCPEDC.CODFILIAL as "store",
CASE
WHEN PCPEDC.POSICAO = 'B' THEN 'BLOQUEADO'
WHEN PCPEDC.POSICAO = 'P' THEN 'PENDENTE'
WHEN PCPEDC.POSICAO = 'L' THEN 'LIBERADO'
WHEN PCPEDC.POSICAO = 'M' THEN 'MONTADO'
WHEN PCPEDC.POSICAO = 'F' THEN 'FATURADO'
END as "status",
PCPEDC.CODCLI as "customerId",
PCPEDC.CODUSUR as "sellerId",
PCCLIENT.CLIENTE as "customerName",
PCPEDC.VLATEND as "orderValue",
PCPEDC.NUMITENS as "itens",
CASE WHEN ( SELECT COUNT(1) FROM ESTPIX WHERE ESTPIX.NUMPED = PCPEDC.NUMPED ) > 0 THEN 'S' ELSE 'N' END as "pixCreate"
FROM PCPEDC, PCCLIENT
WHERE PCPEDC.CODCLI = PCCLIENT.CODCLI
AND PCPEDC.CONDVENDA IN (1,7)
AND PCPEDC.DTCANCEL IS NULL
AND PCPEDC.POSICAO NOT IN ('C')
AND PCPEDC.ROTINALANC = 'VENDAWEB' `;
if (store && store !== '') {
sqlWhere += ` AND PCPEDC.CODFILIAL = '${store}' `;
}
if (document != null && document != '') {
sqlWhere += ` AND REGEXP_REPLACE(PCCLIENT.CGCENT, '[^0-9]', '') = REGEXP_REPLACE('${document}', '[^0-9]', '')`;
if (document && document !== '') {
sqlWhere += ` AND REGEXP_REPLACE(PCCLIENT.CGCENT, '[^0-9]', '') = REGEXP_REPLACE('${document}', '[^0-9]', '') `;
}
if (name != null && name != '') {
sqlWhere += ` AND PCCLIENT.CLIENTE LIKE '${name.replace('@', '%')}'||'%'`;
if (name && name !== '') {
sqlWhere += ` AND PCCLIENT.CLIENTE LIKE '${name.replace('@', '%')}'||'%' `;
}
if (sellerId > 0) {
sqlWhere += ` AND PCPEDC.CODUSUR = ${sellerId} `;
sqlWhere += ` AND PCPEDC.CODUSUR = ${sellerId} `;
}
if (idOrder.trim() != null && idOrder.trim() != '') {
sqlWhere += ` AND PCPEDC.NUMPED = ${idOrder} `;
if (idOrder && idOrder.trim() !== '') {
sqlWhere += ` AND PCPEDC.NUMPED = ${idOrder} `;
}
//tratamento de data//
const startDate = new Date(initialDate);
// Formatação das datas para o SQL
const startDate = initialDateObj;
let day = startDate.getDate();
let month = ("00" + (startDate.getMonth() + 1)).slice(-2);
let year = startDate.getFullYear();
const startFormat = day + "/" + month + "/" + year;
const endDate = new Date(finalDate);
const endDate = finalDateObj;
day = endDate.getDate();
month = ("00" + (endDate.getMonth() + 1)).slice(-2);
year = endDate.getFullYear();
const endFormat = day + "/" + month + "/" + year;
sqlWhere += ` AND PCPEDC.DATA BETWEEN TO_DATE('${startFormat}', 'DD/MM/YYYY') AND TO_DATE('${endFormat}', 'DD/MM/YYYY') `;
sqlWhere += ` AND PCPEDC.DATA BETWEEN TO_DATE('${startFormat}', 'DD/MM/YYYY') AND TO_DATE('${endFormat}', 'DD/MM/YYYY') `;
const result = await queryRunner.query(sql + sqlWhere);
// Armazena o resultado no cache com TTL de 1 hora (3600 segundos)
try {
await this.redisClient.set(cacheKey, JSON.stringify(result), 'EX', 3600);
} catch (cacheSetErr) {
console.error('Erro ao salvar o resultado no cache (getOrders):', cacheSetErr?.message || cacheSetErr);
}
return result;
} catch (error) {
console.log(error);
} catch (error) {
console.error('Erro ao executar a query no getOrders:', error?.message || error);
throw error;
} finally {
} finally {
await queryRunner.release();
await connection.close();
// Libera o lock, somente se o valor armazenado for o mesmo deste processo
try {
const currentLockValue = await this.redisClient.get(lockKey);
if (currentLockValue === lockValue.toString()) {
await this.redisClient.del(lockKey);
}
} catch (lockErr) {
console.error('Erro ao liberar o lock do Redis (getOrders):', lockErr?.message || lockErr);
}
}
} else {
// Se não conseguir adquirir o lock, aguarda 1 segundo e tenta novamente
console.log('Lock não adquirido (getOrders), aguardando e tentando novamente...');
await this.sleep(1000);
return this.getOrders(store, initialDate, finalDate, document, name, sellerId, idOrder);
}
}
}
// Função auxiliar para aguardar um período determinado (em milissegundos)
private sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
async getItensOrder(idOrder: number) {
const connection = new Connection(connectionOptions);