impl redis cloud

This commit is contained in:
JurTI-BR
2025-04-01 16:42:05 -03:00
parent f8bea4114f
commit 28a1cee876
14 changed files with 819 additions and 6 deletions

View File

@@ -0,0 +1,208 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
exports.__esModule = true;
exports.OrdersService = void 0;
var common_1 = require("@nestjs/common");
var redis_client_adapter_provider_1 = require("src/core/configs/cache/redis-client.adapter.provider");
var cache_util_1 = require("src/shared/cache.util");
var crypto_1 = require("crypto");
var OrdersService = /** @class */ (function () {
function OrdersService(ordersRepository, redisClient) {
this.ordersRepository = ordersRepository;
this.redisClient = redisClient;
this.TTL_ORDERS = 60 * 10; // 10 minutos
this.TTL_INVOICE = 60 * 60; // 1 hora
this.TTL_ITENS = 60 * 10; // 10 minutos
}
/**
* Buscar pedidos com cache baseado nos filtros
*/
OrdersService.prototype.findOrders = function (query) {
return __awaiter(this, void 0, void 0, function () {
var key;
var _this = this;
return __generator(this, function (_a) {
key = "orders:query:" + this.hashObject(query);
return [2 /*return*/, cache_util_1.getOrSetCache(this.redisClient, key, this.TTL_ORDERS, function () { return _this.ordersRepository.findOrders(query); })];
});
});
};
/**
* Buscar nota fiscal por chave NFe com cache
*/
OrdersService.prototype.findInvoice = function (chavenfe) {
return __awaiter(this, void 0, Promise, function () {
var key;
var _this = this;
return __generator(this, function (_a) {
key = "orders:invoice:" + chavenfe;
return [2 /*return*/, cache_util_1.getOrSetCache(this.redisClient, key, this.TTL_INVOICE, function () { return __awaiter(_this, void 0, void 0, function () {
var invoiceData, invoice;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.ordersRepository.findInvoice(chavenfe)];
case 1:
invoiceData = _a.sent();
invoice = {
storeId: invoiceData.storeId,
invoiceDate: new Date(invoiceData.invoiceDate),
orderId: invoiceData.orderId,
invoiceId: invoiceData.invoiceId,
transactionId: invoiceData.transactionId,
customerId: invoiceData.customerId,
customer: invoiceData.customer,
sellerId: invoiceData.sellerId,
sellerName: invoiceData.sellerName,
itensQt: invoiceData.itensQt,
itens: invoiceData.itens
};
return [2 /*return*/, invoice];
}
});
}); })];
});
});
};
/**
* Buscar itens de pedido com cache
*/
OrdersService.prototype.getItens = function (orderId) {
return __awaiter(this, void 0, Promise, function () {
var key;
var _this = this;
return __generator(this, function (_a) {
key = "orders:itens:" + orderId;
return [2 /*return*/, cache_util_1.getOrSetCache(this.redisClient, key, this.TTL_ITENS, function () { return __awaiter(_this, void 0, void 0, function () {
var itens;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.ordersRepository.getItens(orderId)];
case 1:
itens = _a.sent();
return [2 /*return*/, itens.map(function (item) { return ({
productId: Number(item.productId),
description: item.description,
pacth: item.pacth,
color: item.color,
stockId: Number(item.stockId),
quantity: Number(item.quantity),
salePrice: Number(item.salePrice),
deliveryType: item.deliveryType,
total: Number(item.total),
weight: Number(item.weight),
department: item.department,
brand: item.brand
}); })];
}
});
}); })];
});
});
};
OrdersService.prototype.getCutItens = function (orderId) {
return __awaiter(this, void 0, Promise, function () {
var itens;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.ordersRepository.getCutItens(orderId)];
case 1:
itens = _a.sent();
return [2 /*return*/, itens.map(function (item) { return ({
productId: Number(item.productId),
description: item.description,
pacth: item.pacth,
stockId: Number(item.stockId),
saleQuantity: Number(item.saleQuantity),
cutQuantity: Number(item.cutQuantity),
separedQuantity: Number(item.separedQuantity)
}); })];
}
});
});
};
OrdersService.prototype.getOrderDelivery = function (orderId) {
return __awaiter(this, void 0, Promise, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.ordersRepository.getOrderDelivery(orderId)];
});
});
};
OrdersService.prototype.getTransfer = function (orderId) {
return __awaiter(this, void 0, Promise, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.ordersRepository.getTransfer(orderId)];
});
});
};
OrdersService.prototype.getStatusOrder = function (orderId) {
return __awaiter(this, void 0, Promise, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.ordersRepository.getStatusOrder(orderId)];
});
});
};
/**
* Utilitário para gerar hash MD5 de objetos
*/
OrdersService.prototype.hashObject = function (obj) {
var str = JSON.stringify(obj, Object.keys(obj).sort());
return crypto_1.createHash('md5').update(str).digest('hex');
};
OrdersService.prototype.createInvoiceCheck = function (invoice) {
return __awaiter(this, void 0, Promise, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.ordersRepository.createInvoiceCheck(invoice)];
});
});
};
OrdersService = __decorate([
common_1.Injectable(),
__param(1, common_1.Inject(redis_client_adapter_provider_1.RedisClientToken))
], OrdersService);
return OrdersService;
}());
exports.OrdersService = OrdersService;

