This commit is contained in:
Felipe Batista
2025-01-27 17:44:27 -03:00
commit 47e7f75720
238 changed files with 36425 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
import { Body, Controller, Get, HttpException, HttpStatus, Param, Post, Put } from '@nestjs/common';
import { Address } from 'src/domain/models/address.model';
import { ResultModel } from 'src/domain/models/result.model';
import { AddressCustomerService } from './address-customer.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Customer')
@Controller('api/v1/address')
export class AddressCustomerController {
constructor(private readonly addressService: AddressCustomerService){}
@Get(':idCustomer')
async getAddresses(@Param('idCustomer') idCustomer: number){
try {
return await this.addressService.getAdresses(idCustomer);
} catch (error) {
throw new HttpException(new ResultModel(false, error.status == 404 ?
'Não foram encontrados endereços de entrega para este cliente.' :
error.message, [], error),
error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR);
// const status = error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR;
// throw new HttpException(error.message, status);
}
}
@Get(':idCustomer/:idAddress')
async getAddress(@Param('idCustomer') idCustomer: number, @Param('idAddress') idAddress: number){
try {
return await this.addressService.getAddress(idCustomer, idAddress);
} catch (error) {
const status = error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR;
throw new HttpException(error.message, status);
}
}
@Get('cep/:idCustomer/:cep')
async getAddressByCep(@Param('idCustomer') idCustomer: number, @Param('cep') cep: string){
try {
return await this.addressService.getAddressByCep(idCustomer, cep);
} catch (error) {
const status = error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR;
throw new HttpException(error.message, status);
}
}
@Post('create')
async createAddress(@Body() address: Address){
try {
const addressCreate = await this.addressService.createAddress(address);
return new ResultModel(true, 'Endereço de entrega cadastrado com sucesso!', addressCreate, null);
} catch (error) {
throw new HttpException(new ResultModel(false, 'Erro ao cadastrar endereço de entrega.', {}, error),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Put()
async updateItemShopping(@Body() address: Address){
try {
const addressCreate = await this.addressService.updateAddress(address);
return addressCreate;
} catch (error) {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
}
}

View File

@@ -0,0 +1,12 @@
import { AddressCustomerController } from './address-customer.controller';
import { AddressCustomerService } from './address-customer.service';
import { Module } from '@nestjs/common';
@Module({
imports: [],
controllers: [
AddressCustomerController,],
providers: [
AddressCustomerService,],
})
export class AddressCustomerModule { }

View File

@@ -0,0 +1,360 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Address } from 'src/domain/models/address.model';
import { Connection } from 'typeorm';
import { Pcclientendent } from '../../domain/entity/tables/pcclientendent.entity';
import { Pccidade } from '../../domain/entity/tables/pccidade.entity';
import { ResultModel } from 'src/domain/models/result.model';
import { connectionOptions } from 'src/configs/typeorm.config';
@Injectable()
export class AddressCustomerService {
async getAdresses(idCustomer: number) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const addresses = await queryRunner.manager
.getRepository(Pcclientendent)
.createQueryBuilder('pcclientendent')
.select('\"pcclientendent\".codcli', 'customerId')
.addSelect('\"pcclientendent\".codendentcli', 'idAddress')
.addSelect('\"pcclientendent\".bairroent', 'neighbourhood')
.addSelect('\"pcclientendent\".municent', 'city')
.addSelect('\"pcclientendent\".estent', 'state')
.addSelect('\"pcclientendent\".cepent', 'zipCode')
.addSelect('\"pcclientendent\".enderent', 'street')
.addSelect('\"pcclientendent\".complementoent', 'complement')
.addSelect('\"pcclientendent\".numeroent', 'numberAddress')
.addSelect('\"pcclientendent\".codcidade', 'cityCode')
.addSelect('\"pcclientendent\".pontorefer', 'referencePoint')
.addSelect('\"pcclientendent\".observacao', 'note')
.addSelect('\"pcclientendent\".telent', 'phone')
.addSelect('\"pcclientendent\".telent', 'cellPhone')
.addSelect('\"pcclientendent\".codpracaent', 'placeId')
.addSelect('\"pcclientendent\".latitude', 'latitude')
.addSelect('\"pcclientendent\".longitude', 'longitude')
.where("\"pcclientendent\".codcli = :idCustomer", { idCustomer })
.getRawMany();
return new ResultModel(true, null, addresses, null);
} catch (error) {
// throw new HttpException(new ResultModel(false, error.status == 404 ?
// 'Não foram encontrados endereços de entrega para este cliente.' :
// error.message, {}, error),
// error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR);
// console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async getAddress(idCustomer: number, idAddress: number) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
console.log('getAddress');
try {
const sql = 'SELECT ' +
' pcclientendent.codcli as "customerId" ' +
' ,pcclientendent.codendentcli as "idAddress" ' +
' ,pcclientendent.bairroent as "neighbourhood" ' +
' ,pcclientendent.municent as "city" ' +
' ,pcclientendent.estent as "state" ' +
' ,pcclientendent.cepent as "zipCode" ' +
' ,pcclientendent.enderent as "street" ' +
' ,pcclientendent.complementoent as "complement" ' +
' ,pcclientendent.numeroent as "numberAddress" ' +
' ,pcclientendent.codcidade as "cityCode" ' +
' ,pcclientendent.pontorefer as "referencePoint" ' +
' ,pcclientendent.observacao as "note" ' +
' ,pcclientendent.telent as "phone" ' +
' ,pcclientendent.telent as "cellPhone" ' +
' ,pcclientendent.codpracaent as "placeId" ' +
' ,pcclientendent.latitude as "latitude" ' +
' ,pcclientendent.longitude as "longitude" ' +
' FROM pcclientendent ' +
' WHERE pcclientendent.codcli = :idCustomer ' +
' AND pcclientendent.codendentcli = :idAddress ';
const address = await queryRunner.query( sql, [idCustomer, idAddress] ) ;
// .getRepository(Pcclientendent)
// .createQueryBuilder('pcclientendent')
// .select('\"pcclientendent\".codcli', 'customerId')
// .addSelect('\"pcclientendent\".codendentcli', 'idAddress')
// .addSelect('\"pcclientendent\".bairroent', 'neighbourhood')
// .addSelect('\"pcclientendent\".municent', 'city')
// .addSelect('\"pcclientendent\".estent', 'state')
// .addSelect('\"pcclientendent\".cepent', 'zipCode')
// .addSelect('\"pcclientendent\".enderent', 'street')
// .addSelect('\"pcclientendent\".complementoent', 'complement')
// .addSelect('\"pcclientendent\".numeroent', 'numberAddress')
// .addSelect('\"pcclientendent\".codcidade', 'cityCode')
// .addSelect('\"pcclientendent\".pontorefer', 'referencePoint')
// .addSelect('\"pcclientendent\".observacao', 'note')
// .addSelect('\"pcclientendent\".telent', 'phone')
// .addSelect('\"pcclientendent\".telent', 'cellPhone')
// .addSelect('\"pcclientendent\".codpracaent', 'placeId')
// .where("\"pcclientendent\".codcli = :idCustomer", { idCustomer })
// .andWhere("\"pcclientendent\".codendentcli = :idAddress", { idAddress })
// .getOne();
return address[0];
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async getAddressByCep(idCustomer: number, cep: string ) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const sql = 'SELECT ' +
' pcclientendent.codcli as "customerId" ' +
' ,pcclientendent.codendentcli as "idAddress" ' +
' ,pcclientendent.bairroent as "neighbourhood" ' +
' ,pcclientendent.municent as "city" ' +
' ,pcclientendent.estent as "state" ' +
' ,pcclientendent.cepent as "zipCode" ' +
' ,pcclientendent.enderent as "street" ' +
' ,pcclientendent.complementoent as "complement" ' +
' ,pcclientendent.numeroent as "numberAddress" ' +
' ,pcclientendent.codcidade as "cityCode" ' +
' ,pcclientendent.pontorefer as "referencePoint" ' +
' ,pcclientendent.observacao as "note" ' +
' ,pcclientendent.telent as "phone" ' +
' ,pcclientendent.telent as "cellPhone" ' +
' ,pcclientendent.codpracaent as "placeId" ' +
' ,pcclientendent.latitude as "latitude" ' +
' ,pcclientendent.longitude as "longitude" ' +
' FROM pcclientendent ' +
' WHERE pcclientendent.codcli = :idCustomer ' +
" AND REGEXP_REPLACE(pcclientendent.cepent, '[^0-9]', '') = REGEXP_REPLACE(:cepent, '[^0-9]', '')";
const address = await queryRunner.query( sql, [idCustomer, cep]);
return address[0];
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async updateAddress(data: Address) {
let address = await this.getAddress(data.idCustomer, data.idAddress);
if (address == null) {
throw new HttpException('Endereço não encontrado para alteração.', HttpStatus.NOT_FOUND);
}
const cityCode = await this.findCity(data.ibgeCode);
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
console.log(data);
const customer = await queryRunner.query('SELECT PCCLIENT.CODCLI as "customerId", PCCLIENT.CLIENTE as "name", PCCLIENT.CEPENT as "zipCode", ' +
' PCPRACA.NUMREGIAO as "region", PCCLIENT.EMAIL as "email" ' +
' FROM PCCLIENT, PCPRACA ' +
' WHERE PCCLIENT.CODPRACA = PCPRACA.CODPRACA (+) ' +
' AND PCCLIENT.CODCLI = :1', [data.idCustomer]);
console.log("cliente:" + JSON.stringify(customer));
await queryRunner.manager
.createQueryBuilder()
.update(Pcclientendent)
.set({
enderent: data.street,
numeroent: data.numberAddress,
bairroent: data.neighbourhood,
complementoent: data.complement,
municent: data.city,
estent: data.state,
cepent: data.zipCode,
observacao: data.note,
telent: data.cellPhone,
fonerecebedor: data.phone,
codmunicipio: cityCode,
codcidade: cityCode,
codpracaent: data.placeId,
pontorefer: data.referencePoint,
razaorecebedor: customer[0].name,
fantasia: customer[0].name,
ceprecebedor: customer[0].zipCode,
numregiao: customer[0].region,
codpaisrecebedor: 1058,
emailRecebedor: customer[0].email,
latitude: ( data.latitude ) ? data.latitude.toString() : '0',
longitude:( data.longitude ) ? data.longitude.toString() : '0',
})
.where("\"PCCLIENTENDENT\".codcli = :codcli and \"PCCLIENTENDENT\".codendentcli = :codendentcli",
{ codcli: data.idCustomer, codendentcli: data.idAddress })
.execute();
address = await this.getAddress(data.idCustomer, data.idAddress);
return address;
} catch (erro) {
console.log(erro);
throw new HttpException("Erro ao criar item no carrinho de compras", HttpStatus.INTERNAL_SERVER_ERROR);
} finally {
await queryRunner.release();
await connection.close();
}
}
async createAddress(data: Address) {
console.log(data);
const address = await this.getAddressByCep(data.idCustomer, data.zipCode);
if ( address != null ) {
data.idAddress = address.idAddress;
const result = this.updateAddress(data);
return result;
}
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const cityCode = await this.findCity(data.ibgeCode);
const customer = await queryRunner.query('SELECT PCCLIENT.CODCLI as "customerId", PCCLIENT.CLIENTE as "name", PCCLIENT.CEPENT as "zipCode", ' +
' PCPRACA.NUMREGIAO as "region", PCCLIENT.EMAIL as "email" ' +
' FROM PCCLIENT, PCPRACA ' +
' WHERE PCCLIENT.CODPRACA = PCPRACA.CODPRACA (+) ' +
' AND PCCLIENT.CODCLI = :1', [data.idCustomer]);
const id = await this.getIdAddress();
const newPcclientendent = new Pcclientendent();
newPcclientendent.codendentcli = id;
newPcclientendent.codcli = data.idCustomer;
newPcclientendent.enderent = data.street;
newPcclientendent.numeroent = data.numberAddress;
newPcclientendent.complementoent = data.complement;
newPcclientendent.bairroent = data.neighbourhood;
newPcclientendent.municent = data.city;
newPcclientendent.estent = data.state;
newPcclientendent.cepent = data.zipCode;
newPcclientendent.observacao = data.note;
newPcclientendent.fonerecebedor = data.phone;
newPcclientendent.telent = data.cellPhone;
newPcclientendent.codmunicipio = Number.parseInt(data.ibgeCode);
newPcclientendent.codcidade = cityCode;
newPcclientendent.pontorefer = data.referencePoint;
newPcclientendent.observacao = data.note;
newPcclientendent.codpracaent = data.placeId;
newPcclientendent.razaorecebedor = customer.name;
newPcclientendent.fantasia = customer.name;
newPcclientendent.ceprecebedor = customer.cep;
newPcclientendent.numregiao = customer.region;
newPcclientendent.codpaisrecebedor = 1058;
newPcclientendent.emailRecebedor = customer.email;
newPcclientendent.latitude = ( data.latitude ) ? data.latitude.toString() : '0';
newPcclientendent.longitude = ( data.longitude ) ? data.longitude.toString() : '0';
await queryRunner.manager
.createQueryBuilder()
.insert()
.into(Pcclientendent)
.values(newPcclientendent)
.execute();
const newAddress: Address = {
idCustomer: data.idCustomer,
idAddress: id,
neighbourhood: data.neighbourhood,
city: data.city,
state: data.state,
zipCode: data.zipCode,
street: data.street,
complement: data.complement,
numberAddress: data.numberAddress,
cityCode: data.cityCode,
referencePoint: data.referencePoint,
note: data.note,
ibgeCode: data.ibgeCode,
phone: data.phone,
cellPhone: data.cellPhone,
placeId: data.placeId,
razaorecebedor: customer.name,
fantasia: customer.name,
ceprecebedor: customer.cep,
numregiao: customer.region,
codpaisrecebedor: 1058,
emailRecebedor: customer.email,
latitude: data.latitude,
longitude: data.longitude,
}
return newAddress;
} catch (erro) {
console.log(erro);
throw new HttpException("Erro ao criar endereço de entrega do cliente", HttpStatus.INTERNAL_SERVER_ERROR);
} finally {
await queryRunner.release();
await connection.close();
}
}
async findCity(ibgeCode: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const city = await queryRunner.manager
.getRepository(Pccidade)
.createQueryBuilder('pccidade')
.where("\"pccidade\".CODIBGE = :codibge", { codibge: ibgeCode })
.getOne();
if (city == null)
return 0;
return city.codcidade;
} catch (error) {
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async getIdAddress() {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const address = await queryRunner.manager
.getRepository(Pcclientendent)
.createQueryBuilder('pcclientendent')
.select('max(codendentcli)', 'id')
.getRawOne();
const id = address.id + 1;
return id;
} catch (error) {
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
}

View File

@@ -0,0 +1,43 @@
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Controller, Get, Param, Query } from '@nestjs/common';
import { CepService } from './cep.service';
import { GoogleService } from 'src/google/google.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Cep')
@Controller('api/v1/cep')
export class CepController {
constructor(
private cepService: CepService,
private googleService: GoogleService,
) {}
@Get('find/:cep')
findCep(@Param('cep') cep: string){
//return this.cepService.findCep(cep);
return this.cepService.findViaCep(cep);
}
@Get('find/viacep/:cep')
findViaCep(@Param('cep') cep: string){
return this.cepService.findViaCep(cep);
}
@Get('geolocation/:cep')
geolocationCep(@Param('cep') cep: string){
return this.cepService.geoLocalicationCep(cep);
}
@Get('google')
async geolocationGoogle(@Query() query){
const address = query['address'];
const addressNumber = query['addressNumber'];
const neighborhood = query['neighborhood'];
const city = query['city'];
const state = query['state'];
return this.googleService.getGeocoder(address, addressNumber, neighborhood, city, state);
}
}

View File

@@ -0,0 +1,27 @@
import { CepService } from './cep.service';
import { CepController } from './cep.controller';
/*
https://docs.nestjs.com/modules
*/
import { HttpModule, Module } from '@nestjs/common';
import { GoogleService } from 'src/google/google.service';
import { ListsService } from 'src/backoffice/lists/lists.service';
@Module({
imports: [
HttpModule
// HttpModule.register({
// timeout: 5000,
// maxRedirects: 5,
// }),
],
controllers: [
CepController,],
providers: [
CepService,
GoogleService,
ListsService],
})
export class CepModule { }

View File

@@ -0,0 +1,88 @@
/* eslint-disable @typescript-eslint/camelcase */
/*
https://docs.nestjs.com/providers#services
*/
import { HttpService, Injectable } from '@nestjs/common';
import { catchError, firstValueFrom, switchMap } from 'rxjs';
import { Cep } from 'src/domain/models/cep.model';
import { GeolocationCep } from 'src/domain/models/geolocation-cep.model';
import { ViaCep } from 'src/domain/models/via-cep.model';
@Injectable()
export class CepService {
constructor(
private readonly httpService: HttpService) { }
async findCep(cep: string): Promise<Cep> {
const url = `http://eduardoestevaogyn-d90e3e3eb6249000.api.findcep.com/v1/cep/${cep}.json`;
const { data } = await firstValueFrom(
this.httpService.get<Cep>(url,
{
headers: {
'Accept': 'application/json',
'Referer': 'EVAB02XJN87NY'
}
}).pipe(
catchError((error) => {
console.log(error);
throw error.response;
}),
)
);
const dataGeoloacation = await this.geoLocalicationCep(cep);
return { ...data, ...dataGeoloacation.location };
}
async findViaCep(cep: string): Promise<Cep> {
const url = `http://viacep.com.br/ws/${cep}/json/`;
const { data } = await firstValueFrom(
this.httpService.get<ViaCep>(url
).pipe(
catchError((error) => {
console.log(error);
throw error.response;
}),
)
);
const dataGeoloacation = { location: { latitude: 0, longitude: 0} };
const dataCep: Cep = {
bairro : data.bairro,
cep: data.cep,
cidade: data.localidade,
codigo_ibge: data.ibge,
complemento: data.complemento,
logradouro: data.logradouro,
nome: null,
status: null,
tipo: null,
uf: data.uf
}
return { ...dataCep, ...dataGeoloacation.location };
}
async geoLocalicationCep(cep: string): Promise<GeolocationCep> {
const url = `http://eduardoestevaogyn-d90e3e3eb6249000.api.findcep.com/v1/geolocation/cep/${cep}`;
const { data } = await firstValueFrom(
this.httpService.get<GeolocationCep>(url,
{
headers: {
'Accept': 'application/json',
'Referer': 'EVAB02XJN87NY'
}
}).pipe(
catchError((error) => {
console.log(error);
throw error.response;
}),
),
);
return data;
}
}

View File

@@ -0,0 +1,109 @@
import { Body, Controller, Get, HttpException, HttpStatus, Param, Post, Query } from '@nestjs/common';
import { CustomerService } from './customer.service';
import { ResultModel } from '../../domain/models/result.model';
import { error } from 'console';
import { Customer } from 'src/domain/models/customer.model';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Customer')
@Controller('api/v1/customer')
export class CustomerController {
constructor(private readonly customerService: CustomerService){}
@Get(':name')
async getCustomerByName(@Param('name') name: string){
try{
const customers = await this.customerService.findCustomerByName(name);
return new ResultModel(true, null, customers, null);
} catch(err){
throw new HttpException(new ResultModel(false, 'Não foi possível consultar o cadastro de clientes.', {}, error),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get('categories/fechAll')
async getCategories(){
try{
const categories = await this.customerService.getCategory();
return categories;
} catch(err){
throw new HttpException(new ResultModel(false, err.message, {}, error),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get('subcategories/fechAll')
async getSubCategories(){
try{
const subCategories = await this.customerService.getSubCategory();
return subCategories;
} catch(err){
throw new HttpException(new ResultModel(false, err.message, {}, error),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get()
async getCustomer(@Query() query){
try{
const field = query['field'];
const textSearch = query['textsearch'];
const customers = await this.customerService.findCustomerByQuery(field, textSearch);
return new ResultModel(true, null, customers, null);
} catch(err){
// 'Não foi possível consultar o cadastro de clientes.'
throw new HttpException(new ResultModel(false, err.message, {}, error),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get(':id')
async getCustomerById(@Param('id') id: number){
try{
const customers = await this.customerService.findCustomerById(id);
return new ResultModel(true, null, customers, null);
} catch(err){
throw new HttpException(new ResultModel(false, 'Não foi possível consultar o cadastro de clientes.', {}, error),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get('cpf/:cpf')
async getCustomerByCpf(@Param('cpf') cpf: string){
try{
console.log("pesquisando por cpf");
const customer = await this.customerService.findCustomerByCpf(cpf);
if (!customer) return new ResultModel(false, 'Cliente não cadastrado', null, null);
return new ResultModel(true, null, customer, null);
} catch(err){
throw new HttpException(new ResultModel(false, 'Não foi possível consultar o cadastro de clientes.', {}, error),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get('create/proxnumcli')
async IdCustomer(){
try{
console.log('proxnumcli');
const id = await this.customerService.generateIdCustomer();
return new ResultModel(true, null, id, null);
} catch(err){
throw err;
}
}
@Post('create')
async createCustomer(@Body() customer: Customer){
try{
console.log(customer);
const result = await this.customerService.createCustomer(customer);
return new ResultModel(true, null, result, null);
//return new ResultModel(true, null, id, null);
} catch(err){
throw new HttpException(new ResultModel(false, 'Erro ao cadastrar cliente.', {}, err),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

View File

@@ -0,0 +1,12 @@
import { CustomerController } from './customer.controller';
import { CustomerService } from './customer.service';
import { Module } from '@nestjs/common';
@Module({
imports: [],
controllers: [
CustomerController,],
providers: [
CustomerService,],
})
export class CustomerModule { }

View File

@@ -0,0 +1,663 @@
import { HttpStatus } from '@nestjs/common';
import { Injectable, HttpException } from '@nestjs/common';
import { connectionOptions } from 'src/configs/typeorm.config';
import { Customer } from 'src/domain/models/customer.model';
import { Connection } from 'typeorm';
import { Pcclient } from '../../domain/entity/tables/pcclient.entity';
import { Estcategoriacliente } from '../../domain/entity/tables/estcategoriacliente.entity';
import { Estsubcategoriacliente } from 'src/domain/entity/tables/estsubcategoriacliente.entity';
@Injectable()
export class CustomerService {
async findCustomerByName(name: string) {
let auxName = '';
for (let i = 0; i < name.length; i++) {
auxName += name[i].replace("@", "%");
}
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const sql = ' SELECT pcclient.cliente as "name" ' +
' ,pcclient.codcli as "customerId" ' +
' ,pcclient.emailnfe as "email" ' +
' ,pcclient.cgcent as "cpfCnpj" ' +
' ,pcclient.sexo as "gender" ' +
' ,pcclient.enderent as "address" ' +
' ,pcclient.numeroent as "addressNumber" ' +
' ,pcclient.complementoent as "complement" ' +
' ,pcclient.bairroent as "neigborhood" ' +
' ,pcclient.municent as "city" ' +
' ,pcclient.estent as "state" ' +
' ,pcclient.cepent as "zipCode" ' +
' ,pcclient.telent as "phone" ' +
' ,pcclient.telcelent as "cellPhone" ' +
' ,pcclient.ieent as "numberState" ' +
' ,pcclient.codcategoria as "categoryId" ' +
' ,pcclient.codsubcategoria as "subCategoryId" ' +
' ,pcclient.codpraca as "placeId" ' +
' ,pcclient.codusur1 as "sellerId" ' +
' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' +
' ,pcclient.codcidade as "cityId" ' +
' FROM pcclient, pccidade ' +
' WHERE pcclient.codcidade = pccidade.codcidade (+)';
let where = ` AND ( pcclient.cliente like '%'||'${auxName.replace('@', '%')}'||'%' OR ` +
` REGEXP_REPLACE(pcclient.cgcent, '[^0-9]', '') = REGEXP_REPLACE('${name}', '[^0-9]') OR ` +
` pcclient.codcli = REGEXP_REPLACE('${name}', '[^0-9]') )`;
where += ` AND pcclient.codcli NOT IN (2) AND pcclient.DTEXCLUSAO IS NULL `;
const orderBy = ` ORDER BY pcclient.cliente `;
const pagination = ` OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY`;
const customers = await queryRunner.manager
.query(sql + where + orderBy + pagination) as Customer[];
return customers;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async findCustomerByCpf(cpf: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const sql = ' SELECT pcclient.cliente as "name" ' +
' ,pcclient.codcli as "customerId" ' +
' ,pcclient.emailnfe as "email" ' +
' ,pcclient.cgcent as "cpfCnpj" ' +
' ,pcclient.sexo as "gender" ' +
' ,pcclient.enderent as "address" ' +
' ,pcclient.numeroent as "addressNumber" ' +
' ,pcclient.complementoent as "complement" ' +
' ,pcclient.bairroent as "neighborhood" ' +
' ,pcclient.municent as "city" ' +
' ,pcclient.estent as "state" ' +
' ,pcclient.cepent as "zipCode" ' +
' ,pcclient.telent as "phone" ' +
' ,pcclient.telcelent as "cellPhone" ' +
' ,pcclient.ieent as "numberState" ' +
' ,pcclient.codcategoria as "categoryId" ' +
' ,pcclient.codsubcategoria as "subCategoryId" ' +
' ,pcclient.codpraca as "placeId" ' +
' ,pcclient.codusur1 as "sellerId" ' +
' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' +
' ,pcclient.codcidade as "cityId" ' +
' FROM pcclient, pccidade ' +
' WHERE pcclient.codcidade = pccidade.codcidade (+)';
const where = ` AND REGEXP_REPLACE(pcclient.cgcent, '[^0-9]', '') =REGEXP_REPLACE('${cpf}', '[^0-9]', '')`;
const customer = await queryRunner.query(sql + where);
return customer[0];
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async findCustomerById(idCustomer: number) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const sql = ' SELECT pcclient.cliente as "name" ' +
' ,pcclient.codcli as "customerId" ' +
' ,pcclient.emailnfe as "email" ' +
' ,pcclient.cgcent as "cpfCnpj" ' +
' ,pcclient.sexo as "gender" ' +
' ,pcclient.enderent as "address" ' +
' ,pcclient.numeroent as "addressNumber" ' +
' ,pcclient.complementoent as "complement" ' +
' ,pcclient.bairroent as "neighborhood" ' +
' ,pcclient.municent as "city" ' +
' ,pcclient.estent as "state" ' +
' ,pcclient.cepent as "zipCode" ' +
' ,pcclient.telent as "phone" ' +
' ,pcclient.telcelent as "cellPhone" ' +
' ,pcclient.ieent as "numberState" ' +
' ,pcclient.codcategoria as "categoryId" ' +
' ,pcclient.codsubcategoria as "subCategoryId" ' +
' ,pcclient.codpraca as "placeId" ' +
' ,pcclient.codusur1 as "sellerId" ' +
' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' +
' ,pcclient.codcidade as "cityId" ' +
' FROM pcclient, pccidade ' +
' WHERE pcclient.codcidade = pccidade.codcidade (+)';
const where = ` AND pcclient.codcli = ${idCustomer}`;
const customer = await queryRunner.query(sql + where);
// const customer = await queryRunner.manager
// .getRepository(Pcclient)
// .createQueryBuilder('pcclient')
// .select("\"pcclient\".codcli as \"customerId\"")
// .addSelect("\"pcclient\".cliente as \"name\"")
// .addSelect("\"pcclient\".emailnfe as \"email\"")
// .addSelect("\"pcclient\".cgcent as \"cpfCnpj\"")
// .addSelect("\"pcclient\".ieent as \"numberState\"")
// .addSelect("\"pcclient\".enderent as \"address\"")
// .addSelect("\"pcclient\".numeroent as \"addressNumber\"")
// .addSelect("\"pcclient\".bairroent as \"neighborhood\"")
// .addSelect("\"pcclient\".complementoent as \"complement\"")
// .addSelect("\"pcclient\".municent as \"city\"")
// .addSelect("\"pcclient\".estent as \"state\"")
// .addSelect("\"pcclient\".cepent as \"zipCode\"")
// .addSelect("\"pcclient\".telent as \"phone\"")
// .addSelect("\"pcclient\".telcelent as \"cellPhone\"")
// .addSelect("\"pcclient\".codcategoria as \"categoryId\"")
// .addSelect("\"pcclient\".codsubcategoria as \"subCategoryId\"")
// .addSelect("\"pcclient\".codpraca as \"placeId\"")
// .where("\"pcclient\".codcli = :codcli", { codcli: idCustomer })
// .andWhere("\"pcclient\".CODCLI NOT IN (2)")
// .getOne();
return customer[0];
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async findCustomerByQuery(field: string, textSearch: string) {
let where = "";
switch (field) {
case "name":
where += "\"pcclient\".cliente like '" + textSearch + "%'";
break;
case "document":
where += "REGEXP_REPLACE(\"pcclient\".cgcent, '[^0-9]', '') = REGEXP_REPLACE('" + textSearch + "', '[^0-9]', '')";
break;
case "phone":
where += "REGEXP_REPLACE(\"pcclient\".telent, '[^0-9]', '') = REGEXP_REPLACE('" + textSearch + "', '[^0-9]', '')";
break;
case "cellphone":
where += "REGEXP_REPLACE(\"pcclient\".telcelent, '[^0-9]', '') = REGEXP_REPLACE('" + textSearch + "', '[^0-9]', '')";
break;
case "customerId":
where += "\"pcclient\".codcli = " + textSearch;
break;
default:
throw new HttpException('Não foi informado um campo válido para pesquisa.', HttpStatus.BAD_REQUEST);
}
/*
if (document){
where += "REGEXP_REPLACE(\"pcclient\".cgcent, '[^0-9]', '') = REGEXP_REPLACE('"+document+"', '[^0-9]', '')";
}
if (name){
if(where.length > 0) {
where += " AND \"pcclient\".cliente like '" + name + "%'";
} else {
where += "\"pcclient\".cliente like '" + name + "%'";
}
}*/
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const customers = await queryRunner.manager
.getRepository(Pcclient)
.createQueryBuilder('pcclient')
.select("\"pcclient\".codcli as \"customerId\"")
.addSelect("\"pcclient\".cliente as \"name\"")
.addSelect("\"pcclient\".emailnfe as \"email\"")
.addSelect("\"pcclient\".cgcent as \"cpfCnpj\"")
.addSelect("\"pcclient\".sexo as \"gender\"")
.addSelect("\"pcclient\".enderent as \"address\"")
.addSelect("\"pcclient\".numeroent as \"addressNumber\"")
.addSelect("\"pcclient\".bairroent as \"neighborhood\"")
.addSelect("\"pcclient\".complementoent as \"complement\"")
.addSelect("\"pcclient\".municent as \"city\"")
.addSelect("\"pcclient\".estent as \"state\"")
.addSelect("\"pcclient\".cepent as \"zipCode\"")
.addSelect("\"pcclient\".telent as \"phone\"")
.addSelect("\"pcclient\".telcelent as \"cellPhone\"")
.addSelect("\"pcclient\".codcategoria as \"categoryId\"")
.addSelect("\"pcclient\".codsubcategoria as \"subCategoryId\"")
.addSelect("\"pcclient\".codpraca as \"placeId\"")
.addSelect("\"pcclient\".ieent as \"numberState\"")
.addSelect("\"pcclient\".latitude as \"latitude\"")
.addSelect("\"pcclient\".longitude as \"longitude\"")
.addSelect("\"pcclient\".codmunicipio as \"ibgeCode\"")
.addSelect("\"pcclient\".codcidade as \"cityId\"")
.where(where)
.andWhere("\"pcclient\".CODCLI NOT IN (2) AND \"pcclient\".DTEXCLUSAO IS NULL")
.getRawMany();
return customers;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async createCustomer(customer: Customer) {
try {
console.log("Dados consumer: " + JSON.stringify(customer));
const newCustomer = await this.InitializeCustomer();
newCustomer.tipofj = (customer.company == 'true' ? "J" : "F");
newCustomer.ieent = (customer.company == 'true' ? customer.numberState : "ISENTO");
newCustomer.inscestadual = newCustomer.ieent;
newCustomer.cgcent = customer.cpfCnpj;
newCustomer.sexo = customer.gender;
newCustomer.cgcentrega = customer.cpfCnpj;
newCustomer.cliente = customer.name.toUpperCase();
newCustomer.fantasia = newCustomer.cliente;
newCustomer.email = customer.email.toLowerCase();
newCustomer.emailnfe = customer.email.toLowerCase();
newCustomer.telent = customer.cellPhone;
newCustomer.telcelent = customer.cellPhone;
newCustomer.celularwhatsapp = customer.cellPhone;
newCustomer.codusur1 = customer.sellerId;
newCustomer.codatv1 = ( customer.ramo != null && customer.ramo.id > 0 ) ? customer.ramo.id : newCustomer.codatv1;
//Endereço de entrega
newCustomer.cepent = customer.zipCode;
newCustomer.enderent = customer.address.toUpperCase();
newCustomer.numeroent = customer.addressNumber;
if ( customer.complement !== null && customer.complement.length > 80 ) {
newCustomer.complementoent = customer.complement.substring(0, 80 ).toUpperCase();
} else {
if ( customer.complement != null ) {
newCustomer.complementoent = customer.complement.toUpperCase();
}
}
newCustomer.bairroent = customer.neighborhood.toUpperCase();
newCustomer.municent = customer.city.toUpperCase();
newCustomer.estent = customer.state.toUpperCase();
//Endereço de comercial
newCustomer.cepcom = customer.zipCode;
newCustomer.endercom = customer.address.toUpperCase();
newCustomer.numerocom = customer.addressNumber.toUpperCase();
if ( customer.complement !== null && customer.complement.length > 80 ) {
newCustomer.complementocom = customer.complement.substring(0, 80 ).toUpperCase();
} else {
if ( customer.complement != null ) {
newCustomer.complementocom = customer.complement.toUpperCase();
}
}
newCustomer.bairrocom = customer.neighborhood.toUpperCase();
newCustomer.municcom = customer.city.toUpperCase();
newCustomer.estcom = customer.state.toUpperCase();
//Endereço de cobrança
newCustomer.cepcob = customer.zipCode;
newCustomer.endercob = customer.address.toUpperCase();
newCustomer.numerocob = customer.addressNumber;
if ( customer.complement !== null && customer.complement.length > 80 ) {
newCustomer.complementocob = customer.complement.substring(0, 80 ).toUpperCase();
} else {
if ( customer.complement ) {
newCustomer.complementocob = customer.complement.toUpperCase();
}
}
newCustomer.bairrocob = customer.neighborhood.toUpperCase();
newCustomer.municcob = customer.city.toUpperCase();
newCustomer.estcob = customer.state.toUpperCase();
newCustomer.codcategoria = (customer.category != null) ? customer.category.id : null;
newCustomer.codsubcategoria = (customer.subCategory != null) ? customer.subCategory.id : null;
newCustomer.codpraca = customer.place.id;
newCustomer.codcidade = customer.ibgeCode != null ? await this.findCity(customer.ibgeCode) : null;
newCustomer.codmunicipio = Number.parseInt(customer.ibgeCode);
newCustomer.codcidadecom = newCustomer.codcidade;
newCustomer.dtnasc = customer.birthdate;
newCustomer.meiocomunicacao = customer.communicate;
newCustomer.codfunccad = customer.idUser;
newCustomer.codfunccadastro = customer.idUser;
newCustomer.codfuncultalter = customer.idUser;
newCustomer.dtultalter = new Date();
newCustomer.latitude = customer.latitude;
newCustomer.longitude = customer.longitude;
const oldCustomer = await this.findCustomerByCpf(newCustomer.cgcent);
if (oldCustomer) {
console.log('Cliente localizado: ' + oldCustomer.customerId);
newCustomer.codcli = oldCustomer.customerId;
await this.updateCustomer(newCustomer);
return {
customerId: oldCustomer.customerId,
company: customer.company, name: customer.name, sexo: customer.gender,
cpfCnpj: customer.cpfCnpj, numberState: customer.numberState,
email: customer.email, zipCode: customer.zipCode, address: customer.address,
addressNumber: customer.addressNumber, complement: customer.complement,
neighborhood: customer.neighborhood,
city: customer.city, state: customer.state,
allowMessage: customer.allowMessage, cellPhone: customer.cellPhone,
category: customer.category, subCategory: customer.subCategory,
place: customer.place, ramo: customer.ramo, meiocomunicacao: customer.communicate,
latitude: customer.latitude, longitude: customer.longitude, ibgeCode: customer.ibgeCode
};
} else {
const idCustomer = await this.generateIdCustomer();
if (idCustomer == -1)
return new HttpException("Erro ao gerar númeração de cliente.", HttpStatus.INTERNAL_SERVER_ERROR);
newCustomer.codcli = idCustomer;
await this.insertCustomer(newCustomer);
return {
customerId: idCustomer,
company: customer.company, name: customer.name,
cpfCnpj: customer.cpfCnpj, gender: customer.gender, numberState: customer.numberState,
email: customer.email, zipCode: customer.zipCode, address: customer.address,
addressNumber: customer.addressNumber, complement: customer.complement,
neighborhood: customer.neighborhood,
city: customer.city, state: customer.state,
allowMessage: customer.allowMessage, cellPhone: customer.cellPhone,
category: customer.category, subCategory: customer.subCategory,
place: customer.place, meiocomunicacao: customer.communicate,
ramo: customer.ramo, latitude: customer.latitude, longitude: customer.longitude, ibgeCode: customer.ibgeCode
};
}
} catch (error) {
throw error;
}
}
async updateCustomer(client: Pcclient) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
console.log("MEIO DE COMUNICACAO: " + client.meiocomunicacao);
await queryRunner.manager
.createQueryBuilder()
.update(Pcclient)
.set({
cliente: client.cliente,
fantasia: client.cliente,
telcelent: client.telcelent,
sexo: client.sexo,
telent: client.telent,
email: client.email,
emailnfe: client.email,
cepent: client.cepent,
enderent: client.enderent,
numeroent: client.numeroent,
complementoent: client.complementoent,
bairroent: client.bairroent,
municent: client.municent,
estent: client.estent,
cepcob: client.cepent,
endercob: client.enderent,
numerocob: client.numeroent,
complementocob: client.complementoent,
bairrocob: client.bairroent,
municcob: client.municent,
estcob: client.estent,
cepcom: client.cepent,
endercom: client.enderent,
numerocom: client.numeroent,
complementocom: client.complementoent,
bairrocom: client.bairroent,
municcom: client.municent,
estcom: client.estent,
codcategoria: client.codcategoria,
codsubcategoria: client.codsubcategoria,
codpraca: client.codpraca,
codcidade: client.codcidade,
codmunicipio: client.codmunicipio,
codcidadecom: client.codcidade,
dtnasc: client.dtnasc,
codatv1: client.codatv1,
meiocomunicacao: client.meiocomunicacao,
codfuncultalter: client.codfuncultalter,
dtultalter: client.dtultalter,
latitude: client.latitude,
longitude: client.longitude,
})
.where({ codcli: client.codcli })
.execute();
await queryRunner.commitTransaction();
return client;
} catch (err) {
await queryRunner.rollbackTransaction();
throw err;
} finally {
if ( queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction();
}
await queryRunner.release();
await connection.close();
}
}
async findCity(ibgeCode: string) {
if (ibgeCode == null) {
return 0;
}
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const city = await queryRunner.query('SELECT PCCIDADE.CODCIDADE as "codigoCidade" FROM PCCIDADE WHERE PCCIDADE.codibge = :1', [ibgeCode]);
let cityId = 0;
if (city.length > 0) {
cityId = city[0].codigoCidade;
}
return cityId;
} catch (err) {
throw err;
} finally {
await queryRunner.release();
await connection.close();
}
}
async InitializeCustomer() {
const cliente = new Pcclient();
cliente.codusur1 = 1;
cliente.codplpag = 10;
cliente.codpraca = 119;
cliente.codcob = "D";
cliente.dtcadastro = new Date();
cliente.codcontab = "1";
cliente.aceitavendafracao = "N";
//cliente.Meiocomunicacao = "N";
cliente.bloqueio = "N";
cliente.bloqueiosefaz = "N";
cliente.bloqueiosefazped = "N";
cliente.bloqvendapf = "N";
cliente.condvenda1 = "S";
cliente.condvenda5 = "S";
cliente.condvenda7 = "S";
cliente.condvenda8 = "S";
cliente.contribuinte = "N";
cliente.validarmultiplovenda = "N";
cliente.codfunccad = 1;
cliente.codfunccadastro = 1;
cliente.horacadastro = new Date();
cliente.dtcadastro = new Date();
cliente.dtultvisita = new Date();
cliente.codatv1 = 7;
cliente.aceitatrocanegativa = "N";
cliente.consumidorfinal = "S";
cliente.aplicadescnf = "S";
cliente.simplesnacional = "N";
cliente.sexo = "M";
cliente.isencaosuframa = "T";
cliente.clicrm = "N";
cliente.tv10usacustoproduto = "N";
cliente.inscestadual = "ISENTO";
cliente.codpais = 1058; //Brasil
cliente.observacao = "Importado do E-Commerce";
cliente.aceitachterceiros = "S";
cliente.agregarvalorstdescfin = "N";
cliente.anvisa = "N";
cliente.aplicredbaseicmstransp = "N";
cliente.atendedomingo = "N";
cliente.atendequarta = "N";
cliente.atendequinta = "N";
cliente.atendesabado = "N";
cliente.atendesegunda = "N";
cliente.atendesexta = "N";
cliente.atendeterca = "N";
cliente.atualizasaldoccdescfin = "N";
cliente.bloqremcob = "N";
cliente.clientedan = "N";
cliente.clientefontest = "N";
cliente.clientemonitorado = "N";
cliente.clientprotesto = "S";
cliente.fretedespacho = "0";
cliente.aceitavendafracao = "S";
cliente.validarmultiplovenda = "S";
return cliente;
}
async generateIdCustomer() {
console.log("Gerando idcustomer");
const connection = new Connection(connectionOptions);
const queryRunner = connection.createQueryRunner();
try {
await connection.connect();
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 param = await queryRunner.query(sql);
// const param = await queryRunner.manager
// .getRepository(Pcconsum)
// .createQueryBuilder('pcconsum')
// .setLock("dirty_read")
// .getOne();
const idCustomer = param[0].proxnumcli;
console.log(idCustomer);
sql = `UPDATE PCCONSUM SET PROXNUMCLI = NVL(PROXNUMCLI,0) + 1`;
param = await queryRunner.query(sql);
// await queryRunner.manager
// .createQueryBuilder()
// .update(Pcconsum)
// .set({ proxnumcli: idCustomer + 1 })
// .execute();
// commit transaction now:
await queryRunner.commitTransaction();
return idCustomer;
} catch (err) {
// since we have errors let's rollback changes we made
if ( queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction();
}
console.log(err);
return -1;
} finally {
if ( queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction();
}
// you need to release query runner which is manually created:
await queryRunner.release();
await connection.close();
}
}
async insertCustomer(client: Pcclient) {
console.log(client);
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
await queryRunner.manager
.createQueryBuilder()
.insert()
.into(Pcclient)
.values(client)
.execute();
await queryRunner.commitTransaction();
return client;
} catch (err) {
await queryRunner.rollbackTransaction();
console.log(err);
throw err;
} finally {
if ( queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction();
}
await queryRunner.release();
await connection.close();
}
}
async getCategory() {
const connectionDb = new Connection(connectionOptions)
await connectionDb.connect();
const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect();
try {
return await queryRunner.manager
.getRepository(Estcategoriacliente)
.createQueryBuilder("estcategoriacliente")
.getMany();
} catch (err) {
console.log(err);
throw err;
} finally {
await queryRunner.release();
await connectionDb.close();
}
}
async getSubCategory() {
const connectionDb = new Connection(connectionOptions)
await connectionDb.connect();
const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect();
try {
return await queryRunner.manager
.getRepository(Estsubcategoriacliente)
.createQueryBuilder("estsubcategoriacliente")
.getMany();
} catch (err) {
console.log(err);
throw err;
} finally {
await queryRunner.release();
await connectionDb.close();
}
}
}

View File

@@ -0,0 +1,44 @@
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Controller, Get, Param, Query } from '@nestjs/common';
import { DashboardService } from './dashboard.service';
@Controller('api/v1/dashboard')
export class DashboardController {
constructor(private dashboardService: DashboardService){}
@Get('sale')
getSale() {
return this.dashboardService.dashboarSale();
}
@Get('sale/store')
getSaleSellers(@Query() query) {
let supervisorIds: string;
if (query['ids'] != null) {
supervisorIds = query['ids'];
}
return this.dashboardService.dashboardSeller(null, supervisorIds);
}
@Get('sale/company')
getSaleCompany(@Query() query) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
let supervisorIds: string;
if (query['ids'] != null) {
supervisorIds = query['ids'];
}
return this.dashboardService.dashboardCompany();
}
@Get('sale/:supervisorId')
getSaleSeller(@Param('supervisorId') supervisorId: number) {
return this.dashboardService.dashboardSeller(supervisorId, null);
}
}

View File

@@ -0,0 +1,16 @@
import { DashboardService } from './dashboard.service';
import { DashboardController } from './dashboard.controller';
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
@Module({
imports: [],
controllers: [
DashboardController,],
providers: [
DashboardService,],
})
export class DashboardModule { }

View File

@@ -0,0 +1,705 @@
/*
https://docs.nestjs.com/providers#services
*/
import { Injectable } from '@nestjs/common';
import { connectionOptions } from 'src/configs/typeorm.config';
import { Connection } from 'typeorm';
@Injectable()
export class DashboardService {
async dashboarSale() {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const sqlSale = `SELECT ROUND(SUM(VLVENDA),2) as "sale",
ROUND(SUM(CUSTOFIN),2) as "cost",
ROUND(SUM(VLDEVOLUCAO),2) as "devolution",
ROUND(SUM(VLMETA),2) as "objetivo",
CASE WHEN SUM(VLVENDA) > 0 THEN
ROUND(( ( ( SUM(VLVENDA) - SUM(CUSTOFIN) ) / SUM(VLVENDA) ) * 100 ),2) ELSE 0 END as "profit",
CASE WHEN SUM(VLMETA) > 0 THEN ROUND((( SUM(VLVENDA) / SUM(VLMETA) ) * 100),2) ELSE 0 END as "percentual",
SUM(NFS) as "nfs"
FROM (
SELECT VENDAS.DTSAIDA, VENDAS.CODSUPERVISOR,
SUM(VENDAS.VLVENDA) VLVENDA,
SUM(VENDAS.VLCUSTOFIN) CUSTOFIN,
0 VLDEVOLUCAO,
0 VLMETA,
COUNT(DISTINCT VENDAS.NUMTRANSVENDA) NFS
FROM view_vendas_resumo_faturamento vendas
WHERE VENDAS.DTSAIDA = TRUNC(SYSDATE)
AND VENDAS.CONDVENDA IN (1,7)
GROUP BY VENDAS.DTSAIDA, VENDAS.CODSUPERVISOR
UNION ALL
SELECT DEVOLUCAO.DTENT DTSAIDA, PCUSUARI.CODSUPERVISOR,
ROUND(SUM(DEVOLUCAO.vldevolucao * (-1)), 2) VLVENDA,
ROUND(SUM(DEVOLUCAO.VLCUSTOFIN * (-1)), 2) VLCUSTOFIN,
ROUND(SUM(DEVOLUCAO.VLDEVOLUCAO), 2) VLDEVOLUCAO,
0 VLMETA,
0 NFS
FROM view_devol_resumo_faturamento devolucao, PCNFSAID, PCNFENT, PCUSUARI
WHERE devolucao.dtent = TRUNC(SYSDATE)
AND DEVOLUCAO.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA (+)
AND DEVOLUCAO.NUMTRANSENT = PCNFENT.NUMTRANSENT
AND DEVOLUCAO.codusurdevol = PCUSUARI.CODUSUR
GROUP BY DEVOLUCAO.DTENT, PCUSUARI.CODSUPERVISOR
UNION ALL
SELECT PCMETARCA.DATA, PCUSUARI.CODSUPERVISOR,
0 VLVENDA,
0 VLCUSTOFIN,
0 VLDEVOLUCAO,
SUM(PCMETARCA.VLVENDAPREV) VLMETA,
0 NFS
FROM PCMETARCA, PCUSUARI
WHERE PCMETARCA.DATA = trunc(sysdate)
AND PCMETARCA.CODUSUR = PCUSUARI.CODUSUR
GROUP BY PCMETARCA.DATA, PCUSUARI.CODSUPERVISOR ) DADOS`;
const sqlSaleBySupervisor = `SELECT DADOS.CODSUPERVISOR as "supervisorId",
PCSUPERV.NOME as "name",
ROUND(SUM(VLVENDA),2) as "sale",
ROUND(SUM(CUSTOFIN),2) as "cost",
ROUND(SUM(VLDEVOLUCAO),2) as "devolution",
ROUND(SUM(VLMETA),2) as "objetivo",
CASE WHEN SUM(VLVENDA) > 0 THEN
ROUND(( ( ( SUM(VLVENDA) - SUM(CUSTOFIN) ) / SUM(VLVENDA) ) * 100 ),2) ELSE 0 END as "profit",
CASE WHEN SUM(VLMETA) > 0 THEN ROUND((( SUM(VLVENDA) / SUM(VLMETA) ) * 100),2) ELSE 0 END as "percentual",
SUM(NFS) as "nfs"
FROM (
SELECT VENDAS.DTSAIDA, VENDAS.CODSUPERVISOR,
SUM(VENDAS.VLVENDA) VLVENDA,
SUM(VENDAS.VLCUSTOFIN) CUSTOFIN,
0 VLDEVOLUCAO,
0 VLMETA,
COUNT(DISTINCT VENDAS.NUMTRANSVENDA) NFS
FROM view_vendas_resumo_faturamento vendas
WHERE VENDAS.DTSAIDA = TRUNC(SYSDATE)
AND VENDAS.CONDVENDA IN (1,7)
GROUP BY VENDAS.DTSAIDA, VENDAS.CODSUPERVISOR
UNION ALL
SELECT DEVOLUCAO.DTENT DTSAIDA, PCUSUARI.CODSUPERVISOR,
SUM(DEVOLUCAO.vldevolucao * (-1)) VLVENDA,
SUM(DEVOLUCAO.VLCUSTOFIN * (-1)) VLCUSTOFIN,
SUM(DEVOLUCAO.VLDEVOLUCAO) VLDEVOLUCAO,
0 VLMETA,
0 NFS
FROM view_devol_resumo_faturamento devolucao, PCNFSAID, PCNFENT, PCUSUARI
WHERE devolucao.dtent = TRUNC(SYSDATE)
AND DEVOLUCAO.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA (+)
AND DEVOLUCAO.NUMTRANSENT = PCNFENT.NUMTRANSENT
AND DEVOLUCAO.codusurdevol = PCUSUARI.CODUSUR
GROUP BY DEVOLUCAO.DTENT, PCUSUARI.CODSUPERVISOR
UNION ALL
SELECT PCMETARCA.DATA, PCUSUARI.CODSUPERVISOR,
0 VLVENDA,
0 VLCUSTOFIN,
0 VLDEVOLUCAO,
SUM(PCMETARCA.VLVENDAPREV) VLMETA,
0 NFS
FROM PCMETARCA, PCUSUARI
WHERE PCMETARCA.DATA = TRUNC(SYSDATE)
AND PCMETARCA.CODUSUR = PCUSUARI.CODUSUR
GROUP BY PCMETARCA.DATA, PCUSUARI.CODSUPERVISOR ) DADOS, PCSUPERV
WHERE DADOS.CODSUPERVISOR = PCSUPERV.CODSUPERVISOR
GROUP BY DADOS.CODSUPERVISOR, PCSUPERV.NOME
ORDER BY SUM(DADOS.VLVENDA) DESC`;
const sale = await queryRunner.query(sqlSale);
const saleBySupervisor = await queryRunner.query(sqlSaleBySupervisor);
const data = { ...sale[0], saleSupervisor: [...saleBySupervisor] };
return data;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async dashboardSeller(supervisorId: number, supervisorIds: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
let filter = '';
if (supervisorId != null) {
filter = `CODSUPERVISOR = ${supervisorId} `;
}
if (supervisorIds != null) {
filter = `CODSUPERVISOR IN ( ${supervisorIds} )`;
}
const sqlDashboard = `SELECT PCSUPERV.CODSUPERVISOR as "supervisorId",
PCSUPERV.NOME as "store",
PCUSUARI.CODUSUR as "sellerId",
PCUSUARI.NOME as "sellerName",
MAX(DIASMES.QTDIAS) as "qtdeDaysMonth",
MAX(DIASMES.QTDIASTRANSCORRIDOS) as "qtdeDays",
SUM(DADOS.VLMETA) as "objetivo" ,
SUM(DADOS.VLVENDA) as "saleValue",
SUM(DADOS.VLDEVOLUCAO) as "devolution",
( SUM(DADOS.VLVENDA) - SUM(DADOS.VLMETA) ) as "dif",
ROUND(CASE WHEN ( SUM(DADOS.VLVENDA) - SUM(DADOS.VLMETA) ) < 0 THEN
( SUM(DADOS.VLMETA) - SUM(DADOS.VLVENDA) ) /
DECODE(( MAX(DIASMES.QTDIAS) - MAX(DIASMES.QTDIASTRANSCORRIDOS) ), 0, 1, ( MAX(DIASMES.QTDIAS) - MAX(DIASMES.QTDIASTRANSCORRIDOS) ) )
ELSE 0 END,2) as "ObjetivoSale",
( CASE WHEN SUM(DADOS.VLMETA) > 0 THEN
ROUND(( SUM(DADOS.VLVENDA) / SUM(DADOS.VLMETA) * 100),2)
ELSE 0 END ) as "percentualObjective",
SUM(DADOS.QTNOTAS) as "qtdeInvoice",
CASE WHEN SUM(DADOS.QTNOTAS) > 0 THEN
ROUND(( SUM(DADOS.VLVENDA) / SUM(DADOS.QTNOTAS) ),2)
ELSE 0 END as "ticket",
SUM(DADOS.VLTABELA) as "listPrice",
( SUM(DADOS.VLTABELA) - SUM(DADOS.VLVENDA) ) as "discountValue",
ROUND(CASE WHEN SUM(DADOS.VLTABELA) > 0 THEN
( ( SUM(DADOS.VLTABELA) - SUM(DADOS.VLVENDA) ) / SUM(DADOS.VLTABELA) * 100 )
ELSE 0 END,2) as "percentOff",
SUM(DADOS.MIX) as "mix",
SUM(DADOS.VLMETADIA) as "objetiveToday",
SUM(DADOS.VLVENDADIA) as "saleToday",
SUM(DADOS.VLORCAMENTO) as "preSaleValue",
SUM(DADOS.QTORCAMENTO) as "preSaleQtde",
SUM(DADOS.QTNOTASDIA) as "qtdeInvoiceDay",
SUM(DADOS.VLMETADIA * META_HORA.PERCMETAHORA / 100) as "objetiveHour",
( CASE WHEN SUM(DADOS.VLMETADIA) > 0 THEN
ROUND(( SUM(DADOS.VLVENDADIA) / SUM(DADOS.VLMETADIA * META_HORA.PERCMETAHORA / 100) * 100),2)
ELSE 0 END ) as "percentualObjectiveHour",
SUM(DADOS.VLMETADIA * META_HORA.PERCMETAHORATOTAL / 100) as "objetiveTotalHour",
( CASE WHEN SUM(DADOS.VLMETADIA) > 0 THEN
ROUND(( SUM(DADOS.VLVENDADIA) / SUM(DADOS.VLMETADIA * META_HORA.PERCMETAHORATOTAL / 100) * 100),2)
ELSE 0 END ) as "percentualObjectiveTotalHour"
FROM ( SELECT PCMETARCA.CODUSUR,
SUM(PCMETARCA.VLVENDAPREV) VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
0 VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA
FROM PCMETARCA
WHERE PCMETARCA.DATA BETWEEN LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE),-1)) + 1 AND LAST_DAY(TRUNC(SYSDATE))
GROUP BY PCMETARCA.CODUSUR
UNION ALL
SELECT PCMETARCA.CODUSUR,
0 VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
0 VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
SUM(PCMETARCA.VLVENDAPREV) VLMETADIA,
0 QTNOTASDIA
FROM PCMETARCA
WHERE PCMETARCA.DATA = TRUNC(SYSDATE)
GROUP BY PCMETARCA.CODUSUR
UNION ALL
SELECT VENDAS.CODUSUR,
0 VLMETA,
SUM(VENDAS.VLVENDA) VLVENDA,
COUNT(DISTINCT VENDAS.NUMPED) QTNOTAS,
SUM(VENDAS.VLTABELA) VLTABELA,
COUNT(DISTINCT VENDAS.CODPROD) MIX,
0 VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA
FROM view_vendas_resumo_faturamento VENDAS
WHERE VENDAS.DTSAIDA BETWEEN LAST_DAY(ADD_MONTHS((TRUNC(SYSDATE) - 1),-1)) + 1 AND TRUNC(SYSDATE)
AND VENDAS.CONDVENDA IN (1,7)
GROUP BY VENDAS.CODUSUR
UNION ALL
SELECT DEVOLUCAO.CODUSURDEVOL CODUSUR,
0 VLMETA,
SUM(DEVOLUCAO.VLDEVOLUCAO * (-1)) VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
0 VLVENDADIA,
SUM(DEVOLUCAO.VLDEVOLUCAO) VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA
FROM view_devol_resumo_faturamento DEVOLUCAO
WHERE DEVOLUCAO.DTENT BETWEEN LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE)-1,-1)) + 1 AND TRUNC(SYSDATE)
GROUP BY DEVOLUCAO.CODUSURDEVOL
UNION ALL
SELECT VENDAS.CODUSUR,
0 VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
SUM(VENDAS.VLVENDA) VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
COUNT(DISTINCT VENDAS.NUMPED) QTNOTASDIA
FROM view_vendas_resumo_faturamento VENDAS
WHERE VENDAS.DTSAIDA = TRUNC(SYSDATE)
AND VENDAS.CONDVENDA IN (1,7)
GROUP BY VENDAS.CODUSUR
UNION ALL
SELECT DEVOLUCAO.CODUSURDEVOL CODUSUR,
0 VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
SUM(DEVOLUCAO.VLDEVOLUCAO * (-1)) VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA
FROM view_devol_resumo_faturamento DEVOLUCAO
WHERE DEVOLUCAO.DTENT = TRUNC(SYSDATE)
GROUP BY DEVOLUCAO.CODUSURDEVOL
UNION ALL
SELECT PCORCAVENDAC.CODUSUR,
0 VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
0 VLVENDADIA,
0 VLDEVOLUCAO,
SUM(PCORCAVENDAC.VLATEND) VLORCAMENTO,
COUNT(DISTINCT PCORCAVENDAC.NUMORCA) QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA
FROM PCORCAVENDAC
WHERE NVL(PCORCAVENDAC.ORCAMENTOUTILIZADO,'N') = 'N'
AND PCORCAVENDAC.DATA BETWEEN LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE) - 1, -1)) + 1 AND TRUNC(SYSDATE)
GROUP BY PCORCAVENDAC.CODUSUR
,PCORCAVENDAC.CODSUPERVISOR
) DADOS,
( SELECT COUNT(1) QTDIAS
,COUNT(CASE WHEN PCDIASUTEIS.DATA < TRUNC(SYSDATE) THEN 1 ELSE NULL END) QTDIASTRANSCORRIDOS
FROM PCDIASUTEIS
WHERE PCDIASUTEIS.CODFILIAL = '4'
AND PCDIASUTEIS.DIAVENDAS = 'S'
AND PCDIASUTEIS.DATA BETWEEN LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE),-1)) + 1 AND LAST_DAY(TRUNC(SYSDATE)) ) DIASMES,
(SELECT ESTMETAHORA.CODSUPERVISOR,
CASE WHEN TO_CHAR(SYSDATE, 'D') = 7 THEN
ESTMETAHORA.PERCMETADOM
ELSE ESTMETAHORA.PERCMETAHORA END PERCMETAHORA
, CASE WHEN TO_CHAR(SYSDATE, 'D') = 7 THEN
ESTMETAHORA.PERCMETADOMTOTAL
ELSE ESTMETAHORA.PERCMETAHORATOTAL END PERCMETAHORATOTAL
FROM ESTMETAHORA
WHERE ESTMETAHORA.${filter}
AND TO_CHAR(HORA, 'HH24') = TO_CHAR(SYSDATE, 'HH24')) META_HORA,
PCUSUARI, PCSUPERV
WHERE PCUSUARI.CODUSUR = DADOS.CODUSUR
AND PCUSUARI.CODSUPERVISOR = PCSUPERV.CODSUPERVISOR
AND PCUSUARI.CODSUPERVISOR = META_HORA.CODSUPERVISOR
AND PCUSUARI.${filter}
-- HAVING SUM(DADOS.VLMETA) > 0
GROUP BY PCSUPERV.CODSUPERVISOR, PCSUPERV.NOME, PCUSUARI.CODUSUR, PCUSUARI.NOME
ORDER BY PCUSUARI.NOME`;
const saleByRCA = await queryRunner.query(sqlDashboard);
let initialValue = 0;
const totalSale = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.saleValue,
initialValue,
);
initialValue = 0;
const totalObjetive = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.objetivo,
initialValue,
);
initialValue = 0;
const totalObjetiveDay = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.objetiveToday,
initialValue,
);
initialValue = 0;
const totalDiscount = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.discountValue,
initialValue,
);
initialValue = 0;
const totalMix = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.mix,
initialValue,
);
initialValue = 0;
const totalNFs = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.qtdeInvoice,
initialValue,
);
initialValue = 0;
const totalSaleToday = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.saleToday,
initialValue,
);
initialValue = 0;
const totalDevolution = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.devolution,
initialValue,
);
initialValue = 0;
const totalQtNfsDia = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.qtdeInvoiceDay,
initialValue,
);
const percentualSale = Number.parseFloat(((totalSale / totalObjetive) * 100).toFixed(2));
initialValue = 0;
const totalObjetiveHour = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.objetiveHour,
initialValue,
);
const percentualObjetiveHour = Number.parseFloat(((totalSaleToday / totalObjetiveHour) * 100).toFixed(2));
initialValue = 0;
const totalObjetiveCompanyHour = saleByRCA.reduce(
(accumulator, currentValue) => accumulator + currentValue.objetiveTotalHour,
initialValue,
);
const percentualObjetiveCompanyHour = Number.parseFloat(((totalSaleToday / totalObjetiveCompanyHour) * 100).toFixed(2));
const data = {
objetive: totalObjetive, sale: totalSale, percentualSale: percentualSale,
discount: totalDiscount, nfs: totalNFs, mix: totalMix, objetiveToday: totalObjetiveDay,
saleToday: totalSaleToday, nfsToday: totalQtNfsDia, devolution: totalDevolution,
objetiveHour: totalObjetiveHour, percentualObjetiveHour: percentualObjetiveHour,
objetiveTotalHour: totalObjetiveCompanyHour, percentualObjetiveTotalHour: percentualObjetiveCompanyHour,
saleSupervisor: [...saleByRCA]
};
return data;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async dashboardCompany() { //supervisorId: number, supervisorIds: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const sqlDashboard = `SELECT PCSUPERV.CODSUPERVISOR as "supervisorId",
PCSUPERV.NOME as "store",
MAX(DIASMES.QTDIAS) as "qtdeDaysMonth",
MAX(DIASMES.QTDIASTRANSCORRIDOS) as "qtdeDays",
SUM(DADOS.VLMETA) as "objetivo" ,
SUM(DADOS.VLVENDA) as "saleValue",
SUM(DADOS.VLDEVOLUCAO) as "devolution",
( SUM(DADOS.VLVENDA) - SUM(DADOS.VLMETA) ) as "dif",
ROUND(CASE WHEN ( SUM(DADOS.VLVENDA) - SUM(DADOS.VLMETA) ) < 0 THEN
( SUM(DADOS.VLMETA) - SUM(DADOS.VLVENDA) ) /
DECODE(( MAX(DIASMES.QTDIAS) - MAX(DIASMES.QTDIASTRANSCORRIDOS) ), 0, 1, ( MAX(DIASMES.QTDIAS) - MAX(DIASMES.QTDIASTRANSCORRIDOS) ) )
ELSE 0 END,2) as "ObjetivoSale",
( CASE WHEN SUM(DADOS.VLMETA) > 0 THEN
ROUND(( SUM(DADOS.VLVENDA) / SUM(DADOS.VLMETA) * 100),2)
ELSE 0 END ) as "percentualObjective",
SUM(DADOS.QTNOTAS) as "qtdeInvoice",
CASE WHEN SUM(DADOS.QTNOTAS) > 0 THEN
ROUND(( SUM(DADOS.VLVENDA) / SUM(DADOS.QTNOTAS) ),2)
ELSE 0 END as "ticket",
SUM(DADOS.VLTABELA) as "listPrice",
( SUM(DADOS.VLTABELA) - SUM(DADOS.VLVENDA) ) as "discountValue",
ROUND(CASE WHEN SUM(DADOS.VLTABELA) > 0 THEN
( ( SUM(DADOS.VLTABELA) - SUM(DADOS.VLVENDA) ) / SUM(DADOS.VLTABELA) * 100 )
ELSE 0 END,2) as "percentOff",
SUM(DADOS.MIX) as "mix",
SUM(DADOS.VLMETADIA) as "objetiveToday",
SUM(DADOS.VLVENDADIA) as "saleToday",
SUM(DADOS.VLORCAMENTO) as "preSaleValue",
SUM(DADOS.QTORCAMENTO) as "preSaleQtde",
SUM(DADOS.QTNOTASDIA) as "qtdeInvoiceDay",
SUM(DADOS.VLMETADIA * META_HORA.PERCMETAHORA / 100) as "objetiveHour",
( CASE WHEN SUM(DADOS.VLMETADIA) > 0 THEN
ROUND(( SUM(DADOS.VLVENDADIA) / SUM(DADOS.VLMETADIA * META_HORA.PERCMETAHORA / 100) * 100),2)
ELSE 0 END ) as "percentualObjectiveHour",
SUM(DADOS.VLMETADIA * META_HORA.PERCMETAHORATOTAL / 100) as "objetiveTotalHour",
( CASE WHEN SUM(DADOS.VLMETADIA) > 0 THEN
ROUND(( SUM(DADOS.VLVENDADIA) / SUM(DADOS.VLMETADIA * META_HORA.PERCMETAHORATOTAL / 100) * 100),2)
ELSE 0 END ) as "percentualObjectiveTotalHour",
SUM(DADOS.VLCUSTOFIN) as "profitValue"
FROM ( SELECT PCMETARCA.CODUSUR,
SUM(PCMETARCA.VLVENDAPREV) VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
0 VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA,
0 VLCUSTOFIN
FROM PCMETARCA
WHERE PCMETARCA.DATA BETWEEN LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE),-1)) + 1 AND TRUNC(SYSDATE) - 1
GROUP BY PCMETARCA.CODUSUR
UNION ALL
SELECT PCMETARCA.CODUSUR,
0 VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
0 VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
SUM(PCMETARCA.VLVENDAPREV) VLMETADIA,
0 QTNOTASDIA,
0 VLCUSTOFIN
FROM PCMETARCA
WHERE PCMETARCA.DATA = TRUNC(SYSDATE)
GROUP BY PCMETARCA.CODUSUR
UNION ALL
SELECT VENDAS.CODUSUR,
0 VLMETA,
SUM(VENDAS.VLVENDA) VLVENDA,
COUNT(DISTINCT VENDAS.NUMPED) QTNOTAS,
SUM(VENDAS.VLTABELA) VLTABELA,
COUNT(DISTINCT VENDAS.CODPROD) MIX,
0 VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA,
0 VLCUSTOFIN
FROM view_vendas_resumo_faturamento VENDAS
WHERE VENDAS.DTSAIDA BETWEEN LAST_DAY(ADD_MONTHS((TRUNC(SYSDATE) - 1),-1)) + 1 AND TRUNC(SYSDATE) - 1
AND VENDAS.CONDVENDA IN (1,7)
GROUP BY VENDAS.CODUSUR
UNION ALL
SELECT DEVOLUCAO.CODUSURDEVOL CODUSUR,
0 VLMETA,
SUM(DEVOLUCAO.VLDEVOLUCAO * (-1)) VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
0 VLVENDADIA,
SUM(DEVOLUCAO.VLDEVOLUCAO) VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA,
0 VLCUSTOFIN
FROM view_devol_resumo_faturamento DEVOLUCAO
WHERE DEVOLUCAO.DTENT BETWEEN LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE)-1,-1)) + 1 AND TRUNC(SYSDATE) - 1
GROUP BY DEVOLUCAO.CODUSURDEVOL
UNION ALL
SELECT VENDAS.CODUSUR,
0 VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
SUM(VENDAS.VLVENDA) VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
COUNT(DISTINCT VENDAS.NUMPED) QTNOTASDIA,
SUM(VENDAS.VLCUSTOFIN) VLCUSTOFIN
FROM view_vendas_resumo_faturamento VENDAS
WHERE VENDAS.DTSAIDA = TRUNC(SYSDATE)
AND VENDAS.CONDVENDA IN (1,7)
GROUP BY VENDAS.CODUSUR
UNION ALL
SELECT DEVOLUCAO.CODUSURDEVOL CODUSUR,
0 VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
SUM(DEVOLUCAO.VLDEVOLUCAO * (-1)) VLVENDADIA,
0 VLDEVOLUCAO,
0 VLORCAMENTO,
0 QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA,
SUM(DEVOLUCAO.VLCUSTOFIN * (-1)) VLCUSTOFIN
FROM view_devol_resumo_faturamento DEVOLUCAO
WHERE DEVOLUCAO.DTENT = TRUNC(SYSDATE)
GROUP BY DEVOLUCAO.CODUSURDEVOL
UNION ALL
SELECT PCORCAVENDAC.CODUSUR,
0 VLMETA,
0 VLVENDA,
0 QTNOTAS,
0 VLTABELA,
0 MIX,
0 VLVENDADIA,
0 VLDEVOLUCAO,
SUM(PCORCAVENDAC.VLATEND) VLORCAMENTO,
COUNT(DISTINCT PCORCAVENDAC.NUMORCA) QTORCAMENTO,
0 VLMETADIA,
0 QTNOTASDIA,
0 VLCUSTOFIN
FROM PCORCAVENDAC
WHERE NVL(PCORCAVENDAC.ORCAMENTOUTILIZADO,'N') = 'N'
AND PCORCAVENDAC.DATA BETWEEN LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE) - 1, -1)) + 1 AND TRUNC(SYSDATE)
GROUP BY PCORCAVENDAC.CODUSUR
,PCORCAVENDAC.CODSUPERVISOR
) DADOS,
( SELECT COUNT(1) QTDIAS
,COUNT(CASE WHEN PCDIASUTEIS.DATA < TRUNC(SYSDATE) THEN 1 ELSE NULL END) QTDIASTRANSCORRIDOS
FROM PCDIASUTEIS
WHERE PCDIASUTEIS.CODFILIAL = '4'
AND PCDIASUTEIS.DIAVENDAS = 'S'
AND PCDIASUTEIS.DATA BETWEEN LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE),-1)) + 1 AND LAST_DAY(TRUNC(SYSDATE)) ) DIASMES,
(SELECT ESTMETAHORA.CODSUPERVISOR,
CASE WHEN TO_CHAR(SYSDATE, 'D') = 7 THEN
ESTMETAHORA.PERCMETADOM
ELSE ESTMETAHORA.PERCMETAHORA END PERCMETAHORA
, CASE WHEN TO_CHAR(SYSDATE, 'D') = 7 THEN
ESTMETAHORA.PERCMETADOMTOTAL
ELSE ESTMETAHORA.PERCMETAHORATOTAL END PERCMETAHORATOTAL
FROM ESTMETAHORA
WHERE TO_CHAR(HORA, 'HH24') = TO_CHAR(SYSDATE, 'HH24')) META_HORA,
PCUSUARI, PCSUPERV
WHERE PCUSUARI.CODUSUR = DADOS.CODUSUR
AND PCUSUARI.CODSUPERVISOR = PCSUPERV.CODSUPERVISOR
AND PCUSUARI.CODSUPERVISOR = META_HORA.CODSUPERVISOR
-- HAVING SUM(DADOS.VLMETA) > 0
GROUP BY PCSUPERV.CODSUPERVISOR, PCSUPERV.NOME
ORDER BY PCSUPERV.NOME`;
const saleByStore = await queryRunner.query(sqlDashboard);
let initialValue = 0;
const totalSale = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.saleValue,
initialValue,
);
initialValue = 0;
const totalObjetive = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.objetivo,
initialValue,
);
initialValue = 0;
const totalObjetiveDay = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.objetiveToday,
initialValue,
);
initialValue = 0;
const totalDiscount = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.discountValue,
initialValue,
);
initialValue = 0;
const totalMix = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.mix,
initialValue,
);
initialValue = 0;
const totalNFs = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.qtdeInvoice,
initialValue,
);
initialValue = 0;
const totalSaleToday = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.saleToday,
initialValue,
);
initialValue = 0;
const totalDevolution = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.devolution,
initialValue,
);
initialValue = 0;
const totalQtNfsDia = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.qtdeInvoiceDay,
initialValue,
);
const percentualSale = Number.parseFloat(((totalSale / totalObjetive) * 100).toFixed(2));
initialValue = 0;
const totalObjetiveHour = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.objetiveHour,
initialValue,
);
const percentualObjetiveHour = Number.parseFloat(((totalSaleToday / totalObjetiveHour) * 100).toFixed(2));
initialValue = 0;
const totalObjetiveCompanyHour = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.objetiveTotalHour,
initialValue,
);
const percentualObjetiveCompanyHour = Number.parseFloat(((totalSaleToday / totalObjetiveCompanyHour) * 100).toFixed(2));
initialValue = 0;
const totalProfitCompany = saleByStore.reduce(
(accumulator, currentValue) => accumulator + currentValue.profitValue,
initialValue,
);
const profitPerc = ( ( totalSaleToday - totalProfitCompany) / totalSaleToday ) * 100;
const profitValue = ( totalSaleToday - totalProfitCompany);
const data = {
objetive: totalObjetive, sale: totalSale, percentualSale: percentualSale,
discount: totalDiscount, nfs: totalNFs, mix: totalMix, objetiveToday: totalObjetiveDay,
saleToday: totalSaleToday, nfsToday: totalQtNfsDia, devolution: totalDevolution,
objetiveHour: totalObjetiveHour, percentualObjetiveHour: percentualObjetiveHour,
objetiveTotalHour: totalObjetiveCompanyHour, percentualObjetiveTotalHour: percentualObjetiveCompanyHour,
profitValue: profitValue, profitPerc: profitPerc,
saleSupervisor: [...saleByStore]
};
return data;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
}

View File

@@ -0,0 +1,154 @@
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Get, HttpException, HttpStatus, Post, Req } from '@nestjs/common';
import { Param } from '@nestjs/common/decorators';
import { Cart } from 'src/domain/models/cart.model';
import { ResultModel } from 'src/domain/models/result.model';
import { OrderService } from './order.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Order')
@Controller('api/v1/order')
export class OrderController {
constructor(private readonly orderService: OrderService) { }
@Get('list')
async getOrder(@Req() request) {
try {
let store = '';
let initialDate = new Date();
let finalDate = new Date();
let name: string;
let document: string;
let sellerId = 0;
let idOrder = '';
if (request.query['x-store'])
store = request.query['x-store'];
if (request.query['initialDate']){
initialDate = request.query['initialDate'];
}
if (request.query['finalDate']){
finalDate = request.query['finalDate'] = finalDate;
}
if (request.query['document'])
document = request.query['document'];
if (request.query['name'])
name = request.query['name'];
if (request.query['sellerId'])
sellerId = request.query['sellerId'];
if (request.query['idOrder'])
idOrder = request.query['idOrder'];
const result = await this.orderService.getOrders(store, initialDate, finalDate, document, name, sellerId, idOrder);
return result;
} catch (err) {
throw new HttpException(new ResultModel(false, err.errors.message, {}, err),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get('cart')
async getCart(@Req() request) {
console.log('consultando pedido de venda');
let orderId = 0;
const query = request.query;
if (query.orderId) {
orderId = query.orderId;
}
if (orderId == 0) {
throw new HttpException('Informe um número do pedido de venda para realizar a pesquisa.', HttpStatus.BAD_REQUEST);
}
return await this.orderService.getCartId(orderId);
}
@Get('productsTax')
async getProductsWithoutTax(@Req() request) {
let cartId = '';
let customerId = 0;
const query = request.query;
if (query.cartId) {
cartId = query.cartId;
}
if (query.customerId) {
customerId = query.customerId;
}
return await this.orderService.productsWithoutTax(cartId, customerId);
}
@Get('orderretiraposterior')
async getOrdersRetiraPosterior() {
return await this.orderService.OrderRetiraPosterior();
}
@Get('itens/:id')
async getItensOrder(@Param('id') orderId: number) {
console.log('consultando pedido de venda');
if (orderId == 0) {
throw new HttpException('Informe um número do pedido de venda para realizar a pesquisa.', HttpStatus.BAD_REQUEST);
}
return await this.orderService.getItensOrder(orderId);
}
@Post('create')
async createOrder(@Body() cart: Cart) {
console.log("cart: " + JSON.stringify(cart));
try {
const result = await this.orderService.create(cart);
return new ResultModel(true, null, result, null);
} catch (err) {
console.log(err);
throw new HttpException(new ResultModel(false, err.response, {}, err),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get('products-order')
async getProductsOrder(@Req() request) {
try {
let store = '';
let initialDate = new Date();
let finalDate = new Date();
let name: string;
let document: string;
let sellerId = 0;
let idOrder = '';
let typeFilterProduct = '';
let productText = '';
if (request.query['x-store'])
store = request.query['x-store'];
if (request.query['initialDate']){
initialDate = request.query['initialDate'];
}
if (request.query['finalDate']){
finalDate = request.query['finalDate'] = finalDate;
}
if (request.query['document'])
document = request.query['document'];
if (request.query['name'])
name = request.query['name'];
if (request.query['sellerId'])
sellerId = request.query['sellerId'];
if (request.query['idOrder'])
idOrder = request.query['idOrder'];
if (request.query['typeFilterProduct'])
typeFilterProduct = request.query['typeFilterProduct'];
if (request.query['productText'])
productText = request.query['productText'];
const result = await this.orderService
.getProductsOrder(store, initialDate, finalDate,
document, name, sellerId, idOrder,
typeFilterProduct,
productText );
return result;
} catch (err) {
throw new HttpException(new ResultModel(false, err.errors.message, {}, err),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

View File

@@ -0,0 +1,30 @@
import { OrderController } from './order.controller';
/*
https://docs.nestjs.com/modules
*/
import { HttpModule, Module } from '@nestjs/common';
import { OrderService } from './order.service';
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 { UserService } from 'src/Auth/services/user.service';
@Module({
imports: [HttpModule],
controllers: [
OrderController,
OrderController,],
providers: [
OrderService,
OrderService,
ListsService,
CustomerService,
AddressCustomerService,
ShoppingService,
UserService,
],
exports: [OrderService]
})
export class OrderModule { }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
/*
https://docs.nestjs.com/modules
*/
import { HttpModule, Module } from '@nestjs/common';
import { OrderModule } from 'src/sales/order/order.module';
import { PixSantanderController } from './santander/pix-santander.controller';
import { PixSantanderService } from './santander/pix-santander.service';
@Module({
imports: [HttpModule, OrderModule],
controllers: [PixSantanderController],
providers: [PixSantanderService],
})
export class PaymentPixModule {}

View File

@@ -0,0 +1,11 @@
export interface SantanderPixAuthToken {
    refreshUrl: string;
    token_type: string;
    client_id: string;
    access_token: string;
    refresh_token: string;
    scopes: string;
    expires_in: string;
}

View File

@@ -0,0 +1,72 @@
export interface Paginacao {
paginaAtual: number;
itensPorPagina: number;
quantidadeDePaginas: number;
quantidadeTotalDeItens: number;
}
export interface Parametros {
inicio: Date;
fim: Date;
paginacao: Paginacao;
}
export interface Calendario {
criacao: Date;
expiracao: string;
}
export interface Devedor {
cnpj: string;
nome: string;
}
export interface Valor {
original: string;
}
export interface Pagador {
cnpj: string;
nome: string;
}
export interface Horario {
solicitacao: Date;
}
export interface Devolucao {
id: string;
rtrId: string;
valor: string;
horario: Horario;
status: string;
}
export interface Pix {
endToEndId: string;
txid: string;
valor: string;
horario: Date;
pagador: Pagador;
infoPagador: string;
devolucoes: Devolucao[];
}
export interface Cob {
status: string;
calendario: Calendario;
location: string;
txid: string;
revisao: number;
devedor: Devedor;
valor: Valor;
chave: string;
solicitacaoPagador: string;
pix: Pix[];
}
export interface SantanderCreatePix {
parametros: Parametros;
cobs: Cob[];
}

View File

@@ -0,0 +1,50 @@
export interface Calendario {
    dataDeVencimento: string;
    validadeAposVencimento: number;
}
export interface Devedor {
    logradouro: string;
    cidade: string;
    uf: string;
    cep: string;
    cpf: string;
    nome: string;
}
export interface Multa {
    modalidade: string;
    valorPerc: number;
}
export interface Juros {
    modalidade: string;
    valorPerc: number;
}
export interface DescontoDataFixa {
    data: string;
    valorPerc: string;
}
export interface Desconto {
    modalidade: string;
    descontoDataFixa: DescontoDataFixa[];
}
export interface Valor {
    original: number;
    multa: Multa;
    juros: Juros;
    desconto: Desconto;
}
export interface SantanderCreateCob {
    calendario: Calendario;
    devedor: Devedor;
    valor: Valor;
    chave: string;
    solicitacaoPagador: string;
}

View File

@@ -0,0 +1,5 @@
export interface OrderPayment {
orderId: number,
customerId: number,
amount: number,
}

View File

@@ -0,0 +1,22 @@
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Post } from '@nestjs/common';
import { OrderPayment } from './models/order-payment.model';
import { PixSantanderService } from './pix-santander.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Pix-Santander')
@Controller('api/v1/payment/pix/santander')
export class PixSantanderController {
constructor (private pixSantanderService: PixSantanderService){}
@Post('create')
async create(@Body() orderPayment: OrderPayment ){
return this.pixSantanderService.create(orderPayment);
}
}

View File

@@ -0,0 +1,159 @@
/*
https://docs.nestjs.com/providers#services
*/
import { HttpService, Injectable, HttpException } from '@nestjs/common';
import QueryString = require('qs');
import { map, catchError, lastValueFrom } from 'rxjs';
import { HttpStatus } from '@nestjs/common/enums';
import { SantanderPixAuthToken } from './models/auth-token.model';
import { Calendario, Devedor, SantanderCreateCob, Valor } from './models/create-cob.model';
import { OrderService } from 'src/sales/order/order.service';
import { OrderPayment } from './models/order-payment.model';
import { SantanderCreatePix } from './models/cob-pix.model';
import { SharedService } from 'src/shared/services/shared.service';
import * as crc from 'crc';
@Injectable()
export class PixSantanderService {
constructor(
private http: HttpService,
private orderService: OrderService) { }
async create(orderPayment: OrderPayment) {
// const txid = '0';
// this.http.put(`https://pix.santander.com.br/api/v1/sandbox/cob/${txid}`, null);
//let authToken: SantanderPixAuthToken = null;
const authToken = await this.getToken();
const dateNow = new Date();
const year = dateNow.getFullYear();
const month = ("00" + (dateNow.getMonth() + 1)).slice(-2);
const day = ("00" + dateNow.getDate()).slice(-2);
if (authToken.access_token !== null) {
const customer = await this.orderService.getCustomer(orderPayment.customerId);
const calendario: Calendario = {
dataDeVencimento: year + '-' + month + '-' + day,
validadeAposVencimento: 1,
};
const devedor: Devedor = {
logradouro: customer.enderent,
cidade: customer.municent,
uf: customer.estent,
cep: customer.cepent,
cpf: customer.cgcent,
nome: customer.cliente
}
const valor: Valor = {
original: orderPayment.amount,
multa: null,
desconto: null,
juros: null,
};
const pixCob: SantanderCreateCob = {
calendario: calendario,
devedor: devedor,
valor: valor,
chave: orderPayment.orderId.toString(),
solicitacaoPagador: "Compra realizada na JURUNENSE"
}
console.log(pixCob);
return this.createCobPix(authToken, pixCob);
}
return authToken;
}
async createCobPix(token: SantanderPixAuthToken, data: SantanderCreateCob) {
const config = {
headers: {
"Authorization": `Bearer ${token.access_token} `,
"Content-Type": 'text/plain'
},
};
const request = this.http
.post<SantanderCreatePix>("https://pix.santander.com.br/api/v1/sandbox/cob/987456123", data, config)
.pipe(
map((res) => {
return res.data
}),
)
.pipe(
catchError((error) => {
console.log(error);
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}),
);
const fact = await lastValueFrom(request);
const storeName = "JURUNENSE HOME CENTER";
const storeCity = "BELEM";
const lengthTxId = fact.cobs[0].txid.length + 4;
let qrCodeDynamic = "000201" +
"010212" +
"26850014" +
"br.gov.bcb.pix" +
"2563" +
fact.cobs[0].location +
"52040000" +
"5303986" +
"54" +
("00" + fact.cobs[0].valor.original.length).slice(-2) +
fact.cobs[0].valor.original +
"5402BR" +
"59" + ("00" + storeName.length).slice(-2) +
storeName + // deve ser o nome de fantasia da filial
"60" + ("00" + storeCity.length).slice(-2) +
storeCity + // deve ser a cidade da filial
"62" + lengthTxId.toString() +
fact.cobs[0].txid;//ver que informação é TXID
const crcValue = crc.crc16ccitt(qrCodeDynamic).toString(16);
qrCodeDynamic += "6304" + crcValue
console.log(qrCodeDynamic);
return fact;
}
async getToken() {
const data = QueryString.stringify({
'client_id': 'yooItYcY7AYxWHwrjyBvIGcF9uEJDG1L',
'client_secret': 'L0J47wlZ28ERlEfu'
});
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
};
const request = this.http
.post<SantanderPixAuthToken>('https://pix.santander.com.br/sandbox/oauth/token?grant_type=client_credentials', data, config)
.pipe(
map((res) => {
return res.data
}),
)
.pipe(
catchError((error) => {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}),
);
const fact = await lastValueFrom(request);
return fact;
}
}

