homolog #1

Merged
luis merged 22 commits from homolog into main 2026-01-12 14:55:39 -05:00
15 changed files with 505 additions and 331 deletions

13
.env Normal file
View File

@@ -0,0 +1,13 @@
ORACLE_CLIENT_PATH='/usr/lib/oracle/21/client64/lib'
###REDIS
REDIS_HOST='172.35.0.217'
REDIS_PORT='6379'
####ORACLE
PORT='8065'
DB_USERNAME='simplifique'
DB_PASSWORD='simplifique'
DB_CONNECT_STRING='(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.35.0.250)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)))'

View File

@@ -0,0 +1,27 @@
name: Deploy NestJS API
on: [push]
jobs:
build-and-push-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Login no Harbor
run: |
echo "${{ secrets.HARBOR_PASSWORD }}" | docker login 172.35.0.216 -u ${{ secrets.HARBOR_USERNAME }} --password-stdin
- name: Build e Push
run: |
TAG=${{ gitea.sha }}
docker build -t 172.35.0.216/library/vendaweb-api:$TAG .
docker tag 172.35.0.216/library/vendaweb-api:$TAG 172.35.0.216/library/vendaweb-api:latest
docker push 172.35.0.216/library/vendaweb-api:$TAG
docker push 172.35.0.216/library/vendaweb-api:latest
- name: Notificar Portainer via Webhook
run: |
# O Webhook avisa o Portainer para puxar a nova imagem imediatamente
curl -X POST "${{ secrets.PORTAINER_WEBHOOK_VENDAWEBAPI }}"

View File

@@ -0,0 +1,7 @@
O Rollback via Git (Mais Seguro)
No Gitea, faça um git revert no commit que deu erro.
Dê o git push.
O Portainer detectará a mudança e atualizará o serviço para a versão estável de forma oficial.

3
.gitignore vendored
View File

@@ -33,3 +33,6 @@ lerna-debug.log*
!.vscode/launch.json !.vscode/launch.json
!.vscode/extensions.json !.vscode/extensions.json
# Environment variables
.env

View File

@@ -1,32 +1,39 @@
FROM node:16 # Estágio 1: Build
FROM node:16-bullseye-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install --legacy-peer-deps
COPY . .
RUN npm run build
FROM node:16-bullseye-slim
# Instalar dependências do Oracle
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
apt-transport-https \
ca-certificates \
libaio1 \ libaio1 \
unzip \ unzip \
wget \ wget \
libc6 \ && mkdir -p /opt/oracle
libncurses5 && \
mkdir -p /opt/oracle && \
wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basic-linuxx64.zip -O /opt/oracle/instantclient-basic-linuxx64.zip && \
unzip /opt/oracle/instantclient-basic-linuxx64.zip -d /opt/oracle && \
rm /opt/oracle/instantclient-basic-linuxx64.zip && \
ln -s /opt/oracle/instantclient_* /opt/oracle/instantclient && \
echo "/opt/oracle/instantclient" > /etc/ld.so.conf.d/oracle-instantclient.conf && \
ldconfig
# Instalar Oracle Instant Client
RUN wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basic-linuxx64.zip -O /opt/oracle/client.zip && \
unzip /opt/oracle/client.zip -d /opt/oracle && \
rm /opt/oracle/client.zip && \
ln -s /opt/oracle/instantclient_* /opt/oracle/instantclient
# Configurar o sistema para encontrar as bibliotecas do Oracle
ENV LD_LIBRARY_PATH=/opt/oracle/instantclient
RUN echo "/opt/oracle/instantclient" > /etc/ld.so.conf.d/oracle-instantclient.conf && ldconfig
WORKDIR /app WORKDIR /app
# Copiar apenas o necessário do estágio anterior
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./ # Variáveis de ambiente padrão para o driver oracledb
ENV OCI_LIB_DIR=/opt/oracle/instantclient
ENV OCI_INC_DIR=/opt/oracle/instantclient/sdk/include
RUN npm install --legacy-peer-deps
COPY . .
CMD ["npm", "run", "start:prod"] CMD ["npm", "run", "start:prod"]

150
README.md
View File