View File

@@ -8,6 +8,12 @@ import { IRedisClient } from 'src/core/configs/cache/IRedisClient';
import { RedisClientToken } from 'src/core/configs/cache/redis-client.adapter.provider';
import { getOrSetCache } from 'src/shared/cache.util';
import { createHash } from 'crypto';
import { OrderDeliveryDto } from '../dto/OrderDeliveryDto';
import { OrderTransferDto } from '../dto/OrderTransferDto';
import { OrderStatusDto } from '../dto/OrderStatusDto';
import { InvoiceCheckDto } from '../dto/invoice-check.dto';
@Injectable()
export class OrdersService {
@@ -101,7 +107,17 @@ export class OrdersService {
}));
}
async getOrderDelivery(orderId: string): Promise<OrderDeliveryDto> {
return this.ordersRepository.getOrderDelivery(orderId);
}
async getTransfer(orderId: number): Promise<OrderTransferDto[] | null> {
return this.ordersRepository.getTransfer(orderId);
}
async getStatusOrder(orderId: number): Promise<OrderStatusDto[] | null> {
return this.ordersRepository.getStatusOrder(orderId);
}
/**
* Utilitário para gerar hash MD5 de objetos
*/
@@ -110,4 +126,9 @@ export class OrdersService {
return createHash('md5').update(str).digest('hex');
}
async createInvoiceCheck(invoice: InvoiceCheckDto): Promise<{ message: string }> {
return this.ordersRepository.createInvoiceCheck(invoice);
}
}

View File