View File

@@ -0,0 +1,95 @@
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Get, HttpException, HttpStatus, Param, Post, Req } from '@nestjs/common';
import { Cart } from 'src/domain/models/cart.model';
import { ResultModel } from 'src/domain/models/result.model';
import { PreOrderService } from './pre-order.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Pre-Order')
@Controller('api/v1/preorder')
export class PreOrderController {
constructor(private readonly preOrderService: PreOrderService) { }
@Post('create')
async createOrder(@Body() cart: Cart) {
try {
const result = await this.preOrderService.create(cart);
return new ResultModel(true, null, result, null);
} catch (err) {
throw new HttpException(new ResultModel(false, err.errors.message, {}, err),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Get('list')
async getPreOrders(@Req() request: any) {
let sellerId = 0;
let storeId = '';
let start = new Date();
let end = new Date();
let idPreOrder = 0;
let document = '';
let nameCustomer = '';
const query = request.query;
if (query.store) {
storeId = query.store;
}
if (query.start) {
start = query.start;
}
if (query.end) {
end = query.end;
}
if (query.seller) {
sellerId = query.seller;
}
if (query.idPreOrder) {
idPreOrder = query.idPreOrder;
}
if (query.document) {
document = query.document;
}
if (query.nameCustomer) {
nameCustomer = query.nameCustomer;
}
try {
// if (sellerId == 0) {
// throw new HttpException('Não foi informado um vendedor para a pesquisa de orçamentos.', HttpStatus.BAD_REQUEST);
// }
const result = await this.preOrderService.getPreOrders(sellerId, storeId, start, end, idPreOrder, document, nameCustomer);
return new ResultModel(true, null, result, null);
} catch (err) {
throw err;
}
}
@Get('cart')
async getCartId(@Req() request: any) {
console.log('consultando orçamento');
let preOrderId = 0;
const query = request.query;
if (query.preOrderId) {
preOrderId = query.preOrderId;
}
if (preOrderId == 0) {
throw new HttpException('Informe um número de orçamento para realizar a pesquisa.', HttpStatus.BAD_REQUEST);
}
return await this.preOrderService.getCartId(preOrderId);
}
@Get('itens/:id')
async getItensOrder(@Param('id') preOrderId: number) {
console.log('consultando pedido de venda');
if (preOrderId == 0) {
throw new HttpException('Informe um número do orçamento de venda para realizar a pesquisa.', HttpStatus.BAD_REQUEST);
}
return await this.preOrderService.getItensPreOrder(preOrderId);
}
}

View File

@@ -0,0 +1,23 @@
import { PreOrderController } from './pre-order.controller';
import { PreOrderService } from './pre-order.service';
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
import { SharedModule } from 'src/shared/shared.module';
import { ListsService } from 'src/backoffice/lists/lists.service';
import { AddressCustomerService } from '../address-customer/address-customer.service';
import { CustomerService } from '../customer/customer.service';
@Module({
imports: [SharedModule],
controllers: [
PreOrderController,],
providers: [
PreOrderService,
ListsService,
CustomerService,
AddressCustomerService],
})
export class PreOrderModule { }

View File

@@ -0,0 +1,506 @@
/*
https://docs.nestjs.com/providers#services
*/
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { Pcorcavendai } from 'src/domain/entity/tables/pcorcavendai.entity';
import { Cart } from 'src/domain/models/cart.model';
import { SharedService } from 'src/shared/services/shared.service';
import { Connection } from 'typeorm';
import { Pcorcavendac } from '../../domain/entity/tables/pcorcavendac.entity';
import { Shopping } from '../../domain/entity/tables/estprevendac.entity';
import { connectionOptions } from 'src/configs/typeorm.config';
import { ListsService } from 'src/backoffice/lists/lists.service';
import { CustomerService } from '../customer/customer.service';
import { AddressCustomerService } from '../address-customer/address-customer.service';
@Injectable()
export class PreOrderService {
constructor(
private readonly sharedService: SharedService,
private readonly listsService: ListsService,
private readonly customerService: CustomerService,
private readonly addressCustomerService: AddressCustomerService) { }
async create(cart: Cart) {
console.log('cart: ' + JSON.stringify(cart));
// if (cart.idCustomer === 1 && cart.preCustomerDocument !== null) {
// this.createPreCustomer(cart);
// }
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
console.log('Processo 1');
try {
const customer = await this.sharedService.getCustomer(cart.idCustomer);
let idPreOrder = 0;
let idRca = 0;
const preOrder = new Pcorcavendac();
const shopping = await queryRunner.query(' SELECT ESTPREVENDAC.NUMORCA as "idPreOrder", ESTPREVENDAC.CODUSUR as "idRca" ' +
' FROM ESTPREVENDAC ' +
' WHERE ESTPREVENDAC.ID = :1 ' +
' AND ESTPREVENDAC.NUMORCA IS NOT NULL ', [cart.id]);
if (shopping.length > 0) {
idPreOrder = shopping[0].idPreOrder;
const existPreOrder = await queryRunner
.query('SELECT PCORCAVENDAC.CODUSUR as "idRca" FROM PCORCAVENDAC WHERE NUMORCA = :NUMORCA', [idPreOrder]);
idRca = existPreOrder[0].idRca;
await queryRunner.query('DELETE FROM PCORCAVENDAI WHERE NUMORCA = :1', [idPreOrder]);
await queryRunner.query('DELETE FROM PCORCAVENDAC WHERE NUMORCA = :1', [idPreOrder]);
} else {
idPreOrder = await this.sharedService.generateIdPreOrder(cart.idSeller);
}
//Create pre-customers
if (cart.idCustomer === 1 && cart.preCustomerDocument !== null) {
const preCustomer = await queryRunner.query(`SELECT ESTVENDAPRECLIENTE.CPF FROM ESTVENDAPRECLIENTE ` +
` WHERE IDCART = :1 AND CPF = :2`, [cart.id, cart.preCustomerDocument]);
if (preCustomer === null || preCustomer.length === 0) {
const sqlInsert = ` INSERT INTO ESTVENDAPRECLIENTE ( CPF, IDCART, NOME, TELEFONE, DTCADASTRO, CODUSUR, NUMPEDRCA ) ` +
` VALUES ( REGEXP_REPLACE(:CPF, '[^0-9]', '') , :IDCART, :NOME, :TELEFONE, SYSDATE, :CODUSUR, :NUMPEDRCA ) `;
await queryRunner.query(sqlInsert, [cart.preCustomerDocument,
cart.id, cart.preCustomerName, cart.preCustomerPhone, cart.idSeller, idPreOrder]);
}
} else {
if ( cart.preCustomerDocument != null ) {
await queryRunner.query(`DELETE FROM ESTVENDAPRECLIENTE WHERE IDCART = :1 AND REGEXP_REPLACE(:CPF, '[^0-9]', '')`,
[cart.id, cart.preCustomerDocument]);
}
}
const dataAtual = await queryRunner.query("SELECT TO_CHAR(SYSDATE, \'DD\') AS \"dia\" " +
" ,TO_CHAR(SYSDATE, \'MM\') AS \"mes\" " +
" ,TO_CHAR(SYSDATE, \'YYYY\') AS \"ano\" FROM DUAL");
preOrder.numorca = idPreOrder;
const dateNow = new Date(dataAtual[0].ano, dataAtual[0].mes - 1, dataAtual[0].dia);
const dateDelivery = new Date(dataAtual[0].ano, dataAtual[0].mes, dataAtual[0].dia);
dateDelivery.setDate(dateDelivery.getDate() + 3); // setDate(dateNow.getDate() + 3);
console.log('Processo 2');
let numeroSeq = 1;
for (const item of cart.itens) {
const itemPreOrder = new Pcorcavendai();
itemPreOrder.numorca = preOrder.numorca;
itemPreOrder.data = this.formatDate(new Date());
itemPreOrder.codcli = cart.idCustomer;
itemPreOrder.codprod = item.idProduct;
itemPreOrder.codauxiliar = item.ean;
itemPreOrder.codusur = ( idRca > 0 ) ? idRca : cart.idSeller;
itemPreOrder.qt = item.quantity;
itemPreOrder.pvenda = item.salePrice;
itemPreOrder.ptabela = item.listPrice;
itemPreOrder.numcar = 0;
itemPreOrder.posicao = 'L';
itemPreOrder.st = 0;
itemPreOrder.vlcustocont = 0;
itemPreOrder.vlcustofin = 0;
itemPreOrder.vlcustoreal = 0;
itemPreOrder.vlcustorep = 0;
itemPreOrder.percom = 0;
itemPreOrder.perdesc = (item.listPrice > 0) ? ((item.listPrice - item.salePrice) / item.listPrice) * 100 : 0;
itemPreOrder.numseq = numeroSeq;
itemPreOrder.pvendabase = 0;
itemPreOrder.codst = await this.
sharedService.
getTaxId(item.idProduct,
cart.saleStore,
customer.estent);
itemPreOrder.custofinest = 0;
itemPreOrder.codauxiliar = item.ean;
itemPreOrder.codfilialretira = item.idStock;
itemPreOrder.poriginal = 0;
itemPreOrder.pvendabase = 0;
itemPreOrder.pvenda1 = 0;
itemPreOrder.tipoentrega = item.deliveryMethod;
// eslint-disable-next-line @typescript-eslint/camelcase
itemPreOrder.rp_imediata = (item.deliveryMethod == "RA") ? "S" : "N";
itemPreOrder.complemento = item.descriptionAux;
itemPreOrder.ambiente = item.environment;
console.log('Processo 3');
await queryRunner.manager
.createQueryBuilder()
.insert()
.into(Pcorcavendai)
.values(itemPreOrder)
.execute();
console.log('Processo 4');
numeroSeq = numeroSeq + 1;
}
if (cart.shippingValue > 0) {
const itemPreOrder = new Pcorcavendai();
itemPreOrder.numorca = preOrder.numorca;
itemPreOrder.data = this.formatDate(new Date());
itemPreOrder.codcli = cart.idCustomer;
itemPreOrder.codprod = 48500;
itemPreOrder.codauxiliar = 48500;
itemPreOrder.codusur = ( idRca > 0 ) ? idRca : cart.idSeller;
itemPreOrder.qt = 1;
itemPreOrder.pvenda = Number.parseFloat(cart.shippingValue.toString());
itemPreOrder.ptabela = Number.parseFloat(cart.shippingValue.toString());
itemPreOrder.numcar = 0;
itemPreOrder.posicao = 'L';
itemPreOrder.st = 0;
itemPreOrder.vlcustocont = 0;
itemPreOrder.vlcustofin = 0;
itemPreOrder.vlcustoreal = 0;
itemPreOrder.vlcustorep = 0;
itemPreOrder.percom = 0;
itemPreOrder.perdesc = 0;
itemPreOrder.numseq = numeroSeq;
itemPreOrder.pvendabase = 0;
itemPreOrder.codst = await this.
sharedService.
getTaxId(48500,
cart.saleStore,
customer.estent);
itemPreOrder.custofinest = 0;
itemPreOrder.codauxiliar = 48500;
itemPreOrder.codfilialretira = cart.saleStore;
itemPreOrder.poriginal = 0;
itemPreOrder.pvendabase = 0;
itemPreOrder.pvenda1 = 0;
itemPreOrder.tipoentrega = 'EF';
console.log('Processo 3');
await queryRunner.manager
.createQueryBuilder()
.insert()
.into(Pcorcavendai)
.values(itemPreOrder)
.execute();
console.log('Processo 4');
numeroSeq = numeroSeq + 1;
}
//#region create PCORCAVENDAC
console.log('Processo 5' + cart);
const supervisor = await queryRunner.manager.query('SELECT PCUSUARI.CODSUPERVISOR as "codsupervisor" FROM PCUSUARI WHERE CODUSUR = :1', [cart.idSeller]);
console.log('Supervisor: ' + JSON.stringify(supervisor));
preOrder.posicao = 'L';
preOrder.numcar = 0;
preOrder.numpedrca = preOrder.numorca;
preOrder.percvenda = 100;
preOrder.codendent = cart.idAddress;
preOrder.codcob = cart.idBilling;
preOrder.codplpag = cart.idPaymentPlan;
preOrder.condvenda = 7;
preOrder.data = this.formatDate(new Date());
preOrder.hora = new Date().getHours();
preOrder.minuto = new Date().getMinutes();
preOrder.dtentrega = cart.shippingDate; // dateDelivery;
preOrder.codfilial = cart.saleStore,
preOrder.codusur = ( idRca > 0 ) ? idRca : cart.idSeller;
preOrder.codemitente = cart.userId;
preOrder.codusur3 = cart.idProfessional;
preOrder.tipoprioridadeentrega = cart.shippingPriority;
if (supervisor != null && supervisor.length > 0) {
preOrder.codsupervisor = supervisor[0].codsupervisor;
}
preOrder.codemitente = cart.userId;
preOrder.vlfrete = cart.shippingValue;
preOrder.vloutrasdesp = 0;
preOrder.numitens = cart.itens.length;
preOrder.obs1 = cart.notation1;
preOrder.obs2 = cart.notation2;
preOrder.obsentrega1 = cart.deliveryNote1;
preOrder.obsentrega2 = cart.deliveryNote2;
preOrder.obsentrega3 = cart.deliveryNote3;
//Dados do cliente
preOrder.codcli = cart.idCustomer;
preOrder.codpraca = customer.codpraca;
preOrder.fretedespacho = customer.fretedespacho;
preOrder.data = dateNow;
preOrder.vlfrete = Number.parseFloat(cart.shippingValue.toString());
//#endregion
//#region create PCPEDITEMP
//#endregion
// execute some operations on this transaction:
console.log('Processo 6');
const totalOrca = await queryRunner.
query('SELECT SUM((PCORCAVENDAI.QT * PCORCAVENDAI.PVENDA)) AS \"valorTotal\" ' +
' ,SUM(PCORCAVENDAI.QT * PCORCAVENDAI.PTABELA ) AS \"valorTabela\" ' +
' ,SUM(PCORCAVENDAI.QT * PCPRODUT.PESOBRUTO ) AS \"pesoTotal\" ' +
' ,SUM(PCORCAVENDAI.QT * PCPRODUT.VOLUME ) AS \"volumeTotal\" ' +
' ,SUM(PCORCAVENDAI.QT * ( PCORCAVENDAI.PTABELA - PCORCAVENDAI.PVENDA) ) AS \"valorDesconto\" ' +
' FROM PCORCAVENDAI, PCPRODUT ' +
' WHERE PCORCAVENDAI.CODPROD = PCPRODUT.CODPROD ' +
' AND PCORCAVENDAI.NUMORCA = :idPreOrder ', [preOrder.numorca]);
preOrder.vltotal = totalOrca[0].valorTotal;
preOrder.vlatend = totalOrca[0].valorTotal;
preOrder.vltabela = totalOrca[0].valorTabela;
preOrder.totpeso = totalOrca[0].pesoTotal;
preOrder.totvolume = totalOrca[0].volumeTotal;
preOrder.vldesconto = totalOrca[0].valorDesconto;
await queryRunner.manager
.createQueryBuilder()
.insert()
.into(Pcorcavendac)
.values(preOrder)
.execute();
const sql = 'UPDATE PCORCAVENDAC SET DATA = TRUNC(SYSDATE) ' +
' WHERE PCORCAVENDAC.NUMORCA = :1 ';
await queryRunner.query(sql, [
preOrder.numorca
]);
console.log('Processo 7');
await queryRunner.manager
.createQueryBuilder()
.update(Shopping)
.set({
numorca: idPreOrder
})
.where("ESTPREVENDAC.ID = :idcart", { idcart: cart.id })
.execute();
await queryRunner.commitTransaction();
return preOrder;
} catch (err) {
await queryRunner.rollbackTransaction();
console.log(err);
throw err;
} finally {
await queryRunner.release();
await connection.close();
}
}
formatDate(date: Date) {
const day = date.getDay();
const month = date.getMonth() + 1;
const year = date.getFullYear();
const newDate: Date = new Date(year, month, day);
console.log(newDate);
return newDate;
}
async getPreOrders(sellerId: number, storeId: string, start: Date, end: Date, idPreOrder: number, document: string, nameCustomer: string) {
console.log('Vendedor: ' + sellerId);
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const startDate = new Date(start);
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(end);
day = endDate.getDate();
month = ("00" + (endDate.getMonth() + 1)).slice(-2);
year = endDate.getFullYear();
const endFormat = day + "/" + month + "/" + year;
let sql = 'SELECT TO_CHAR(PCORCAVENDAC.DATA, \'DD/MM/YYYY\') as "data" ' +
' ,PCORCAVENDAC.NUMORCA as "idPreOrder" ' +
' ,PCORCAVENDAC.VLATEND as "value" ' +
' ,PCORCAVENDAC.VLTABELA as "listValue" ' +
' ,PCORCAVENDAC.CODCLI as "idCustomer" ' +
` ,CASE WHEN PCORCAVENDAC.CODCLI = 1 THEN NVL(( SELECT ESTVENDAPRECLIENTE.NOME || '( PRE-CADASTRO)' ` +
' FROM ESTVENDAPRECLIENTE ' +
' WHERE ESTVENDAPRECLIENTE.IDCART = ESTPREVENDAC.ID AND ROWNUM = 1 ), ' +
' PCCLIENT.CLIENTE ) ELSE PCCLIENT.CLIENTE END as "customer" ' +
' ,PCORCAVENDAC.CODUSUR as "idSeller" ' +
' ,PCUSUARI.NOME as "seller" ' +
' ,CASE WHEN PCORCAVENDAC.ORCAMENTOUTILIZADO = \'S\' THEN \'ORÇAMENTO UTILIZADO\' ELSE \'PENDENTE\' END as "status"' +
' ,PCORCAVENDAC.NUMPED as "orderId" ' +
' ,( SELECT ESTVENDAPRECLIENTE.CPF FROM ESTVENDAPRECLIENTE WHERE ESTVENDAPRECLIENTE.IDCART = ESTPREVENDAC.ID AND ROWNUM = 1 ) as "cpfPreCustomer" ' +
' ,( SELECT ESTVENDAPRECLIENTE.NOME FROM ESTVENDAPRECLIENTE WHERE ESTVENDAPRECLIENTE.IDCART = ESTPREVENDAC.ID AND ROWNUM = 1 ) as "namePreCustomer" ' +
' FROM PCORCAVENDAC, PCCLIENT, PCUSUARI, ESTPREVENDAC ' +
' WHERE PCORCAVENDAC.CODCLI = PCCLIENT.CODCLI ' +
' AND PCORCAVENDAC.CODUSUR = PCUSUARI.CODUSUR ' +
' AND PCORCAVENDAC.NUMORCA = ESTPREVENDAC.NUMORCA ' +
' AND PCORCAVENDAC.CODFILIAL = :1 ' +
' AND PCORCAVENDAC.DATA BETWEEN TO_DATE(:2, \'DD/MM/YYYY\') AND TO_DATE(:3, \'DD/MM/YYYY\')';
if (sellerId > 0) {
sql += ` AND PCORCAVENDAC.CODUSUR = ${sellerId} `;
}
if (idPreOrder > 0) {
sql += ` AND PCORCAVENDAC.NUMORCA = ${idPreOrder} `;
}
if ( document.length > 0 ) {
sql += ` AND REGEXP_REPLACE(PCCLIENT.CGCENT, '[^0-9]', '') = REGEXP_REPLACE(${document}, '[^0-9]', '') `;
}
if ( nameCustomer.length > 0 ) {
sql += ` AND PCCLIENT.CLIENTE LIKE UPPER('${nameCustomer}')||'%' `;
}
const preOrders =
await queryRunner.query(sql, [storeId, startFormat, endFormat]);
return preOrders;
} catch (err) {
throw err;
} finally {
await queryRunner.release();
await connection.close();
}
}
async getCartId(preOrderId: number) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const preOrder = await queryRunner.query('SELECT PCORCAVENDAC.DATA as "createDate" ' +
' ,PCORCAVENDAC.ORCAMENTOUTILIZADO as "preOrderFinish" ' +
' ,PCORCAVENDAC.NUMPED as "orderId" ' +
' ,PCORCAVENDAC.CODFILIAL as "invoiceStore" ' +
' ,PCORCAVENDAC.CODCLI as "customerId" ' +
' ,PCORCAVENDAC.CODPLPAG as "paymentPlanId" ' +
' ,PCORCAVENDAC.CODCOB as "billindId" ' +
' ,PCORCAVENDAC.CODENDENT as "addressId" ' +
' ,PCORCAVENDAC.CODUSUR3 as "partnerId" ' +
' ,ESTPREVENDAC.ID as "cartId" ' +
' ,PCORCAVENDAC.OBS as "notification" ' +
' ,PCORCAVENDAC.OBS1 as "notification1" ' +
' ,PCORCAVENDAC.OBS2 as "notification2" ' +
' ,PCORCAVENDAC.OBSENTREGA1 as "notificationDelivery1" ' +
' ,PCORCAVENDAC.OBSENTREGA2 as "notificationDelivery2" ' +
' ,PCORCAVENDAC.OBSENTREGA3 as "notificationDelivery3" ' +
' ,PCORCAVENDAC.DTENTREGA as "deliveryDate" ' +
` ,NVL(PCORCAVENDAC.TIPOPRIORIDADEENTREGA, 'B') as "priorityDelivery" ` +
' ,( SELECT ESTVENDAPRECLIENTE.CPF FROM ESTVENDAPRECLIENTE WHERE ESTVENDAPRECLIENTE.IDCART = ESTPREVENDAC.ID AND ROWNUM = 1 ) as "cpfPreCustomer" ' +
' ,( SELECT ESTVENDAPRECLIENTE.NOME FROM ESTVENDAPRECLIENTE WHERE ESTVENDAPRECLIENTE.IDCART = ESTPREVENDAC.ID AND ROWNUM = 1 ) as "namePreCustomer" ' +
' FROM PCORCAVENDAC, ESTPREVENDAC ' +
' WHERE PCORCAVENDAC.NUMORCA = ESTPREVENDAC.NUMORCA ' +
' AND PCORCAVENDAC.NUMORCA = :1', [preOrderId]);
if (preOrder.length == 0) {
throw new HttpException(`Orçamento não foi localizado`, HttpStatus.NOT_FOUND);
}
if (preOrder.preOrderFinish == 'S') {
throw new HttpException(`Orçamento já utilizado, não pode sofre alterações. Número do pedido gerado: ${preOrder.orderId}`, HttpStatus.BAD_REQUEST);
}
await queryRunner.query("BEGIN ESK_VENDA.ATUALIZAR_PRECO_VENDA(:idcart, :paymentPlanId); END;",
[preOrder[0].cartId, preOrder[0].paymentPlanId]);
const invoiceStores = await this.listsService.GetStoreAll();
const invoiceStore = await invoiceStores.find(data => data.id === preOrder[0].invoiceStore);
const customer = await this.customerService.findCustomerById(preOrder[0].customerId);
const billinds = await this.listsService.GetBilling(preOrder[0].customerId);
const partners = await this.listsService.GetPartners();
const preCustomer = await this.listsService.GetPreCustomer(preOrder[0].cartId);
let address: any;
if (preOrder[0].addressId > 0) {
address = await this.addressCustomerService.getAddress(preOrder[0].customerId, preOrder[0].addressId);
}
// const address = await this.addressCustomerService.getAddress(preOrder[0].customerId, preOrder[0].addressId);
const billing = billinds.find(data => data.codcob === preOrder[0].billindId);
const paymentPlans = await this.listsService.GetPaymentPlan((billing !== null && billing !== undefined) ? billing.codcob : '9999');
const paymentPlan = paymentPlans.find(data => data.codplpag === preOrder[0].paymentPlanId);
const partner = partners.find(data => data.id === preOrder[0].partnerId);
return {
cartId: preOrder[0].cartId, invoiceStore: invoiceStore, customer: customer, partner: partner ?? null,
paymentPlan: paymentPlan ?? null, billing: billing ?? null, address: address ?? null,
notification: preOrder[0].notification, notification1: preOrder[0].notification1, notification2: preOrder[0].notification2,
notificationDelivery1: preOrder[0].notificationDelivery1, notificationDelivery2: preOrder[0].notificationDelivery2,
notificationDelivery3: preOrder[0].notificationDelivery3, deliveryDate: preOrder[0].deliveryDate,
priorityDelivery: preOrder[0].priorityDelivery, preCustomer: preCustomer
}
} finally {
await queryRunner.release();
await connection.close();
}
}
async getItensPreOrder(idPreOrder: number) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
let sql = '';
try {
sql = ` SELECT PCORCAVENDAI.CODPROD as "productId", PCPRODUT.DESCRICAO as "description", ` +
` PCPRODUT.EMBALAGEM as "package", ` +
` PCORCAVENDAI.COMPLEMENTO as "color" , ` +
` PCORCAVENDAI.AMBIENTE as "local", ` +
` PCORCAVENDAI.QT as "quantity", PCORCAVENDAI.PVENDA as "price", ` +
` ( PCORCAVENDAI.QT * PCORCAVENDAI.PVENDA ) as "subTotal" ` +
` FROM PCORCAVENDAI, PCORCAVENDAC, PCPRODUT ` +
` WHERE PCORCAVENDAI.CODPROD = PCPRODUT.CODPROD ` +
` AND PCORCAVENDAI.NUMORCA = PCORCAVENDAC.NUMORCA ` +
` AND PCORCAVENDAC.NUMORCA = :NUMORCA ` +
` ORDER BY PCORCAVENDAI.NUMSEQ `;
const result = await queryRunner.query(sql, [idPreOrder]);
return result;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async createPreCustomer(cart: Cart) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
// const preCustomer = await queryRunner.query(`SELECT ESTVENDAPRECLIENTE.CPF FROM ESTVENDAPRECLIENTE ` +
// ` WHERE IDCART = :1 AND CPF = :2`, [cart.id, cart.preCustomerDocument]);
const sqlInsert = ` INSERT INTO ESTVENDAPRECLIENTE ( CPF, IDCART, NOME, TELEFONE, DTCADASTRO, CODUSUR ) ` +
` VALUES ( REGEXP_REPLACE(:CPF, '[^0-9]', '') , :IDCART, :NOME, :TELEFONE, SYSDATE, :CODUSUR ) `;
await queryRunner.query(sqlInsert, [cart.preCustomerDocument,
cart.id, cart.preCustomerName, cart.preCustomerPhone, cart.idSeller]);
await queryRunner.commitTransaction();
} catch (err) {
await queryRunner.rollbackTransaction();
throw err;
}
finally {
await queryRunner.release();
await connection.close();
}
}
}