@@ -1,75 +1,75 @@
<p align="center"> <p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a> <a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
</p> </p>
[travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master [travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master
[travis-url]: https://travis-ci.org/nestjs/nest [travis-url]: https://travis-ci.org/nestjs/nest
[linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux [linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux
[linux-url]: https://travis-ci.org/nestjs/nest [linux-url]: https://travis-ci.org/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications, heavily inspired by <a href="https://angular.io" target="blank">Angular</a>.</p> <p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications, heavily inspired by <a href="https://angular.io" target="blank">Angular</a>.</p>
<p align="center"> <p align="center">
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a> <a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a> <a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/dm/@nestjs/core.svg" alt="NPM Downloads" /></a> <a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/dm/@nestjs/core.svg" alt="NPM Downloads" /></a>
<a href="https://travis-ci.org/nestjs/nest"><img src="https://api.travis-ci.org/nestjs/nest.svg?branch=master" alt="Travis" /></a> <a href="https://travis-ci.org/nestjs/nest"><img src="https://api.travis-ci.org/nestjs/nest.svg?branch=master" alt="Travis" /></a>
<a href="https://travis-ci.org/nestjs/nest"><img src="https://img.shields.io/travis/nestjs/nest/master.svg?label=linux" alt="Linux" /></a> <a href="https://travis-ci.org/nestjs/nest"><img src="https://img.shields.io/travis/nestjs/nest/master.svg?label=linux" alt="Linux" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#5" alt="Coverage" /></a> <a href="https://coveralls.io/github/nestjs/nest?branch=master"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#5" alt="Coverage" /></a>
<a href="https://gitter.im/nestjs/nestjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge"><img src="https://badges.gitter.im/nestjs/nestjs.svg" alt="Gitter" /></a> <a href="https://gitter.im/nestjs/nestjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge"><img src="https://badges.gitter.im/nestjs/nestjs.svg" alt="Gitter" /></a>
<a href="https://opencollective.com/nest#backer"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a> <a href="https://opencollective.com/nest#backer"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a> <a href="https://opencollective.com/nest#sponsor"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec"><img src="https://img.shields.io/badge/Donate-PayPal-dc3d53.svg"/></a> <a href="https://paypal.me/kamilmysliwiec"><img src="https://img.shields.io/badge/Donate-PayPal-dc3d53.svg"/></a>
<a href="https://twitter.com/nestframework"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a> <a href="https://twitter.com/nestframework"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p> </p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer) <!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)--> [![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description ## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation ## Installation
```bash ```bash
$ npm install $ npm install
``` ```
## Running the app ## Running the app
```bash ```bash
# development # development
$ npm run start $ npm run start
# watch mode # watch mode
$ npm run start:dev $ npm run start:dev
# production mode # production mode
$ npm run start:prod $ npm run start:prod
``` ```
## Test ## Test
```bash ```bash
# unit tests # unit tests
$ npm run test $ npm run test
# e2e tests # e2e tests
$ npm run test:e2e $ npm run test:e2e
# test coverage # test coverage
$ npm run test:cov $ npm run test:cov
``` ```
## Support ## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch ## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/) - Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework) - Twitter - [@nestframework](https://twitter.com/nestframework)
## License ## License
Nest is [MIT licensed](LICENSE). Nest is [MIT licensed](LICENSE).

View File

@@ -1,14 +1,18 @@
version: '3.8' version: '3.8'
services: services:
vendaweb: vendaweb-api:
image: link70/vendaweb image: 172.35.0.216/library/vendaweb-api:latest
deploy:
replicas: 20
resources:
limits:
cpus: '0.5'
memory: 512M
ports: ports:
- "8065:8065" - "8065:8065"
restart: always networks:
- simplifique-network
deploy:
replicas: 4
update_config:
order: start-first
parallelism: 1
networks:
simplifique-network:
external: true

View File

@@ -93,7 +93,7 @@ export class UserService {
' WHERE PCEMPR.CODFILIAL = PCFILIAL.CODIGO (+)' + ' WHERE PCEMPR.CODFILIAL = PCFILIAL.CODIGO (+)' +
' AND PCPARAMFILIAL.CODFILIAL = \'99\' ' + ' AND PCPARAMFILIAL.CODFILIAL = \'99\' ' +
' AND PCPARAMFILIAL.NOME = \'CON_CODSETORGERENTELOJA\' ' + ' AND PCPARAMFILIAL.NOME = \'CON_CODSETORGERENTELOJA\' ' +
' AND PCEMPR.EMAIL = :username AND PCEMPR.SENHABD = CRYPT(:password, USUARIOBD)'; ' AND PCEMPR.USUARIOBD = :username AND PCEMPR.SENHABD = CRYPT(:password, USUARIOBD)';
const users = await queryRunner.manager const users = await queryRunner.manager
.query(sql, [user.email, user.password]); .query(sql, [user.email, user.password]);
@@ -141,8 +141,8 @@ export class UserService {
const noDeliveryDays = await queryRunner.manager const noDeliveryDays = await queryRunner.manager
.query(sqlDiasSemEntrega, [Number.parseInt(users[0].deliveryTime)]); .query(sqlDiasSemEntrega, [Number.parseInt(users[0].deliveryTime)]);
const days = Number.parseInt(deliveryDays2[0].days) + const days = Number.parseInt(deliveryDays2[0].days) +
( noDeliveryDays.length > 0 ? Number.parseInt(noDeliveryDays[0].daysNoDelivery) : 0 ); (noDeliveryDays.length > 0 ? Number.parseInt(noDeliveryDays[0].daysNoDelivery) : 0);
const userDb = users[0]; const userDb = users[0];
console.log(userDb); console.log(userDb);

View File

@@ -12,9 +12,9 @@ export class AppController {
} }
@Get('health') @Get('health')
@ApiOperation({ summary: 'Health check' }) @ApiOperation({ summary: 'Health check' })
healthCheck() { healthCheck() {
return { status: 'ok' }; return { status: 'SIMPLIFIQUE HOME CENTER 2026' };
} }
} }

View File

@@ -1,18 +1,17 @@
import { TypeOrmModuleOptions } from '@nestjs/typeorm'; import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { ConnectionOptions } from 'typeorm'; import { ConnectionOptions } from 'typeorm';
import 'dotenv/config';
export const typeOrmConfig: TypeOrmModuleOptions = { export const typeOrmConfig: TypeOrmModuleOptions = {
type: "oracle", type: "oracle",
// host: "192.168.100.40", host: "172.35.0.250",
// username: "LIVIA", username: process.env.DB_USERNAME || "simplifique",
// password: "LIVIA", password: process.env.DB_PASSWORD || "simplifique",
host: "10.1.1.241", connectString:
username: "SEVEN", process.env.DB_CONNECT_STRING ||
password: "USR54SEV", '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.35.0.250)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)))',
// username: "API",
// password: "E05H5KIEQV3YKDJR",
port: 1521, port: 1521,
sid: "WINT", sid: "ORCL",
synchronize: false, synchronize: false,
logging: false, logging: false,
entities: [__dirname + '/../**/*.entity.{js,ts}'], entities: [__dirname + '/../**/*.entity.{js,ts}'],
@@ -21,11 +20,14 @@ export const typeOrmConfig: TypeOrmModuleOptions = {
export const connectionOptions: ConnectionOptions = { export const connectionOptions: ConnectionOptions = {
type: "oracle", type: "oracle",
host: "10.1.1.241", host: "172.35.0.250",
username: "SEVEN", username: process.env.DB_USERNAME || "simplifique",
password: "USR54SEV", password: process.env.DB_PASSWORD || "simplifique",
connectString:
process.env.DB_CONNECT_STRING ||
'(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.35.0.250)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)))',
port: 1521, port: 1521,
sid: "WINT", sid: "ORCL",
synchronize: false, synchronize: false,
logging: false, logging: false,
entities: [__dirname + '/../**/*.entity.{js,ts}'], entities: [__dirname + '/../**/*.entity.{js,ts}'],

View File

@@ -1355,7 +1355,7 @@ export class Pcclient {
@Column({ name: 'ORGAOPUBMUNICIPAL' }) @Column({ name: 'ORGAOPUBMUNICIPAL' })
orgaopubmunicipal: string; orgaopubmunicipal: string;
@Column({ name: 'CODCIDADECOM' }) @Column({ name: 'CODCIDADECOM' })
codcidadecom: number; codcidadecom: number;
@Column({ name: 'CODPROMOCAOMED' }) @Column({ name: 'CODPROMOCAOMED' })
@@ -1622,8 +1622,8 @@ export class Pcclient {
@Column({ name: 'CODCONDCOMERCIAL' }) @Column({ name: 'CODCONDCOMERCIAL' })
codcondcomercial: string; codcondcomercial: string;
@Column({ name: 'MEIOCOMUNICACAO' }) // @Column({ name: 'MEIOCOMUNICACAO' })
meiocomunicacao: string; // meiocomunicacao: string;
@Column({ name: 'CODGRUPOCOMERCIALMED' }) @Column({ name: 'CODGRUPOCOMERCIALMED' })
codgrupocomercialmed: number; codgrupocomercialmed: number;
@@ -1645,5 +1645,5 @@ export class Pcclient {
@OneToMany(() => Pcpedc, pedidos => pedidos.pcclient) @OneToMany(() => Pcpedc, pedidos => pedidos.pcclient)
pedidos: Pcpedc[]; pedidos: Pcpedc[];
} }

View File

@@ -1,12 +1,23 @@
import { Provider } from '@nestjs/common'; import { Provider } from '@nestjs/common';
import Redis = require('ioredis'); import Redis = require('ioredis');
export const redisProvider: Provider = { export const redisProvider: Provider = {
provide: 'REDIS_CLIENT', provide: 'REDIS_CLIENT',
useFactory: () => { useFactory: () => {
return new Redis({ return new Redis({
host: '10.1.1.109',
host: '172.35.0.217',
port: 6379, port: 6379,
}); });
}, },
};
};

View File

@@ -44,7 +44,7 @@ export class CustomerService {
' ,pccidade.codibge as "ibgeCode" ' + ' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' + ' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' + ' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' + // ' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' + ' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' + ' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' + ' ,pcclient.codmunicipio as "ibgeCode" ' +
@@ -102,16 +102,16 @@ export class CustomerService {
' ,pcclient.telent as "phone" ' + ' ,pcclient.telent as "phone" ' +
' ,pcclient.telcelent as "cellPhone" ' + ' ,pcclient.telcelent as "cellPhone" ' +
' ,pcclient.ieent as "numberState" ' + ' ,pcclient.ieent as "numberState" ' +
' ,pcclient.codcategoria as "categoryId" ' + // ' ,pcclient.codcategoria as "categoryId" ' +
' ,pcclient.codsubcategoria as "subCategoryId" ' + // ' ,pcclient.codsubcategoria as "subCategoryId" ' +
' ,pcclient.codpraca as "placeId" ' + ' ,pcclient.codpraca as "placeId" ' +
' ,pcclient.codusur1 as "sellerId" ' + ' ,pcclient.codusur1 as "sellerId" ' +
' ,pccidade.codibge as "ibgeCode" ' + ' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' + ' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' + ' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' + // ' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' + ' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' + ' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' + ' ,pcclient.codmunicipio as "ibgeCode" ' +
' ,pcclient.codcidade as "cityId" ' + ' ,pcclient.codcidade as "cityId" ' +
' ,pcclient.tipoendereco as "addressType" ' + ' ,pcclient.tipoendereco as "addressType" ' +
@@ -158,7 +158,7 @@ export class CustomerService {
' ,pccidade.codibge as "ibgeCode" ' + ' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' + ' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' + ' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' + //' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' + ' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' + ' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' + ' ,pcclient.codmunicipio as "ibgeCode" ' +
@@ -173,7 +173,7 @@ export class CustomerService {
FROM PCPRACA FROM PCPRACA
WHERE PCPRACA.CODPRACA = ${customer[0].placeId}`); WHERE PCPRACA.CODPRACA = ${customer[0].placeId}`);
return {...customer[0], place: place[0]}; return { ...customer[0], place: place[0] };
} catch (error) { } catch (error) {
console.log(error); console.log(error);
throw error; throw error;
@@ -267,16 +267,16 @@ export class CustomerService {
newCustomer.telcelent = customer.cellPhone; newCustomer.telcelent = customer.cellPhone;
newCustomer.celularwhatsapp = customer.cellPhone; newCustomer.celularwhatsapp = customer.cellPhone;
newCustomer.codusur1 = customer.sellerId; newCustomer.codusur1 = customer.sellerId;
newCustomer.codatv1 = ( customer.ramo != null && customer.ramo.id > 0 ) ? customer.ramo.id : newCustomer.codatv1; newCustomer.codatv1 = (customer.ramo != null && customer.ramo.id > 0) ? customer.ramo.id : newCustomer.codatv1;
//Endereço de entrega //Endereço de entrega
newCustomer.cepent = customer.zipCode; newCustomer.cepent = customer.zipCode;
newCustomer.enderent = customer.address.toUpperCase(); newCustomer.enderent = customer.address.toUpperCase();
newCustomer.numeroent = customer.addressNumber; newCustomer.numeroent = customer.addressNumber;
if ( customer.complement !== null && customer.complement.length > 80 ) { if (customer.complement !== null && customer.complement.length > 80) {
newCustomer.complementoent = customer.complement.substring(0, 80 ).toUpperCase(); newCustomer.complementoent = customer.complement.substring(0, 80).toUpperCase();
} else { } else {
if ( customer.complement != null ) { if (customer.complement != null) {
newCustomer.complementoent = customer.complement.toUpperCase(); newCustomer.complementoent = customer.complement.toUpperCase();
} }
} }
newCustomer.bairroent = customer.neighborhood.toUpperCase(); newCustomer.bairroent = customer.neighborhood.toUpperCase();
@@ -286,10 +286,10 @@ export class CustomerService {
newCustomer.cepcom = customer.zipCode; newCustomer.cepcom = customer.zipCode;
newCustomer.endercom = customer.address.toUpperCase(); newCustomer.endercom = customer.address.toUpperCase();
newCustomer.numerocom = customer.addressNumber.toUpperCase(); newCustomer.numerocom = customer.addressNumber.toUpperCase();
if ( customer.complement !== null && customer.complement.length > 80 ) { if (customer.complement !== null && customer.complement.length > 80) {
newCustomer.complementocom = customer.complement.substring(0, 80 ).toUpperCase(); newCustomer.complementocom = customer.complement.substring(0, 80).toUpperCase();
} else { } else {
if ( customer.complement != null ) { if (customer.complement != null) {
newCustomer.complementocom = customer.complement.toUpperCase(); newCustomer.complementocom = customer.complement.toUpperCase();
} }
} }
@@ -300,12 +300,12 @@ export class CustomerService {
newCustomer.cepcob = customer.zipCode; newCustomer.cepcob = customer.zipCode;
newCustomer.endercob = customer.address.toUpperCase(); newCustomer.endercob = customer.address.toUpperCase();
newCustomer.numerocob = customer.addressNumber; newCustomer.numerocob = customer.addressNumber;
if ( customer.complement !== null && customer.complement.length > 80 ) { if (customer.complement !== null && customer.complement.length > 80) {
newCustomer.complementocob = customer.complement.substring(0, 80 ).toUpperCase(); newCustomer.complementocob = customer.complement.substring(0, 80).toUpperCase();
} else { } else {
if ( customer.complement ) { if (customer.complement) {
newCustomer.complementocob = customer.complement.toUpperCase(); newCustomer.complementocob = customer.complement.toUpperCase();
} }
} }
newCustomer.bairrocob = customer.neighborhood.toUpperCase(); newCustomer.bairrocob = customer.neighborhood.toUpperCase();
newCustomer.municcob = customer.city.toUpperCase(); newCustomer.municcob = customer.city.toUpperCase();
@@ -317,7 +317,7 @@ export class CustomerService {
newCustomer.codmunicipio = Number.parseInt(customer.ibgeCode); newCustomer.codmunicipio = Number.parseInt(customer.ibgeCode);
newCustomer.codcidadecom = newCustomer.codcidade; newCustomer.codcidadecom = newCustomer.codcidade;
newCustomer.dtnasc = customer.birthdate; newCustomer.dtnasc = customer.birthdate;
newCustomer.meiocomunicacao = customer.communicate; // newCustomer.meiocomunicacao = customer.communicate;
newCustomer.codfunccad = customer.idUser; newCustomer.codfunccad = customer.idUser;
newCustomer.codfunccadastro = customer.idUser; newCustomer.codfunccadastro = customer.idUser;
newCustomer.codfuncultalter = customer.idUser; newCustomer.codfuncultalter = customer.idUser;
@@ -341,7 +341,7 @@ export class CustomerService {
city: customer.city, state: customer.state, city: customer.city, state: customer.state,
allowMessage: customer.allowMessage, cellPhone: customer.cellPhone, allowMessage: customer.allowMessage, cellPhone: customer.cellPhone,
category: customer.category, subCategory: customer.subCategory, category: customer.category, subCategory: customer.subCategory,
place: customer.place, ramo: customer.ramo, meiocomunicacao: customer.communicate, place: customer.place, ramo: customer.ramo, /*meiocomunicacao: customer.communicate,*/
latitude: customer.latitude, longitude: customer.longitude, ibgeCode: customer.ibgeCode, latitude: customer.latitude, longitude: customer.longitude, ibgeCode: customer.ibgeCode,
addressType: customer.addressType, addressType: customer.addressType,
}; };
@@ -361,8 +361,8 @@ export class CustomerService {
city: customer.city, state: customer.state, city: customer.city, state: customer.state,
allowMessage: customer.allowMessage, cellPhone: customer.cellPhone, allowMessage: customer.allowMessage, cellPhone: customer.cellPhone,
category: customer.category, subCategory: customer.subCategory, category: customer.category, subCategory: customer.subCategory,
place: customer.place, meiocomunicacao: customer.communicate, place: customer.place, /*meiocomunicacao: customer.communicate,*/
ramo: customer.ramo, latitude: customer.latitude, longitude: customer.longitude, ramo: customer.ramo, latitude: customer.latitude, longitude: customer.longitude,
ibgeCode: customer.ibgeCode, addressType: customer.addressType, ibgeCode: customer.ibgeCode, addressType: customer.addressType,
}; };
} }
@@ -378,7 +378,7 @@ export class CustomerService {
await queryRunner.connect(); await queryRunner.connect();
await queryRunner.startTransaction(); await queryRunner.startTransaction();
try { try {
console.log("MEIO DE COMUNICACAO: " + client.meiocomunicacao); //console.log("MEIO DE COMUNICACAO: " + client.meiocomunicacao);
await queryRunner.manager await queryRunner.manager
.createQueryBuilder() .createQueryBuilder()
.update(Pcclient) .update(Pcclient)
@@ -418,13 +418,13 @@ export class CustomerService {
codmunicipio: client.codmunicipio, codmunicipio: client.codmunicipio,
codcidadecom: client.codcidade, codcidadecom: client.codcidade,
dtnasc: client.dtnasc, dtnasc: client.dtnasc,
codatv1: client.codatv1, codatv1: client.codatv1,
meiocomunicacao: client.meiocomunicacao, // meiocomunicacao: client.meiocomunicacao,
codfuncultalter: client.codfuncultalter, codfuncultalter: client.codfuncultalter,
dtultalter: client.dtultalter, dtultalter: client.dtultalter,
latitude: client.latitude, latitude: client.latitude,
longitude: client.longitude, longitude: client.longitude,
tipoendereco: client.tipoendereco tipoendereco: client.tipoendereco
}) })
.where({ codcli: client.codcli }) .where({ codcli: client.codcli })
.execute(); .execute();
@@ -434,7 +434,7 @@ export class CustomerService {
await queryRunner.rollbackTransaction(); await queryRunner.rollbackTransaction();
throw err; throw err;
} finally { } finally {
if ( queryRunner.isTransactionActive) { if (queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction(); await queryRunner.rollbackTransaction();
} }
await queryRunner.release(); await queryRunner.release();
@@ -532,13 +532,13 @@ export class CustomerService {
const connection = new Connection(connectionOptions); const connection = new Connection(connectionOptions);
const queryRunner = connection.createQueryRunner(); const queryRunner = connection.createQueryRunner();
try { try {
await connection.connect();
await queryRunner.connect();
// lets now open a new transaction: await connection.connect();
await queryRunner.startTransaction();
await queryRunner.connect();
// lets now open a new transaction:
await queryRunner.startTransaction();
let sql = `SELECT PROXNUMCLI as "proxnumcli" FROM PCCONSUM WHERE 1 = 1 FOR UPDATE`; let sql = `SELECT PROXNUMCLI as "proxnumcli" FROM PCCONSUM WHERE 1 = 1 FOR UPDATE`;
@@ -566,14 +566,14 @@ export class CustomerService {
} catch (err) { } catch (err) {
// since we have errors let's rollback changes we made // since we have errors let's rollback changes we made
if ( queryRunner.isTransactionActive) { if (queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction(); await queryRunner.rollbackTransaction();
} }
console.log(err); console.log(err);
return -1; return -1;
} finally { } finally {
if ( queryRunner.isTransactionActive) { if (queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction(); await queryRunner.rollbackTransaction();
} }
// you need to release query runner which is manually created: // you need to release query runner which is manually created:
@@ -603,7 +603,7 @@ export class CustomerService {
console.log(err); console.log(err);
throw err; throw err;
} finally { } finally {
if ( queryRunner.isTransactionActive) { if (queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction(); await queryRunner.rollbackTransaction();
} }
await queryRunner.release(); await queryRunner.release();

View File

@@ -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') @Get('stock/:storeid/:id')
@ApiOperation({ summary: 'Get product stock information' }) @ApiOperation({ summary: 'Get product stock information' })
@ApiParam({ name: 'storeid', description: 'Store ID' }) @ApiParam({ name: 'storeid', description: 'Store ID' })

View File

@@ -20,10 +20,10 @@ import Redis = require('ioredis');
@Injectable() @Injectable()
export class SalesService { export class SalesService {
constructor( constructor(
@Inject('REDIS_CLIENT') private readonly redisClient: Redis.Redis, @Inject('REDIS_CLIENT') private readonly redisClient: Redis.Redis,
private readonly customerService: CustomerService private readonly customerService: CustomerService
) {} ) { }
async GetProducts2(store: string, pageSize: number, pageNumber: number, filter: FilterProduct = null,) { async GetProducts2(store: string, pageSize: number, pageNumber: number, filter: FilterProduct = null,) {
@@ -77,14 +77,16 @@ export class SalesService {
esvlistaprodutos.LETRABASETINTOMETRICO as "letter", esvlistaprodutos.LETRABASETINTOMETRICO as "letter",
esvlistaprodutos.LINHATINTOMETRICO as "line", esvlistaprodutos.LINHATINTOMETRICO as "line",
esvlistaprodutos.LITRAGEM as "can", esvlistaprodutos.LITRAGEM as "can",
esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock" esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock",
esvlistaprodutos.TEM_PRODUTO_SIMILAR as "similar",
NVL(esvlistaprodutos.TIPO, 'SEM') as "type_campaing"
FROM ESVLISTAPRODUTOS FROM ESVLISTAPRODUTOS
WHERE 1 = 1`; WHERE 1 = 1 `;
if (filter && filter.text.length > 0) { if (filter && filter.text.length > 0) {
const description = filter.text.toUpperCase(); const description = filter.text.toUpperCase();
console.log('consultando por codigo de fabrica'); console.log('consultando por codigo de fabrica');
let products = await queryRunner.manager let products = await queryRunner.manager
.getRepository(SalesProduct) .getRepository(SalesProduct)
.createQueryBuilder('esvlistaprodutos') .createQueryBuilder('esvlistaprodutos')
@@ -127,6 +129,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line") .addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line")
.addSelect("\"esvlistaprodutos\".LITRAGEM", "can") .addSelect("\"esvlistaprodutos\".LITRAGEM", "can")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .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("UPPER(\"esvlistaprodutos\".CODFAB) LIKE '%'||REPLACE(:description, '@', '%')||'%'", { description })
.andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store })
.andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')", .andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')",
@@ -184,6 +188,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line") .addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line")
.addSelect("\"esvlistaprodutos\".LITRAGEM", "can") .addSelect("\"esvlistaprodutos\".LITRAGEM", "can")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .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("UPPER(\"esvlistaprodutos\".descricao) LIKE '%'||REPLACE(:description, '@', '%')||'%'", { description })
.andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store })
.andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')", .andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')",
@@ -260,6 +266,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line") .addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line")
.addSelect("\"esvlistaprodutos\".LITRAGEM", "can") .addSelect("\"esvlistaprodutos\".LITRAGEM", "can")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock")
.addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar")
.addSelect("\"esvlistaprodutos\".TIPO_CAMPANHA", "type_campaing")
.where("esvlistaprodutos.brand in (" + xbrands + ")") .where("esvlistaprodutos.brand in (" + xbrands + ")")
.andWhere("\"esvlistaprodutos\".URLCATEGORIA LIKE :urlCategoria||'%'", { urlCategoria: filter.urlCategory }) .andWhere("\"esvlistaprodutos\".URLCATEGORIA LIKE :urlCategoria||'%'", { urlCategoria: filter.urlCategory })
.andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store })
@@ -324,6 +332,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line") .addSelect("\"esvlistaprodutos\".LINHATINTOMETRICO", "line")
.addSelect("\"esvlistaprodutos\".LITRAGEM", "can") .addSelect("\"esvlistaprodutos\".LITRAGEM", "can")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock")
.addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar")
.addSelect("\"esvlistaprodutos\".TIPO_CAMPANHA", "type_campaing")
.where("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .where("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store })
.andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')", .andWhere("(\"esvlistaprodutos\".produto_com_reducao_preco = :produtoComReducaoPreco OR :produtoComReducaoPreco = 'N')",
{ produtoComReducaoPreco: (filter.markdown.toString() == 'true') ? 'S' : 'N' }) { produtoComReducaoPreco: (filter.markdown.toString() == 'true') ? 'S' : 'N' })
@@ -357,92 +367,92 @@ export class SalesService {
pageSize: number, pageSize: number,
pageNumber: number, pageNumber: number,
urlDepartment: string urlDepartment: string
): Promise<any> { ): Promise<any> {
const cacheKey = const cacheKey =
'searchByDepartment:' + 'searchByDepartment:' +
store + store +
'_' + '_' +
pageSize + pageSize +
'_' + '_' +
pageNumber + pageNumber +
'_' + '_' +
urlDepartment; urlDepartment;
const lockKey = 'lock:' + cacheKey; const lockKey = 'lock:' + cacheKey;
const lockTimeout = 30; // lock expira em 30 segundos const lockTimeout = 30; // lock expira em 30 segundos
try { try {
const cachedResult = await this.redisClient.get(cacheKey); const cachedResult = await this.redisClient.get(cacheKey);
if (cachedResult) { if (cachedResult) {
console.log('Retornando resultado do cache (searchByDepartment)'); console.log('Retornando resultado do cache (searchByDepartment)');
return JSON.parse(cachedResult); return JSON.parse(cachedResult);
} }
} catch (err) { } catch (err) {
console.error('Erro ao acessar o Redis no searchByDepartment:', err?.message || err); console.error('Erro ao acessar o Redis no searchByDepartment:', err?.message || err);
} }
const lockValue = Date.now() + lockTimeout * 1000 + 1; const lockValue = Date.now() + lockTimeout * 1000 + 1;
let acquiredLock: string | null = null; let acquiredLock: string | null = null;
try { try {
acquiredLock = await this.redisClient.set(lockKey, lockValue, 'NX', 'EX', lockTimeout); acquiredLock = await this.redisClient.set(lockKey, lockValue, 'NX', 'EX', lockTimeout);
} catch (err) { } catch (err) {
console.error('Erro ao adquirir lock no Redis (searchByDepartment):', err?.message || err); console.error('Erro ao adquirir lock no Redis (searchByDepartment):', err?.message || err);
} }
if (acquiredLock === 'OK') { if (acquiredLock === 'OK') {
const connectionDb = new Connection(connectionOptions); const connectionDb = new Connection(connectionOptions);
await connectionDb.connect(); await connectionDb.connect();
const queryRunner = connectionDb.createQueryRunner(); const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect(); await queryRunner.connect();
try {
if (pageSize === 0) pageSize = 50;
if (pageNumber === 0) pageNumber = 1;
const offSet = (pageNumber - 1) * pageSize;
let products = await queryRunner.manager
.getRepository(SalesProduct)
.createQueryBuilder('esvlistaprodutos')
.where('"esvlistaprodutos".urldepartamento = :urlDepartment', { urlDepartment })
.andWhere('("esvlistaprodutos".codfilial = :codfilial OR :codfilial = \'99\')', { codfilial: store })
.limit(pageSize)
.offset(offSet)
.orderBy('"esvlistaprodutos".DESCRICAO', 'ASC')
.getMany();
products = this.createListImages(products);
try { try {
await this.redisClient.set(cacheKey, JSON.stringify(products), 'EX', 3600); if (pageSize === 0) pageSize = 50;
} catch (cacheErr) { if (pageNumber === 0) pageNumber = 1;
console.error('Erro ao salvar o resultado no cache (searchByDepartment):', cacheErr?.message || cacheErr); const offSet = (pageNumber - 1) * pageSize;
let products = await queryRunner.manager
.getRepository(SalesProduct)
.createQueryBuilder('esvlistaprodutos')
.where('"esvlistaprodutos".urldepartamento = :urlDepartment', { urlDepartment })
.andWhere('("esvlistaprodutos".codfilial = :codfilial OR :codfilial = \'99\')', { codfilial: store })
.limit(pageSize)
.offset(offSet)
.orderBy('"esvlistaprodutos".DESCRICAO', 'ASC')
.getMany();
products = this.createListImages(products);
try {
await this.redisClient.set(cacheKey, JSON.stringify(products), 'EX', 3600);
} catch (cacheErr) {
console.error('Erro ao salvar o resultado no cache (searchByDepartment):', cacheErr?.message || cacheErr);
}
return products;
} catch (error) {
console.error('Erro ao executar a query no searchByDepartment:', error?.message || error);
throw error;
} finally {
await queryRunner.release();
await connectionDb.close();
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 (searchByDepartment):', lockErr?.message || lockErr);
}
} }
return products;
} catch (error) {
console.error('Erro ao executar a query no searchByDepartment:', error?.message || error);
throw error;
} finally {
await queryRunner.release();
await connectionDb.close();
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 (searchByDepartment):', lockErr?.message || lockErr);
}
}
} else { } else {
console.log('Lock não adquirido (searchByDepartment), aguardando e tentando novamente...'); console.log('Lock não adquirido (searchByDepartment), aguardando e tentando novamente...');
await this.sleep(1000); await this.sleep(1000);
return this.searchByDepartment(store, pageSize, pageNumber, urlDepartment); return this.searchByDepartment(store, pageSize, pageNumber, urlDepartment);
} }
} }
async searchBySection(store: string, pageSize: number, pageNumber: number, urlDepartment: string, urlSection: string): Promise<any> { async searchBySection(store: string, pageSize: number, pageNumber: number, urlDepartment: string, urlSection: string): Promise<any> {
const connectionDb = new Connection(connectionOptions); const connectionDb = new Connection(connectionOptions);
@@ -562,6 +572,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing")
.addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock")
.addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar")
.addSelect("\"esvlistaprodutos\".TIPO_CAMPANHA", "type_campaing")
.where("esvlistaprodutos.idProduct = :id", { id: numbers }) .where("esvlistaprodutos.idProduct = :id", { id: numbers })
.andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store })
.limit(pageSize) .limit(pageSize)
@@ -609,6 +621,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing")
.addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock")
.addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar")
.addSelect("\"esvlistaprodutos\".TIPO_CAMPANHA", "type_campaing")
.where("esvlistaprodutos.CODAUXILIAR = :id", { id: numbers }) .where("esvlistaprodutos.CODAUXILIAR = :id", { id: numbers })
.andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store }) .andWhere("(\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99')", { codfilial: store })
.limit(pageSize) .limit(pageSize)
@@ -658,6 +672,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing")
.addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .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("UPPER(esvlistaprodutos.CODFAB) like REPLACE(:description, '@', '%')", { description })
.andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store })
.limit(pageSize) .limit(pageSize)
@@ -704,6 +720,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing")
.addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .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("UPPER(esvlistaprodutos.DESCRICAO) like REPLACE(:description, '@', '%')", { description })
.andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial OR :codfilial = '99'", { codfilial: store })
.limit(pageSize) .limit(pageSize)
@@ -773,6 +791,8 @@ export class SalesService {
.addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing") .addSelect("\"esvlistaprodutos\".PRODUTO_EM_CAMPANHA", "compaing")
.addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base") .addSelect("\"esvlistaprodutos\".BASETINTOMETRICO", "base")
.addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock") .addSelect("\"esvlistaprodutos\".QUANTIDADE_ESTOQUE_GERAL", "full_stock")
.addSelect("\"esvlistaprodutos\".TEM_PRODUTO_SIMILAR", "similar")
.addSelect("\"esvlistaprodutos\".TIPO_CAMPANHA", "type_campaing")
.where("esvlistaprodutos.idProduct = :id", { id: id }) .where("esvlistaprodutos.idProduct = :id", { id: id })
.andWhere("\"esvlistaprodutos\".codfilial = :codfilial", { codfilial: store }) .andWhere("\"esvlistaprodutos\".codfilial = :codfilial", { codfilial: store })
.orderBy("REPLACE(\"esvlistaprodutos\".DESCRICAO,'#', '')", "ASC") .orderBy("REPLACE(\"esvlistaprodutos\".DESCRICAO,'#', '')", "ASC")
@@ -834,6 +854,8 @@ export class SalesService {
,esvlistaprodutos.PRODUTO_EM_CAMPANHA as "compaing" ,esvlistaprodutos.PRODUTO_EM_CAMPANHA as "compaing"
,esvlistaprodutos.BASETINTOMETRICO as "base" ,esvlistaprodutos.BASETINTOMETRICO as "base"
,esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock" ,esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL as "full_stock"
,esvlistaprodutos.TEM_PRODUTO_SIMILAR as "similar"
,esvlistaprodutos.TIPO_CAMPANHA as "type_campaing"
FROM ESVLISTAPRODUTOS, ESTCOMPREJUNTO FROM ESVLISTAPRODUTOS, ESTCOMPREJUNTO
WHERE ESVLISTAPRODUTOS.CODPROD = ESTCOMPREJUNTO.CODPROD WHERE ESVLISTAPRODUTOS.CODPROD = ESTCOMPREJUNTO.CODPROD
AND ESTCOMPREJUNTO.CODPRODVENDA = ${id} AND ESTCOMPREJUNTO.CODPRODVENDA = ${id}
@@ -851,6 +873,68 @@ 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"
,esvlistaprodutos.TEM_PRODUTO_SIMILAR as "similar"
,esvlistaprodutos.TIPO_CAMPANHA as "type_campaing"
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) { async GetStocks(storeId: string, id: number) {
const connectionDb = new Connection(connectionOptions); const connectionDb = new Connection(connectionOptions);
await connectionDb.connect(); await connectionDb.connect();
@@ -874,9 +958,9 @@ export class SalesService {
WHERE ESVESTOQUEVENDA.CODPROD = ${id} WHERE ESVESTOQUEVENDA.CODPROD = ${id}
AND ESVESTOQUEVENDA.CODFILIAL = PCFILIAL.CODIGO AND ESVESTOQUEVENDA.CODFILIAL = PCFILIAL.CODIGO
ORDER BY TO_NUMBER(ESVESTOQUEVENDA.CODFILIAL) `; ORDER BY TO_NUMBER(ESVESTOQUEVENDA.CODFILIAL) `;
const stock = await queryRunner.query(sql); const stock = await queryRunner.query(sql);
// return await queryRunner.manager // return await queryRunner.manager
// .getRepository(Stock) // .getRepository(Stock)
// .createQueryBuilder('esvestoquevenda') // .createQueryBuilder('esvestoquevenda')
@@ -1126,71 +1210,71 @@ export class SalesService {
const cacheKey = 'departments'; const cacheKey = 'departments';
const lockKey = 'departments_lock'; const lockKey = 'departments_lock';
const lockTimeout = 30; const lockTimeout = 30;
try { // try {
const cachedDepartments = await this.redisClient.get(cacheKey); // const cachedDepartments = await this.redisClient.get(cacheKey);
if (cachedDepartments) { // if (cachedDepartments) {
console.log('Buscando departamentos no Redis'); // console.log('Buscando departamentos no Redis');
return JSON.parse(cachedDepartments); // return JSON.parse(cachedDepartments);
} // }
} catch (err) { // } catch (err) {
console.error('Erro ao acessar o Redis (cache):', err); // console.error('Erro ao acessar o Redis (cache):', err);
} // }
const lockValue = Date.now() + lockTimeout * 1000 + 1; const lockValue = Date.now() + lockTimeout * 1000 + 1;
const acquiredLock = await this.redisClient.set(lockKey, lockValue, 'NX', 'EX', lockTimeout); const acquiredLock = await this.redisClient.set(lockKey, lockValue, 'NX', 'EX', lockTimeout);
if (acquiredLock === 'OK') { if (acquiredLock === 'OK') {
const connectionDb = new Connection(connectionOptions); const connectionDb = new Connection(connectionOptions);
await connectionDb.connect(); await connectionDb.connect();
const queryRunner = connectionDb.createQueryRunner(); const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect(); await queryRunner.connect();
try {
const departments = await queryRunner.manager
.getRepository(Esvdepartamento)
.createQueryBuilder('Esvdepartamento')
.innerJoinAndSelect('Esvdepartamento.secoes', 'secoes')
.innerJoinAndSelect('secoes.categorias', 'categorias')
.where('"Esvdepartamento".tituloecommerce is not null')
.orderBy('"Esvdepartamento".tituloecommerce, "secoes".tituloecommerce, "categorias".tituloecommerce')
.getMany();
try { try {
await this.redisClient.set(cacheKey, JSON.stringify(departments), 'EX', 3600); const departments = await queryRunner.manager
} catch (cacheErr) { .getRepository(Esvdepartamento)
console.error('Erro ao armazenar dados no Redis:', cacheErr); .createQueryBuilder('Esvdepartamento')
.innerJoinAndSelect('Esvdepartamento.secoes', 'secoes')
.leftJoinAndSelect('secoes.categorias', 'categorias')
.where('"Esvdepartamento".tituloecommerce is not null')
.orderBy('"Esvdepartamento".tituloecommerce, "secoes".tituloecommerce, "categorias".tituloecommerce')
.getMany();
try {
await this.redisClient.set(cacheKey, JSON.stringify(departments), 'EX', 3600);
} catch (cacheErr) {
console.error('Erro ao armazenar dados no Redis:', cacheErr);
}
return departments;
} catch (dbErr) {
console.error('Erro na consulta ao banco de dados:', dbErr);
throw dbErr;
} finally {
await queryRunner.release();
await connectionDb.close();
// Libera o lock somente se ainda for o proprietário
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:', lockErr);
}
} }
return departments;
} catch (dbErr) {
console.error('Erro na consulta ao banco de dados:', dbErr);
throw dbErr;
} finally {
await queryRunner.release();
await connectionDb.close();
// Libera o lock somente se ainda for o proprietário
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:', lockErr);
}
}
} else { } else {
console.log('Lock não adquirido, aguardando a liberação...'); console.log('Lock não adquirido, aguardando a liberação...');
await this.sleep(1000); // aguarda 1 segundo await this.sleep(1000); // aguarda 1 segundo
return this.getDepartments(); return this.getDepartments();
} }
} }
private sleep(ms: number): Promise<void> { private sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
async getCategory() { async getCategory() {
@@ -1217,15 +1301,15 @@ export class SalesService {
async searchProduct2(store: string, pageSize: number, pageNumber: number, filter: FilterProduct) { async searchProduct2(store: string, pageSize: number, pageNumber: number, filter: FilterProduct) {
console.log('searchProduct2'); console.log('searchProduct2');
const cacheKey = `searchProduct2:${store}:${pageSize}:${pageNumber}:${JSON.stringify(filter)}`; const cacheKey = `searchProduct2:${store}:${pageSize}:${pageNumber}:${JSON.stringify(filter)}`;
const cachedProducts = await this.redisClient.get(cacheKey); const cachedProducts = await this.redisClient.get(cacheKey);
if (cachedProducts) { if (cachedProducts) {
console.log('Retornando produtos do cache'); console.log('Retornando produtos do cache');
return JSON.parse(cachedProducts); return JSON.parse(cachedProducts);
} }
const sql = 'SELECT esvlistaprodutos.CODPROD "idProduct" ' + const sql = 'SELECT esvlistaprodutos.CODPROD "idProduct" ' +
` ,esvlistaprodutos.SEQ "seq" ` + ` ,esvlistaprodutos.SEQ "seq" ` +
' ,esvlistaprodutos.DESCRICAO "smallDescription" ' + ' ,esvlistaprodutos.DESCRICAO "smallDescription" ' +
@@ -1265,9 +1349,11 @@ export class SalesService {
' ,esvlistaprodutos.LINHATINTOMETRICO "line" ' + ' ,esvlistaprodutos.LINHATINTOMETRICO "line" ' +
' ,esvlistaprodutos.LITRAGEM "can" ' + ' ,esvlistaprodutos.LITRAGEM "can" ' +
' ,esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL "full_stock" ' + ' ,esvlistaprodutos.QUANTIDADE_ESTOQUE_GERAL "full_stock" ' +
' ,esvlistaprodutos.TEM_PRODUTO_SIMILAR "similar" ' +
' ,esvlistaprodutos.TIPO_CAMPANHA "type_campaing" ' +
' FROM esvlistaprodutos ' + ' FROM esvlistaprodutos ' +
' WHERE 1 = 1'; ' WHERE 1 = 1 ';
let where = ""; let where = "";
if (filter.text != null) { if (filter.text != null) {
where += ` AND ( ESF_REMOVE_ACENTUACAO(UPPER(esvlistaprodutos.descricao)) LIKE ` + where += ` AND ( ESF_REMOVE_ACENTUACAO(UPPER(esvlistaprodutos.descricao)) LIKE ` +
@@ -1287,7 +1373,7 @@ export class SalesService {
where += ` AND (esvlistaprodutos.produto_em_campanha = '${(filter.offers ? 'D' : 'N')}' OR '${(filter.offers ? '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_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') `; where += ` AND (esvlistaprodutos.produto_em_promocao = '${(filter.promotion ? 'S' : 'N')}' OR '${(filter.promotion ? 'S' : 'N')}' = 'N') `;
if (filter.onlyWithStock) { if (filter.onlyWithStock) {
if (filter.storeStock == '' || filter.storeStock == null) { if (filter.storeStock == '' || filter.storeStock == null) {
where += ` AND EXISTS( SELECT P.CODPROD FROM ESVLISTAPRODUTOS P ` + where += ` AND EXISTS( SELECT P.CODPROD FROM ESVLISTAPRODUTOS P ` +
@@ -1299,15 +1385,15 @@ export class SalesService {
` AND P.ESTOQUE_DISP_LOJA > 0 ) `; ` AND P.ESTOQUE_DISP_LOJA > 0 ) `;
} }
} }
if (filter.percentOffMin > 0) { if (filter.percentOffMin > 0) {
where += ` AND esvlistaprodutos.PERCENTUALDESCONTO >= ${filter.percentOffMin}`; where += ` AND esvlistaprodutos.PERCENTUALDESCONTO >= ${filter.percentOffMin}`;
} }
if (filter.percentOffMax > 0) { if (filter.percentOffMax > 0) {
where += ` AND esvlistaprodutos.PERCENTUALDESCONTO <= ${filter.percentOffMax}`; where += ` AND esvlistaprodutos.PERCENTUALDESCONTO <= ${filter.percentOffMax}`;
} }
let xbrands = ''; let xbrands = '';
if (filter && filter.brands && filter.brands.length > 0) { if (filter && filter.brands && filter.brands.length > 0) {
const brands = filter.brands; const brands = filter.brands;
@@ -1320,24 +1406,24 @@ export class SalesService {
}); });
where += ` AND esvlistaprodutos.nomemarca in ( ${xbrands} )`; where += ` AND esvlistaprodutos.nomemarca in ( ${xbrands} )`;
} }
const orderBy = `ORDER BY esvlistaprodutos.${(filter.orderBy == null) ? 'DESCRICAO' : filter.orderBy}`; const orderBy = `ORDER BY esvlistaprodutos.${(filter.orderBy == null) ? 'DESCRICAO' : filter.orderBy}`;
const skipReg = ((pageNumber - 1) * pageSize); const skipReg = ((pageNumber - 1) * pageSize);
const pagination = ` OFFSET ${skipReg} ROWS FETCH NEXT ${pageSize} ROWS ONLY`; const pagination = ` OFFSET ${skipReg} ROWS FETCH NEXT ${pageSize} ROWS ONLY`;
const connectionDb = new Connection(connectionOptions); const connectionDb = new Connection(connectionOptions);
await connectionDb.connect(); await connectionDb.connect();
const queryRunner = connectionDb.createQueryRunner(); const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect(); await queryRunner.connect();
try { try {
let products = await queryRunner.manager.query(sql + where + orderBy + pagination) as SalesProduct[]; let products = await queryRunner.manager.query(sql + where + orderBy + pagination) as SalesProduct[];
products = this.createListImages(products); products = this.createListImages(products);
console.log("Total de produtos: " + products.length); console.log("Total de produtos: " + products.length);
await this.redisClient.set(cacheKey, JSON.stringify(products), 'EX', 3600); await this.redisClient.set(cacheKey, JSON.stringify(products), 'EX', 3600);
return products; return products;
} catch (err) { } catch (err) {
console.log(err); console.log(err);
@@ -1347,7 +1433,7 @@ export class SalesService {
await connectionDb.close(); await connectionDb.close();
} }
} }
async calculateDeliveryTax(cartId: string, ibgeCode: string) { async calculateDeliveryTax(cartId: string, ibgeCode: string) {
@@ -1402,7 +1488,7 @@ export class SalesService {
WHERE ID = '${cartId}'`; WHERE ID = '${cartId}'`;
await queryRunner.manager await queryRunner.manager
.query(sql); .query(sql);
await queryRunner.commitTransaction(); await queryRunner.commitTransaction();
} catch (err) { } catch (err) {
await queryRunner.rollbackTransaction(); await queryRunner.rollbackTransaction();
@@ -1457,26 +1543,26 @@ export class SalesService {
await queryRunner.release(); await queryRunner.release();
await connectionDb.close(); await connectionDb.close();
} }
} }
async getPlacesInterior() { async getPlacesInterior() {
const connectionDb = new Connection(connectionOptions); const connectionDb = new Connection(connectionOptions);
await connectionDb.connect(); await connectionDb.connect();
const queryRunner = connectionDb.createQueryRunner(); const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect(); await queryRunner.connect();
try { try {
const sql = ` const sql = `
SELECT DISTINCT ESTPREVENTREGAPRACA.CODPRACA, PCPRACA.PRACA SELECT DISTINCT ESTPREVENTREGAPRACA.CODPRACA, PCPRACA.PRACA
FROM ESTPREVENTREGAPRACA, PCPRACA FROM ESTPREVENTREGAPRACA, PCPRACA
WHERE ESTPREVENTREGAPRACA.CODPRACA = PCPRACA.CODPRACA WHERE ESTPREVENTREGAPRACA.CODPRACA = PCPRACA.CODPRACA
`; `;
const places = await queryRunner.query(sql); const places = await queryRunner.query(sql);
return places; return places;
} catch (err) { } catch (err) {
throw err; throw err;
@@ -1485,7 +1571,7 @@ export class SalesService {
await connectionDb.close(); await connectionDb.close();
} }
} }
async getDeliveryTime(saleDate: string, invoiceStoreId: string, placeId: string, cartId: string) { async getDeliveryTime(saleDate: string, invoiceStoreId: string, placeId: string, cartId: string) {
const connection = new Connection(connectionOptions); const connection = new Connection(connectionOptions);
@@ -1494,7 +1580,7 @@ export class SalesService {
await queryRunner.connect(); await queryRunner.connect();
try { try {
const sql = `SELECT ESF_CALCULAR_PRAZO_ENTREGA_PROGRAMADA(TO_DATE('${saleDate}', 'DD-MM-YYYY'), ${invoiceStoreId}, ${placeId}, '${cartId}') AS "days" FROM DUAL`; const sql = `SELECT ESF_CALCULAR_PRAZO_ENTREGA_PROGRAMADA(TO_DATE('${saleDate}', 'DD-MM-YYYY'), ${invoiceStoreId}, ${placeId}, '${cartId}') AS "days" FROM DUAL`;
// const sql = `SELECT ESF_CALCULAR_PRAZO_ENTREGA(TO_DATE('${saleDate}', 'DD-MM-YYYY')) AS "days" FROM DUAL`; // const sql = `SELECT ESF_CALCULAR_PRAZO_ENTREGA(TO_DATE('${saleDate}', 'DD-MM-YYYY')) AS "days" FROM DUAL`;
const timeDays = await queryRunner.query(sql); const timeDays = await queryRunner.query(sql);
const sqlRetiraPosterior = `SELECT ( PROXIMO_DIA_UTIL(TO_DATE('${saleDate}', 'DD-MM-YYYY'), '4') - TRUNC(SYSDATE) ) AS "days" FROM DUAL`; const sqlRetiraPosterior = `SELECT ( PROXIMO_DIA_UTIL(TO_DATE('${saleDate}', 'DD-MM-YYYY'), '4') - TRUNC(SYSDATE) ) AS "days" FROM DUAL`;