@@ -1,6 +1,8 @@
import {
Controller,
Get,
Post,
Body,
Param,
Query,
UsePipes,
@@ -18,6 +20,13 @@ import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
import { InvoiceDto } from '../dto/find-invoice.dto';
import { OrderItemDto } from "../dto/OrderItemDto";
import { CutItemDto } from '../dto/CutItemDto';
import { OrderDeliveryDto } from '../dto/OrderDeliveryDto';
import { OrderTransferDto } from '../dto/OrderTransferDto';
import { OrderStatusDto } from '../dto/OrderStatusDto';
import { InvoiceCheckDto } from '../dto/invoice-check.dto';
@ApiTags('Orders')
@@ -73,4 +82,60 @@ export class OrdersController {
);
}
}
@Get('delivery/:orderId')
@ApiOperation({ summary: 'Busca dados de entrega do pedido' })
@UsePipes(new ValidationPipe({ transform: true }))
async getOrderDelivery(@Param('orderId') orderId: string): Promise<OrderDeliveryDto | null> {
try {
return await this.ordersService.getOrderDelivery(orderId);
} catch (error) {
throw new HttpException(
error.message || 'Erro ao buscar dados de entrega',
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
@Get('transfer/:orderId')
@ApiOperation({ summary: 'Consulta pedidos de transferência' })
@UsePipes(new ValidationPipe({ transform: true }))
async getTransfer(@Param('orderId') orderId: number): Promise<OrderTransferDto[] | null> {
try {
return await this.ordersService.getTransfer(orderId);
} catch (error) {
throw new HttpException(
error.message || 'Erro ao buscar transferências do pedido',
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
@Get('status/:orderId')
@ApiOperation({ summary: 'Consulta status do pedido' })
@UsePipes(new ValidationPipe({ transform: true }))
async getStatusOrder(@Param('orderId') orderId: number): Promise<OrderStatusDto[] | null> {
try {
return await this.ordersService.getStatusOrder(orderId);
} catch (error) {
throw new HttpException(
error.message || 'Erro ao buscar status do pedido',
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
@Post('invoice/check')
@ApiOperation({ summary: 'Cria conferência de nota fiscal' })
@UsePipes(new ValidationPipe({ transform: true }))
async createInvoiceCheck(@Body() invoice: InvoiceCheckDto): Promise<{ message: string }> {
try {
return await this.ordersService.createInvoiceCheck(invoice);
} catch (error) {
throw new HttpException(
error.message || 'Erro ao salvar conferência',
error.status || HttpStatus.INTERNAL_SERVER_ERROR
);
}
}
}

View File

@@ -0,0 +1,28 @@
export class OrderDeliveryDto {
placeId: number;
placeName: string;
street: string;
addressNumber: string;
bairro: string;
city: string;
state: string;
addressComplement: string;
cep: string;
commentOrder1: string;
commentOrder2: string;
commentDelivery1: string;
commentDelivery2: string;
commentDelivery3: string;
commentDelivery4: string;
shippimentId: number;
shippimentDate: Date;
shippimentComment: string;
place: string;
driver: string;
car: string;
closeDate: Date;
separatorName: string;
confName: string;
releaseDate: Date;
}

View File

@@ -0,0 +1,8 @@
export class OrderStatusDto {
orderId: number;
status: string;
statusDate: Date;
userName: string;
comments: string | null;
}

View File

@@ -0,0 +1,13 @@
export class OrderTransferDto {
orderId: number;
transferDate: Date;
invoiceId: number;
transactionId: number;
oldShipment: number;
newShipment: number;
transferText: string;
cause: string;
userName: string;
program: string;
}

View File

@@ -0,0 +1,7 @@
export class InvoiceCheckItemDto {
productId: number;
seq: number;
qt: number;
confDate: string;
}

View File

@@ -0,0 +1,11 @@
import { InvoiceCheckItemDto } from './invoice-check-item.dto';
export class InvoiceCheckDto {
transactionId: number;
storeId: number;
invoiceId: number;
startDate: string;
endDate: string;
userId: number;
itens: InvoiceCheckItemDto[];
}

View File

@@ -4,6 +4,11 @@ import { InjectDataSource } from "@nestjs/typeorm";
import { FindOrdersDto } from "../dto/find-orders.dto";
import { OrderItemDto } from "../dto/OrderItemDto";
import { CutItemDto } from '../dto/CutItemDto';
import { OrderDeliveryDto } from '../dto/OrderDeliveryDto';
import { OrderTransferDto } from '../dto/OrderTransferDto';
import { OrderStatusDto } from '../dto/OrderStatusDto';
import { InvoiceCheckDto } from '../dto/invoice-check.dto';
@@ -365,4 +370,270 @@ export class OrdersRepository {
await queryRunner.release();
}
}
async getOrderDelivery(orderId: string): Promise<OrderDeliveryDto | null> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `
SELECT PCPRACA.CODPRACA as "placeId",
PCPRACA.PRACA as "placeName",
NVL(ENDENT.ENDERENT, PCCLIENT.ENDERENT) as "street",
NVL(ENDENT.NUMEROENT, PCCLIENT.NUMEROENT) as "addressNumber",
NVL(ENDENT.BAIRROENT, PCCLIENT.BAIRROENT) as "bairro",
NVL(ENDENT.MUNICENT, PCCLIENT.MUNICENT) as "city",
NVL(ENDENT.ESTENT, PCCLIENT.ESTENT) as "state",
NVL(ENDENT.COMPLEMENTOENT, PCCLIENT.COMPLEMENTOENT) as "addressComplement",
NVL(ENDENT.CEPENT, PCCLIENT.CEPENT) as "cep",
PCPEDC.OBS1 as "commentOrder1",
PCPEDC.OBS2 as "commentOrder2",
PCPEDC.OBSENTREGA1 as "commentDelivery1",
PCPEDC.OBSENTREGA2 as "commentDelivery2",
PCPEDC.OBSENTREGA3 as "commentDelivery3",
PCPEDC.OBSENTREGA4 as "commentDelivery4",
PCPEDC.NUMCAR as "shippimentId",
PCCARREG.DTSAIDA as "shippimentDate",
PCCARREG.DESTINO as "shippimentComment",
PCROTAEXP.DESCRICAO as "place",
PCEMPR.MATRICULA||'-'||PCEMPR.NOME as "driver",
PCVEICUL.PLACA||' - '||PCVEICUL.DESCRICAO as "car",
CASE WHEN PCCARREG.DTFECHA < PCCARREG.DTSAIDA THEN NULL ELSE PCCARREG.DTFECHA END as "closeDate",
SEPARADOR.NOME as "separatorName",
CONFERENTE.NOME as "confName",
PCPEDC.DTLIBERA as "releaseDate"
FROM PCPEDC, PCCLIENT, PCPRACA, PCCLIENTENDENT ENDENT, PCCARREG, PCVEICUL, PCEMPR, PCROTAEXP,
PCEMPR SEPARADOR, PCEMPR CONFERENTE
WHERE NVL(ENDENT.CODPRACAENT, PCPEDC.CODPRACA) = PCPRACA.CODPRACA
AND PCPEDC.CODCLI = PCCLIENT.CODCLI
AND PCPEDC.CODENDENTCLI = ENDENT.CODENDENTCLI (+)
AND PCPEDC.CODCLI = ENDENT.CODCLI (+)
AND PCPEDC.NUMCAR = PCCARREG.NUMCAR (+)
AND PCCARREG.CODMOTORISTA = PCEMPR.MATRICULA (+)
AND PCCARREG.CODVEICULO = PCVEICUL.CODVEICULO (+)
AND PCCARREG.CODROTAPRINC = PCROTAEXP.CODROTA (+)
AND PCPEDC.CODFUNCSEP = SEPARADOR.MATRICULA (+)
AND PCPEDC.CODFUNCCONF = CONFERENTE.MATRICULA (+)
AND PCPEDC.NUMPED = ${orderId}
`;
const result = await queryRunner.manager.query(sql);
return result.length > 0 ? result[0] : null;
} finally {
await queryRunner.release();
}
}
async getTransfer(orderId: number): Promise<OrderTransferDto[] | null> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `
SELECT
L.NUMPED as "orderId",
L.DTTRANSF as "transferDate",
L.NUMNOTA as "invoiceId",
L.NUMTRANSVENDA as "transactionId",
L.NUMCARANTERIOR as "oldShipment",
L.NUMCARATUAL as "newShipment",
L.MOTIVOTRANSF as "transferText",
L.codmotivo || '-' || PCTABDEV.MOTIVO as "cause",
L.codfunctransf || '-' || PCEMPR.NOME as "userName",
L.rotinatransf as "program"
FROM PCLOGTRANSFNFCARREG L
LEFT JOIN PCTABDEV ON L.CODMOTIVO = PCTABDEV.coddevol
LEFT JOIN PCEMPR ON L.CODFUNCTRANSF = PCEMPR.MATRICULA
WHERE L.NUMTRANSVENDA IN (
SELECT NUMTRANSVENDA FROM PCPEDC WHERE PCPEDC.NUMPED = ${orderId}
)
`;
const result = await queryRunner.manager.query(sql);
return result.length > 0 ? result : null;
} finally {
await queryRunner.release();
}
}
async getStatusOrder(orderId: number): Promise<OrderStatusDto[] | null> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT pcpedc.numped AS "orderId",
'Digitação pedido' AS "status",
TO_DATE (TO_CHAR(pcpedc.data, 'DD/MM/YYYY') || ' ' || pcpedc.hora || ':' || pcpedc.minuto,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pcpedc.codemitente || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId} AND pcpedc.codemitente = pcempr.matricula(+)
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Montagem de carga' AS "status",
TO_DATE (
TO_CHAR(pccarreg.datamon, 'DD/MM/YYYY')
|| ' '
|| pccarreg.horamon
|| ':'
|| pccarreg.minutomon,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pccarreg.codfuncmon || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr, pccarreg
WHERE pcpedc.numped = ${orderId}
AND pccarreg.codfuncmon = pcempr.matricula(+)
AND pcpedc.numcar = pccarreg.numcar
AND pcpedc.numcar > 0
AND pccarreg.datamon is not null
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Emissão do mapa' AS "status",
CASE WHEN PCPEDC.DTEMISSAOMAPA IS NOT NULL THEN
TO_DATE (
TO_CHAR(pcpedc.dtemissaomapa, 'DD/MM/YYYY')
|| ' '
|| NVL(pcpedc.horaemissaomapa, '00')
|| ':'
|| nvl(pcpedc.minutoemissaomapa, '01'),
'DD/MM/YYYY HH24:MI') ELSE NULL END
AS "statusDate",
pcpedc.codfuncemissaomapa || '-' || pcempr.nome AS "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncemissaomapa = pcempr.matricula(+)
AND PCPEDC.DTEMISSAOMAPA IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Inicio de Separação' AS "status",
pcpedc.dtinicialsep as "statusDate",
pcpedc.codfuncsep || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncsep = pcempr.matricula(+)
AND PCPEDC.dtinicialsep IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Fim de Separação' AS "status",
pcpedc.dtfinalsep as "statusDate",
pcpedc.codfuncsep || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId} AND pcpedc.codfuncsep = pcempr.matricula(+)
and pcpedc.dtfinalsep is not null
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Inicio conferência' AS "status",
pcpedc.dtinicialcheckout AS "statusDate",
pcpedc.codfuncconf || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncconf = pcempr.matricula(+)
AND pcpedc.dtinicialcheckout IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Fim conferência' AS "status",
pcpedc.dtfinalcheckout AS "statusDate",
pcpedc.codfuncconf || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncconf = pcempr.matricula(+)
AND pcpedc.dtfinalcheckout IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Faturamento' AS "status",
TO_DATE (
TO_CHAR(pcpedc.dtfat, 'DD/MM/YYYY') || ' ' || pcpedc.horafat || ':' || pcpedc.minutofat,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pcempr.matricula || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr, pccarreg, pcnfsaid
WHERE pcpedc.numped = ${orderId}
AND pcpedc.numcar = pccarreg.numcar
and pcpedc.numtransvenda = pcnfsaid.numtransvenda
AND nvl(pcnfsaid.codemitente, decode(pcpedc.numcar,0,-1,pccarreg.codfuncfat)) = pcempr.matricula(+)
AND pcpedc.dtfat IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Entrega' AS "status",
pcnfsaid.dtcanhoto AS "statusDate",
CASE WHEN PCNFSAID.NUMCAR > 0 THEN
pcnfsaid.codfunccanhoto || '-' || pcempr.nome
ELSE '' END "userName"
,NULL as "comments"
FROM pcpedc, pcnfsaid, pcempr, pccarreg
WHERE pcpedc.numped = ${orderId}
AND pcpedc.numtransvenda = pcnfsaid.numtransvenda
AND pcnfsaid.numcar = pccarreg.numcar (+)
AND pcnfsaid.codfunccanhoto = pcempr.matricula(+)
AND pcnfsaid.dtcanhoto IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Transf entre carregamento' AS "status",
pclogtransfnfcarreg.dttransf AS "statusDate",
pclogtransfnfcarreg.codfunctransf || '-' || pcempr.nome "userName",
'ORIG: '||pclogtransfnfcarreg.numcaranterior || ' ->
DEST.: ' ||pclogtransfnfcarreg.numcaratual as "comments"
FROM pclogtransfnfcarreg, pcpedc, pcempr
WHERE pclogtransfnfcarreg.numnota = pcpedc.numnota (+)
AND pcpedc.numped = ${orderId}
AND pclogtransfnfcarreg.codfunctransf = pcempr.matricula(+)
ORDER BY 3`;
const result = await queryRunner.manager.query(sql);
return result.length > 0 ? result : null;
} finally {
await queryRunner.release();
}
}
async createInvoiceCheck(invoice: InvoiceCheckDto): Promise<{ message: string }> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sequenceSql = 'SELECT ESSCONFERENCIANF.NEXTVAL as "id" FROM DUAL';
const result = await queryRunner.manager.query(sequenceSql);
const checkId = result[0].id;
const sqlMain = `
INSERT INTO ESTCONFERENCIANF (
ID, NUMTRANSVENDA, CODFILIAL, NUMNOTA, DTINICIO, DTFIM, CODFUNCCONF
) VALUES (
${checkId}, ${invoice.transactionId}, ${invoice.storeId}, ${invoice.invoiceId},
TO_DATE(SUBSTR(REPLACE(REPLACE('${invoice.startDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS'),
TO_DATE(SUBSTR(REPLACE(REPLACE('${invoice.endDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS'),
${invoice.userId}
)
`;
await queryRunner.manager.query(sqlMain);
for (const item of invoice.itens) {
const sqlItem = `
INSERT INTO ESTCONFERENCIANFITENS (
IDCONF, NUMTRANSVENDA, CODPROD, NUMSEQ, QT, DTCONF
) VALUES (
${checkId}, ${invoice.transactionId}, ${item.productId}, ${item.seq}, ${item.qt},
TO_DATE(SUBSTR(REPLACE(REPLACE('${item.confDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS')
)
`;
await queryRunner.manager.query(sqlItem);
}
await queryRunner.commitTransaction();
return { message: 'Conferência salva com sucesso!' };
} catch (error) {
await queryRunner.rollbackTransaction();
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
} finally {
await queryRunner.release();
}
}
}