View File

@@ -0,0 +1,283 @@
import { Body, Controller, Get, HttpException, HttpStatus, Param, Post, Query, Req } from '@nestjs/common';
import { FilterProduct } from 'src/domain/models/filter-product.model';
import { Notify } from 'src/domain/models/notify.model';
import { Rupture } from 'src/domain/models/rupture.model';
import { SalesService } from './sales.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Sales')
@Controller('api/v1/sales')
export class SalesController {
constructor(private salesService: SalesService) { }
@Get('products')
async get(@Req() request: any) {
let pageNumber = 1;
let sizeCount = 500;
let store = '99';
console.log(request.headers);
console.log(request.query);
try {
if (request.headers['x-page'])
pageNumber = request.headers['x-page'];
if (request.headers['x-size-count'])
sizeCount = request.headers['x-size-count'];
if (request.headers['x-store'])
store = request.headers['x-store'];
return await this.salesService.GetProducts2(store, sizeCount, pageNumber, request.query);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('departments')
async getDepartments() {
try {
return await this.salesService.getDepartments();
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('category')
async getCategory() {
try {
return await this.salesService.getCategory();
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('placesinterior')
async getPlacesInterior() {
try {
return await this.salesService.getPlacesInterior();
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('products/:search')
async searchProducts(@Param('search') search: string, @Req() request: any) {
console.log("pesquisando produtos...");
let pageNumber = 1;
let sizeCount = 500;
let store = '99';
try {
if (request.headers['x-page'])
pageNumber = request.headers['x-page'];
if (request.headers['x-size-count'])
sizeCount = request.headers['x-size-count'];
if (request.headers['x-store'])
store = request.headers['x-store'];
return await this.salesService.searchProduct(store, search, sizeCount, pageNumber);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('product/category/:url')
async searchByDepartment(@Param('url') urlDepartment: string, @Req() request: any) {
console.log("pesquisando produtos...");
let pageNumber = 1;
let sizeCount = 500;
let store = '99';
try {
if (request.headers['x-page'])
pageNumber = request.headers['x-page'];
if (request.headers['x-size-count'])
sizeCount = request.headers['x-size-count'];
if (request.headers['x-store'])
store = request.headers['x-store'];
return await this.salesService.searchByDepartment(store, sizeCount, pageNumber, urlDepartment);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('product/category/:urlDepartament/:urlSection')
async searchBySection(@Param('urlDepartament') urlDepartment: string, @Param('urlSection') urlSection: string, @Req() request: any) {
let pageNumber = 1;
let sizeCount = 500;
let store = '99';
try {
if (request.headers['x-page'])
pageNumber = request.headers['x-page'];
if (request.headers['x-size-count'])
sizeCount = request.headers['x-size-count'];
if (request.headers['x-store'])
store = request.headers['x-store'];
return await this.salesService.searchBySection(store, sizeCount, pageNumber, urlDepartment, urlSection);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('product/category/:urlDepartament/:urlSection/:urlCategory')
async searchByCategory(@Param('urlDepartament') urlDepartment: string, @Param('urlSection') urlSection: string,
@Param('urlCategory') urlCategory: string, @Req() request: any) {
let pageNumber = 1;
let sizeCount = 500;
let store = '99';
try {
if (request.headers['x-page'])
pageNumber = request.headers['x-page'];
if (request.headers['x-size-count'])
sizeCount = request.headers['x-size-count'];
if (request.headers['x-store'])
store = request.headers['x-store'];
return await this.salesService.searchByCategory(store, sizeCount, pageNumber, urlDepartment, urlSection, urlCategory);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Post('products')
async getProductsByFilter(@Req() request: any, @Body() filter: FilterProduct) {
let pageNumber = 1;
let sizeCount = 500;
console.log(filter);
let store = '99';
try {
if (request.headers['x-page'])
pageNumber = request.headers['x-page'];
if (request.headers['x-size-count'])
sizeCount = request.headers['x-size-count'];
if (request.headers['x-store'])
store = request.headers['x-store'];
// return await this.salesService.GetProducts2(store, sizeCount, pageNumber, filter);
return await this.salesService.searchProduct2(store, sizeCount, pageNumber, filter);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('product/:id')
async getProduct(@Req() request: any, @Param('id') id: number) {
let store = '99';
try {
if (request.headers['x-store'])
store = request.headers['x-store'];
return await this.salesService.GetProduct(store, id);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('product/bytogether/:id')
async GetProductsBuyTogether(@Req() request: any, @Param('id') id: number) {
let store = '99';
try {
if (request.headers['x-store'])
store = request.headers['x-store'];
return await this.salesService.GetProductsBuyTogether(store, id);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('stock/:storeid/:id')
async getStock(@Param('storeid') storeId: string, @Param('id') id: number) {
try {
return await this.salesService.GetStocks(storeId, id);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('installment/:id')
async getSaleIntallment(@Req() request: any, @Query() query, @Param('id') id: number) {
let store = '99';
let quantity = 1;
try {
if (request.headers['x-store'])
store = request.headers['x-store'];
if (query['quantity']) {
quantity = Number.parseFloat(query['quantity']);
}
return await this.salesService.GetSaleInstallment(store, id, quantity);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('delivery/:cpf')
async getDelivery(@Param('cpf') cpf: string) {
try {
return await this.salesService.GetDelivery(cpf);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('deliveryDays/:createDate/:invoiceStoreId/:placeId/:cartId')
async deliveryDays(@Param('createDate') createDate: string,
@Param('invoiceStoreId') invoiceStoreId: string,
@Param('placeId') placeId: string,
@Param('cartId') cartId: string) {
return this.salesService.getDeliveryTime(createDate, invoiceStoreId, placeId, cartId);
}
@Post('notify')
async createNotification(@Body() data: Notify) {
try {
return await this.salesService.createNotification(data);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Post('rupture')
async createRupture(@Body() data: Rupture) {
try {
return await this.salesService.createRuptura(data);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Post('calculatedeliverytaxorder')
async calcDeliveryTaxOrder(
@Body() dataDeliveryOrder: any) {
try {
return await this.salesService.calculateDeliveryTaxOrder(dataDeliveryOrder);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('analisevenda/:id')
async analiseVendaRca(@Param('id') id: number) {
try {
return await this.salesService.GetAnaliseVenda(id);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('historicovenda/:id')
async historicoVendaRca(@Param('id') id: number) {
try {
return await this.salesService.GetHistoricoVendas(id);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Get('calculatedeliverytax/:cartid/:ibgeCode')
async calculatedeliverytax(
@Param('cartid') cartId: string,
@Param('ibgeCode') ibgeCode: string) {
try {
return await this.salesService.calculateDeliveryTax(cartId, ibgeCode);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
}

View File

@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { SalesController } from './sales.controller';
import { SalesService } from './sales.service';
import { CustomerService } from '../customer/customer.service';
@Module({
imports: [],
controllers: [SalesController],
providers: [SalesService, CustomerService],
})
export class SalesModule {}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
import { Body, Controller, Delete, Get, HttpException, HttpStatus, Param, Post, Put, Req } from '@nestjs/common';
import { ShoppingItem } from 'src/domain/models/shopping-item.model';
import { ShoppingService } from './shopping.service';
import { ResultModel } from '../../domain/models/result.model';
import { OrderDiscount } from 'src/domain/models/order-discount.model';
import { OrderTaxDelivery } from 'src/domain/models/order-taxdelivery.model';
import { LogOrder } from 'src/domain/models/log-order.model';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Shopping')
@Controller('api/v1/shopping')
export class ShoppingController {
constructor(private shoppingService: ShoppingService){}
@Get('cart/:id')
async getCart(@Param('id') id: string){
try {
const cart = await this.shoppingService.GetItensCart(id);
if (cart == null || cart.length == 0)
throw new HttpException("Carrinho de compras não encontrado", HttpStatus.NOT_FOUND);
return cart;
} catch (error) {
const status = error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR;
throw new HttpException(error.message, status);
}
}
@Get(':id')
async getPreVenda(@Param('id') id: string ){
try {
const cart = await this.shoppingService.getShopping(id);
if (cart == null )
throw new HttpException("Carrinho de compras não encontrado", HttpStatus.NOT_FOUND);
return cart;
} catch (error) {
const status = error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR;
throw new HttpException(error.message, status);
}
}
@Get('cart/:idcart/item/:idProduct/tipoentrega/:deliveryType')
async getItemCart(@Req() request, @Param('idCart') idCart: string,
@Param('idProduct') idProduct: string, @Param('deliveryType') deliveryType: string){
let store = '99';
try {
if (request.headers['x-store'])
store = request.headers['x-store'];
const cart = await this.shoppingService.getItemCart(idCart, idProduct, store, deliveryType);
if (cart == null )
throw new HttpException("Item não foi encontrado no carrinho de compras.", HttpStatus.NOT_FOUND);
return cart;
} catch (error) {
const status = error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR;
throw new HttpException(error.message, status);
}
}
@Get('cart/lot/:productId/:customerId')
async getLotProduct( @Req() request, @Param('productId') productId: number,
@Param('customerId') customerId: number ) {
let store = '99';
try {
if (request.headers['x-store'])
store = request.headers['x-store'];
const lotsProduct = await this.shoppingService.getLotProduct(productId, customerId);
return lotsProduct;
} catch (error) {
const status = error.status == 404 ? error.status : HttpStatus.INTERNAL_SERVER_ERROR;
throw new HttpException(error.message, status);
}
}
@Post('item')
async createItemShopping(@Body() item: ShoppingItem){
console.log('createItemShopping')
try {
return await this.shoppingService.createItemCart(item);
} catch (error) {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
}
@Post('log')
async logOrderShopping(@Body() logOrder: LogOrder){
try {
console.log('logOrderShopping')
return await this.shoppingService.createLogShopping(logOrder);
} catch (error) {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
}
@Put('item')
async updateQuantityItem(@Body() item: ShoppingItem){
console.log(item);
try {
if (item.id == null){
throw new HttpException('Item sem Id informado, faça a inclusão do item no carrinho.', HttpStatus.BAD_REQUEST);
}
const itemCreate = await this.shoppingService.updateItem(item);
return itemCreate;
} catch (error) {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
}
@Put('item/discount')
async updatePriceItem(@Body() item: ShoppingItem){
console.log(item);
try {
if (item.id == null){
throw new HttpException('Item sem Id informado, faça a inclusão do item no carrinho.', HttpStatus.BAD_REQUEST);
}
const itemCreate = await this.shoppingService.updatePrice(item);
return itemCreate;
} catch (error) {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
}
@Put('order/discount')
async applyDiscountOrder(@Body() order: OrderDiscount) {
try {
const itensOrder = await this.shoppingService.applyDiscountOrder(order);
return itensOrder;
} catch (error) {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
}
@Put('order/tax')
async applyTaxDeOrder(@Body() order: OrderTaxDelivery) {
try {
const orderTax = await this.shoppingService.applyTaxDelivery(order);
return orderTax;
} catch (error) {
console.log(error);
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
}
@Delete('item/delete/:id')
async deleteItem(@Param('id') id: string){
try {
await this.shoppingService.deleteItem(id);
return new ResultModel(true, 'Item excluído com sucesso!', id, null,);
} catch (error) {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
}
@Put('update/payment/:id')
async updateItemsShopping(@Param('id') id: string, @Body() payment: any) {
try {
console.log('Atualizando preços (controller).')
const idPaymentPlan = payment.idPaymentPlan;
await this.shoppingService.updatePriceShopping(id, idPaymentPlan);
return new ResultModel(true, 'Preços atualizados com sucesso!', {}, null);
} catch (err) {
throw new HttpException(new ResultModel(false, err.errors.message, {}, err),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

View File

@@ -0,0 +1,17 @@
import { ShoppingService } from './shopping.service';
import { ShoppingController } from './shopping.controller';
import { Module } from '@nestjs/common';
import { UserService } from 'src/Auth/services/user.service';
@Module({
imports: [
UserService,
],
controllers: [
ShoppingController,],
providers: [
ShoppingService,
UserService
],
})
export class ShoppingModule { }

View File

@@ -0,0 +1,717 @@
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { ShoppingItens } from 'src/domain/entity/tables/estprevendai.entity';
import { OrderDiscount } from 'src/domain/models/order-discount.model';
import { ShoppingItem } from 'src/domain/models/shopping-item.model';
import { Connection, QueryRunner } from 'typeorm';
import { UserService } from 'src/Auth/services/user.service';
import { Shopping } from 'src/domain/entity/tables/estprevendac.entity';
import { OrderTaxDelivery } from 'src/domain/models/order-taxdelivery.model';
import { connectionOptions } from 'src/configs/typeorm.config';
import { LogOrder } from 'src/domain/models/log-order.model';
@Injectable()
export class ShoppingService {
constructor(private userService: UserService
) { }
async GetItensCart(idcart: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const product = await queryRunner.manager
.getRepository(ShoppingItens)
.createQueryBuilder('estprevendai')
.where("\"estprevendai\".idcart = :idcart", { idcart: idcart })
.andWhere("\"estprevendai\".dtcancel is null")
.orderBy("\"estprevendai\".dtinclusao")
.getMany();
return product;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
/* async createSale(cart: Cart){
try
{
let sale = new Sale();
sale.id = cart.idShopping;
sale.codcli = cart.idCustomer;
sale.codusur = cart.idSeller;
sale.codcob = cart.billingCode;
sale.codendcli = 0;
sale.codplpag = cart.idPayment;
sale.vlfrete = cart.valueShipping;
await getConnection()
.createQueryBuilder()
.insert()
.into(Shopping)
.values(createShopping)
.execute();
return createShopping;
} catch ( erro ) {
console.log(erro);
throw new HttpException("Erro ao criar item no carrinho de compras", HttpStatus.INTERNAL_SERVER_ERROR);
}
}*/
async getItemCart(idCart: string, idProduct: string, store: string, deliveryType: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const item = await queryRunner.manager
.getRepository(ShoppingItens)
.createQueryBuilder('estprevendai')
.where("\"estprevendai\".idcart = :idcart", { idcart: idCart })
.andWhere("\"estprevendai\".codprod = :idProduct", { idProduct: idProduct })
.andWhere("\"estprevendai\".tipoentrega = :tipoentrega", { tipoentrega: deliveryType })
.andWhere("( \"estprevendai\".codfilialretira = :store OR :store = '99' )", { store: store })
.andWhere("\"estprevendai\".dtcancel is null")
.getOne();
console.log(item);
return item;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async getItemCartById(idCart: string, id: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const item = await queryRunner.manager
.getRepository(ShoppingItens)
.createQueryBuilder('estprevendai')
.where("\"estprevendai\".idcart = :idcart", { idcart: idCart })
.andWhere("\"estprevendai\".id = :id", { id: id })
.andWhere("\"estprevendai\".dtcancel is null")
.getOne();
console.log(item);
return item;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async createItemCart(itemShopping: ShoppingItem) {
console.log(JSON.stringify(itemShopping));
const connectionDb = new Connection(connectionOptions);
await connectionDb.connect();
//const connection = getConnection();
const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect();
console.log('Incluindo item 01 - ' + Date.now().toString());
await queryRunner.startTransaction();
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const uuid = require('uuid');
const idItem = uuid.v4();
let idCart = "";
if (itemShopping.idCart == null || itemShopping.idCart == '')
idCart = uuid.v4();
else
idCart = itemShopping.idCart;
console.log('Incluindo item 02 - ' + Date.now().toString());
const cart = await queryRunner.manager
.getRepository(Shopping)
.createQueryBuilder('estprevendac')
.where("\"estprevendac\".id = :id", { id: idCart })
.getOne();
console.log('Incluindo item 03 - ' + Date.now().toString());
if (cart == null) {
await this.createShopping(idCart, itemShopping.invoiceStore, itemShopping.seller, queryRunner);
}
console.log('Incluindo item 04 - ' + Date.now().toString());
const item = await this.getItemCartById(itemShopping.idCart, itemShopping.id);
console.log('Incluindo item 05 - ' + Date.now().toString());
if (item) {
itemShopping.id = item.id;
this.updateItem(itemShopping);
return await this.getItemCartById(itemShopping.idCart, itemShopping.id);
}
console.log('Incluindo item 06 - ' + Date.now().toString());
const recordItens = await queryRunner.query(`SELECT COUNT(1) as "recordNo" FROM ESTPREVENDAI WHERE IDCART = '${itemShopping.idCart}'`);
let numSeq = 1;
if (recordItens != null && recordItens.length > 0) {
numSeq = recordItens[0].recordNo + 1;
}
const sqlInsertitem = 'INSERT INTO ESTPREVENDAI ( ID, IDCART, NUMSEQ, CODPROD, QT, PVENDA, DTINCLUSAO, NOMEECOMMERCE, URLIMAGEM, TIPOPRODUTO, CODFILIALRETIRA, TIPOENTREGA, ' +
' CODUSUR, PERCDESC, CODFUNCDESC, PTABELA, VLDESCONTO, PRECOPROMOCIONAL, MULTIPLO, DESCRICAOAUXILIAR, DESCRICAO, MARCA, ' +
' PRECOPROMOCAO, CODAUXILIAR, VLCUSTOFIN, VLCUSTOREAL, VLCUSTOREP, PERCACRESCIMO, QTACRESCIMO, BASETINTOMETRICO, ' +
' LINHATINTOMETRICO, CORTINTOMETRICO, LITRAGEM, LETRATINTOMETRICO, AMBIENTE, PRODUTOCOMPREJUNTO ) ' +
' VALUES ( :ID, :IDCART, :NUMSEQ, :CODPROD, :QT, :PVENDA, SYSDATE, :NOMEECOMMERCE, :URLIMAGEM, :TIPOPRODUTO, :CODFILIALRETIRA, :TIPOENTREGA, ' +
' :CODUSUR, :PERCDESC, :CODFUNCDESC, :PTABELA, :VLDESCONTO, :PRECOPROMOCIONAL, :MULTIPLO, :DESCRICAOAUXILIAR, :DESCRICAO, :MARCA, ' +
' :PRECOPROMOCAO, :CODAUXILIAR, :VLCUSTOFIN, :VLCUSTOREAL, :VLCUSTOREP, :PERCACRESCIMO, :QTACRESCIMO, :BASETINTOMETRICO, ' +
' :LINHATINTOMETRICO, :CORTINTOMETRICO, :LITRAGEM, :LETRATINTOMETRICO, :AMBIENTE, :PRODUTOCOMPREJUNTO )';
let listPrice = 0;
if (itemShopping.base === 'S') {
listPrice = itemShopping.price;
} else {
listPrice = (itemShopping.promotion > 0) ? itemShopping.promotion : itemShopping.listPrice;
}
await queryRunner.query(sqlInsertitem, [
idItem, //ID
idCart, //IDCART
numSeq, //NUMSEQ
itemShopping.idProduct, //CODPROD
itemShopping.quantity, //QT
itemShopping.price, //PVENDA
itemShopping.description, //NOMEECOMMERCE
itemShopping.image, //URLIMAGE
itemShopping.productType, //TIPOPRODUTO
itemShopping.stockStore, //CODFILIALRETIRA
itemShopping.deliveryType, //TIPOENTREGA
itemShopping.seller, //CODUSUR
itemShopping.discount, //PERCDESC
itemShopping.userDiscount, //CODFUNCDESC
listPrice, //PTABELA
itemShopping.discountValue, //VALORDESCONTO
(itemShopping.promotion > 0) ? 'S' : 'N', //PRECOPROMOCIONAL
itemShopping.mutiple, //MULTIPLO
itemShopping.auxDescription, //DESCRICAOAUXILIAR
itemShopping.smallDescription, //DESCRICAO
itemShopping.brand, //MARCA
itemShopping.promotion, //PRECOPROMOCAO
itemShopping.ean, //CODAUXILIAR
0, //VLCUSTOFIN
0, //VLCUSTOREAL
0, //VLCUSTOREP
itemShopping.percentUpQuantity, //PERCARESCIMO
itemShopping.upQuantity, //QTACRESCIMO
itemShopping.base, //BASEINTOMETRICO
itemShopping.line, //LINHATINTOMETRICO
(itemShopping.base == 'S') ? itemShopping.auxDescription : null, //CORTINTOMETRICO
itemShopping.can, //LITRAGEM
itemShopping.letter, //LETRATINTOMETRICO
itemShopping.environment, //AMBIENTE
itemShopping.productTogether, //PRODUTOCOMPREJUNTO
]);
const createItemShopping = new ShoppingItens();
createItemShopping.id = idItem;
createItemShopping.description = itemShopping.description;
createItemShopping.smallDescription = itemShopping.smallDescription;
createItemShopping.image = itemShopping.image;
createItemShopping.productType = itemShopping.productType;
createItemShopping.idCart = idCart;
createItemShopping.idProduct = itemShopping.idProduct;
if (itemShopping.base === 'S') {
createItemShopping.listPrice = itemShopping.price;
} else {
createItemShopping.listPrice = (itemShopping.promotion > 0) ? itemShopping.promotion : itemShopping.listPrice;
}
createItemShopping.price = itemShopping.price;
createItemShopping.quantity = itemShopping.quantity;
createItemShopping.deliveryType = itemShopping.deliveryType;
createItemShopping.stockStore = itemShopping.stockStore;
createItemShopping.seller = itemShopping.seller;
createItemShopping.discount = itemShopping.discount;
createItemShopping.discountValue = (itemShopping.listPrice * itemShopping.discount / 100);
createItemShopping.promotion = itemShopping.promotion;
createItemShopping.mutiple = itemShopping.mutiple;
createItemShopping.auxDescription = itemShopping.auxDescription;
createItemShopping.brand = itemShopping.brand;
createItemShopping.ean = itemShopping.ean;
createItemShopping.percentUpQuantity = itemShopping.percentUpQuantity;
createItemShopping.upQuantity = itemShopping.upQuantity;
createItemShopping.base = itemShopping.base;
createItemShopping.line = itemShopping.line;
createItemShopping.can = itemShopping.can;
createItemShopping.letter = itemShopping.letter;
createItemShopping.color = (itemShopping.base == 'S') ? itemShopping.auxDescription : null;
createItemShopping.productTogether = itemShopping.productTogether;
createItemShopping.createDate = new Date();
console.log('Incluindo item 07 - ' + Date.now().toString());
// await queryRunner.manager.save(createItemShopping);
console.log('Incluindo item 08 - ' + Date.now().toString());
await queryRunner.commitTransaction();
console.log('Incluindo item 09 - ' + Date.now().toString());
await this.calculateProfitShoppping(idCart, queryRunner);
await this.updateTotalShopping(idCart);
return createItemShopping;
} catch (erro) {
console.log(erro);
await queryRunner.rollbackTransaction();
throw new HttpException("Erro ao criar item no carrinho de compras", HttpStatus.INTERNAL_SERVER_ERROR);
} finally {
await queryRunner.release();
await connectionDb.close();
}
}
async createShopping(idCart: string, storeId: string, sellerId: number, queryRunner: QueryRunner) {
const sql = 'INSERT INTO ESTPREVENDAC ( ID, CODFILIAL, DATA, CODUSUR, VLPEDIDO, VLDESCONTO, VLTAXAENTREGA, TIPOPRIORIDADEENTREGA ) ' +
' VALUES ( :1, :2, TRUNC(SYSDATE), :3, :4, :5, :6, :7 )';
await queryRunner.query(sql, [
idCart,
storeId,
sellerId,
0,
0,
0,
'B'
]);
}
async updateTotalShopping(idCart: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const prevenda = await queryRunner
.query('SELECT SUM(ESTPREVENDAI.PTABELA * ESTPREVENDAI.QT) as "vltabela" ' +
' ,SUM(ESTPREVENDAI.PVENDA * ESTPREVENDAI.QT) as "vlatend" ' +
' ,SUM(ESTPREVENDAI.VLDESCONTO * ESTPREVENDAI.QT) as "vldesconto" ' +
' ,SUM(PCPRODUT.PESOBRUTO * ESTPREVENDAI.QT) as "totpeso" ' +
' FROM ESTPREVENDAI, PCPRODUT ' +
' WHERE ESTPREVENDAI.CODPROD = PCPRODUT.CODPROD ' +
' AND ESTPREVENDAI.IDCART = :1', [idCart]);
if (prevenda != null) {
const sql = ` UPDATE ESTPREVENDAC SET ` +
` VLPEDIDO = :1 ` +
` ,VLDESCONTO = :2 ` +
` ,TOTPESO = :3 ` +
` ,VLTABELA = :4 ` +
` WHERE ID = :5 `;
await queryRunner.query(sql, [
prevenda[0].vlatend,
prevenda[0].vldesconto,
prevenda[0].totpeso,
prevenda[0].vltabela,
idCart
]);
}
await queryRunner.commitTransaction();
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async updateItem(itemShopping: ShoppingItem) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sql = ' UPDATE ESTPREVENDAI SET ' +
' PVENDA = :1 ' +
' ,PTABELA = :2 ' +
' ,QT = :3 ' +
' ,TIPOENTREGA = :4 ' +
' ,CODFILIALRETIRA = :5 ' +
' ,DESCRICAOAUXILIAR = :6 ' +
' ,AMBIENTE = :7 ' +
' WHERE ID = :8 ';
await queryRunner.query(sql, [
itemShopping.price,
itemShopping.listPrice,
itemShopping.quantity,
itemShopping.deliveryType,
itemShopping.stockStore,
itemShopping.auxDescription,
itemShopping.environment,
itemShopping.id
]);
await queryRunner.commitTransaction();
await this.updateTotalShopping(itemShopping.idCart);
await this.calculateProfitShoppping(itemShopping.idCart, queryRunner);
} catch (erro) {
await queryRunner.rollbackTransaction();
throw erro;
} finally {
await queryRunner.release();
await connection.close();
}
}
async updatePrice(itemShopping: ShoppingItem) {
console.log(itemShopping);
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sql = 'UPDATE ESTPREVENDAI SET ' +
' PVENDA = :1 ' +
' ,PERCDESC = :2 ' +
' ,VLDESCONTO = :3 ' +
' ,CODFUNCDESC = :4 ' +
' WHERE ID = :5 ';
await queryRunner.query(sql, [
itemShopping.price,
itemShopping.discount,
Number.parseFloat((itemShopping.listPrice * itemShopping.discount / 100).toFixed(2)),
itemShopping.userDiscount,
itemShopping.id
]);
// await queryRunner.manager
// .createQueryBuilder()
// .update(ShoppingItens)
// .set({
// price: itemShopping.price,
// discount: itemShopping.discount,
// discountValue: Number.parseFloat((itemShopping.listPrice * itemShopping.discount / 100).toFixed(2)),
// userDiscount: itemShopping.userDiscount
// })
// .where("\"ESTPREVENDAI\".id = :id", { id: itemShopping.id })
// .execute();
await queryRunner.commitTransaction();
await this.calculateProfitShoppping(itemShopping.idCart, queryRunner);
await this.updateTotalShopping(itemShopping.idCart);
return itemShopping;
} catch (erro) {
await queryRunner.rollbackTransaction();
throw erro;
} finally {
await queryRunner.release();
await connection.close();
}
}
async deleteItem(id: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const item = await queryRunner.manager
.getRepository(ShoppingItens)
.createQueryBuilder('estprevendai')
.where("\"estprevendai\".id = :id", { id })
.getOne();
if (item != null) {
const sql = 'DELETE FROM ESTPREVENDAI WHERE ID = :1';
await queryRunner.query(sql, [
id
]);
}
await queryRunner.commitTransaction();
await this.updateTotalShopping(item.idCart);
await this.calculateProfitShoppping(item.idCart, queryRunner);
} catch (erro) {
await queryRunner.rollbackTransaction();
throw erro;
} finally {
await queryRunner.release();
await connection.close();
}
}
async applyDiscountOrder(order: OrderDiscount) {
console.log('Desconto pedido: ' + JSON.stringify(order));
const items = await this.GetItensCart(order.id);
const discountAuthUser = await this.userService.discountUser(order.idUserAuth);
console.log(discountAuthUser);
if (discountAuthUser < order.percentDiscount) {
return new HttpException('Percentual de desconto acima do permido para o usuário.', HttpStatus.FORBIDDEN);
}
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
let listPriceTotal = 0;
let discountTotal = 0;
const sql = 'UPDATE ESTPREVENDAI SET ' +
' PVENDA = :1 ' +
' ,PERCDESC = :2 ' +
' ,VLDESCONTO = :3 ' +
' ,CODFUNCDESC = :4 ' +
' WHERE ID = :5 ';
items.filter(item => item.promotion == null || item.promotion == 0)
.forEach(async (item) => {
const price = (item.listPrice * (1 - (order.percentDiscount / 100))).toFixed(2);
listPriceTotal += (item.listPrice * item.quantity);
discountTotal += ((Number.parseFloat(item.listPrice.toFixed(2)) - Number.parseFloat(price)) * item.quantity);
await queryRunner.query(sql, [
Number.parseFloat(price),
order.percentDiscount,
(item.listPrice - Number.parseFloat(price)),
order.idUserAuth,
item.id
]);
// await queryRunner.manager
// .createQueryBuilder()
// .update(ShoppingItens)
// .set({
// price: Number.parseFloat(price),
// discount: order.percentDiscount,
// discountValue: (item.listPrice - Number.parseFloat(price)),
// userDiscount: order.idUserAuth
// })
// .where("\"ESTPREVENDAI\".id = :id", { id: item.id })
// .execute();
});
console.log('total de desconto: ' + discountTotal);
const sqlOrder = 'UPDATE ESTPREVENDAC SET ' +
' VLPEDIDO = :1 ' +
' ,VLDESCONTO = :2 ' +
' WHERE ID = :3 ';
await queryRunner.query(sqlOrder, [
listPriceTotal,
discountTotal,
order.id
]);
// await queryRunner.manager
// .createQueryBuilder()
// .update(Shopping)
// .set({
// vlpedido: listPriceTotal,
// vldesconto: discountTotal,
// })
// .where("\"ESTPREVENDAC\".id = :id", { id: order.id })
// .execute();
await queryRunner.commitTransaction();
await this.calculateProfitShoppping(order.id, queryRunner);
await this.updateTotalShopping(order.id);
} catch (err) {
console.log(err);
await queryRunner.rollbackTransaction();
throw err;
}
finally {
await queryRunner.release();
await connection.close();
}
return await this.GetItensCart(order.id);
}
async applyTaxDelivery(order: OrderTaxDelivery) {
/* const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
// await queryRunner.startTransaction();
try {
// const sql = ' UPDATE ESTPREVENDAC SET ' +
// ' VLTAXAENTREGA = :1 ' +
// ' ,CODFORNECFRETE = :2 ' +
// ' ,CODTABELAFRETE = :3 ' +
// ' WHERE ID = :4';
const sql = 'BEGIN ESK_VENDA.ATULIZAR_DADOS_PREVENDA(:1, :2, :3, :4); END;'
await queryRunner.query(sql, [
order.taxValue,
order.carrierId,
order.deliveryTaxId,
order.id
]);
// await queryRunner.commitTransaction();
} catch (err) {
// await queryRunner.rollbackTransaction();
// console.log(err);
throw err;
}
finally {
await queryRunner.release();
await connection.close();
} */
return await this.GetItensCart(order.id.toString());
}
async getShopping(id: string) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const shopping = await queryRunner.manager
.getRepository(Shopping)
.createQueryBuilder('estprevendac')
.where("\"estprevendac\".id = :id", { id })
.getOne();
return shopping;
} catch (error) {
throw error;
} finally {
await queryRunner.release();
await connection.close();
}
}
async updatePriceShopping(idCart: string, idPaymentPlan: number) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
console.log('atualizando preços.');
await queryRunner
.query("BEGIN ESK_VENDA.ATUALIZAR_PRECO_VENDA(:idCart, :idPaymentPlan); END;", [idCart, idPaymentPlan]);
await this.calculateProfitShoppping(idCart, queryRunner);
await queryRunner.commitTransaction();
return true;
} catch (err) {
await queryRunner.rollbackTransaction();
console.log(err);
throw err;
// since we have errors let's rollback changes we made
} finally {
// you need to release query runner which is manually created:
await queryRunner.release();
await connection.close();
}
}
async calculateProfitShoppping(id: string, queryRunner: QueryRunner) {
try {
console.log('Calculando margem da prevenda - id: ' + id);
await queryRunner.query('BEGIN ESK_VENDA.calcular_cmv_prevenda(:1); END;', [id]).catch(err => console.log(err));
} catch (erro) {
throw erro;
}
}
async createLogShopping(logOrder: LogOrder) {
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sqlInsert = "INSERT INTO ESTLOGPEDIDOWEB ( IDCART, DATA, CODFUNCLOGADO, ACAO, CODFUNCAUTOR, OBSERVACAO ) " +
" VALUES ( :IDCART, SYSDATE, :CODFUNCAUTOR, :ACAO, :CODFUNCAUTOR, :OBSERVACAO )";
await queryRunner
.query(sqlInsert, [
logOrder.idCart,
logOrder.idUser,
logOrder.action,
logOrder.iduserAuth,
logOrder.notation
]);
await queryRunner.commitTransaction();
return true;
} catch (err) {
console.log(err);
await queryRunner.rollbackTransaction();
throw err;
} finally {
await queryRunner.release();
await connection.close();
}
}
async getLotProduct(productId: number, customerId: number) {
const sqlQueryLot = `SELECT LOTES_WMS.CODFILIAL as "storeId",
LOTES_WMS.CODPROD as "customerId",
LOTES_WMS.NUMLOTE as "lotProduct",
SUM(LOTES_WMS.QT) as "quantitySale",
MAX(ESTOQUE_WMS.QT) as "quantityStock"
FROM LOTES_WMS, ESTOQUE_WMS, PCPEDC
WHERE LOTES_WMS.NUMPED = PCPEDC.NUMPED
AND PCPEDC.DATA = ( SELECT MAX(P.DATA) FROM PCPEDC P, PCPEDI I
WHERE P.CODCLI = PCPEDC.CODCLI
AND P.NUMPED = I.NUMPED
AND I.CODPROD = LOTES_WMS.CODPROD )
AND ESTOQUE_WMS.EMPRESA_ERP = LOTES_WMS.CODFILIAL
AND ESTOQUE_WMS.PRODUTO_ERP = LOTES_WMS.CODPROD
AND ESTOQUE_WMS.LOTE = LOTES_WMS.NUMLOTE
AND PCPEDC.CODCLI = ${customerId}
AND ESTOQUE_WMS.PRODUTO_ERP = ${productId}
GROUP BY LOTES_WMS.CODFILIAL, LOTES_WMS.CODPROD, LOTES_WMS.NUMLOTE
UNION ALL
SELECT ESTOQUE_WMS.empresa_erp as "storeId",
ESTOQUE_WMS.produto_erp as "customerId",
ESTOQUE_WMS.LOTE as "lotProduct",
NULL as "quantitySale",
ESTOQUE_WMS.QT as "quantityStock"
FROM ESTOQUE_WMS
WHERE NOT EXISTS(SELECT LOTES_WMS.NUMPED FROM LOTES_WMS, PCPEDC
WHERE ESTOQUE_WMS.EMPRESA_ERP = LOTES_WMS.CODFILIAL
AND ESTOQUE_WMS.PRODUTO_ERP = LOTES_WMS.CODPROD
AND ESTOQUE_WMS.LOTE = LOTES_WMS.NUMLOTE
AND LOTES_WMS.NUMPED = PCPEDC.NUMPED
AND PCPEDC.CODCLI = ${customerId} )
AND ESTOQUE_WMS.PRODUTO_ERP = ${productId} `;
const connection = new Connection(connectionOptions);
await connection.connect();
const queryRunner = connection.createQueryRunner();
await queryRunner.connect();
try {
const lotsProduct = await queryRunner
.query(sqlQueryLot);
return lotsProduct;
} catch (err) {
console.log(err);
throw err;
} finally {
await queryRunner.release();
await connection.close();
}
}
}

View File

@@ -0,0 +1,41 @@
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Get, HttpException, HttpStatus, Post, Query } from '@nestjs/common';
import { CalculatePriceTintometrico } from 'src/domain/models/calculate-price-tintometrico.model';
import { TintometricoService } from './tintometrico.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Tintometrico')
@Controller('api/v1/tintometrico')
export class TintometricoController {
constructor(private readonly tintometricoService: TintometricoService){}
@Get('colors')
async getColors(@Query() query) {
let letter = '';
let product = '';
try {
if (query['letter'])
letter = query['letter'];
if (query['product']) {
product = query['product'];
}
return await this.tintometricoService.GetColors(letter, product);
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
@Post('calculatePrice')
async getPriceTintometrico(@Body() data: CalculatePriceTintometrico) {
try{
const dataPrice = await this.tintometricoService.calculatePriceColor(data);
return dataPrice;
} catch (e) {
throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
}
}
}

View File

@@ -0,0 +1,16 @@
import { TintometricoController } from './tintometrico.controller';
import { TintometricoService } from './tintometrico.service';
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
@Module({
imports: [TintometricoService],
controllers: [
TintometricoController,],
providers: [
TintometricoService,],
})
export class TintometricoModule { }

View File

@@ -0,0 +1,58 @@
/*
https://docs.nestjs.com/providers#services
*/
import { Injectable } from '@nestjs/common';
import { connectionOptions } from 'src/configs/typeorm.config';
import { CalculatePriceTintometrico } from 'src/domain/models/calculate-price-tintometrico.model';
import { Connection } from 'typeorm';
@Injectable()
export class TintometricoService {
async GetColors(letter: string, product: string) {
const connectionDb = new Connection(connectionOptions);
await connectionDb.connect();
const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT DISTINCT PRODUCT as "line", NVL(COLORNAME, COLORID) as "colorName" ` +
` FROM esttintometricoplanbase ` +
` WHERE BASE = :1 AND PRODUCT = :2 ` +
` ORDER BY NVL(COLORNAME, COLORID)`;
const colors = await queryRunner.query(sql, [letter, product]);
return colors;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connectionDb.close();
}
}
async calculatePriceColor(dataPrice: CalculatePriceTintometrico) {
const connectionDb = new Connection(connectionOptions);
await connectionDb.connect();
const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT ESK_VENDA.CALCULAR_PRECO_TINTOMETRICO(:1, :2, :3, :4, :5, :6) as "price_color" ` +
` FROM DUAL`;
const price = await queryRunner.query(sql, [dataPrice.storeId, dataPrice.productId,
dataPrice.letter, dataPrice.line, dataPrice.color, dataPrice.can]);
const resultPrice = new CalculatePriceTintometrico(dataPrice.storeId, dataPrice.productId, dataPrice.letter,
dataPrice.line, dataPrice.can, dataPrice.color, price[0].price_color );
return resultPrice;
} catch (error) {
console.log(error);
throw error;
} finally {
await queryRunner.release();
await connectionDb.close();
}
}
}