Atualização repositorio

This commit is contained in:
eduardoestevao-appsoluti
2025-03-27 19:29:17 -03:00
parent b104682e1d
commit 41e56dda12
70 changed files with 15389 additions and 125 deletions

24
.eslintrc.js Normal file
View File

@@ -0,0 +1,24 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};

148
.gitignore vendored
View File

@@ -1,3 +1,7 @@
# compiled output
/dist
/node_modules
# Logs # Logs
logs logs
*.log *.log
@@ -5,132 +9,26 @@ npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
lerna-debug.log* lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html) # OS
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json .DS_Store
# Runtime data # Tests
pids /coverage
*.pid /.nyc_output
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover # IDEs and editors
lib-cov /.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Coverage directory used by tools like istanbul # IDE - VSCode
coverage .vscode/*
*.lcov !.vscode/settings.json
!.vscode/tasks.json
# nyc test coverage !.vscode/launch.json
.nyc_output !.vscode/extensions.json
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# vitepress build output
**/.vitepress/dist
# vitepress cache directory
**/.vitepress/cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

4
.prettierrc Normal file
View File

@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}

73
README.md Normal file
View File

@@ -0,0 +1,73 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).

BIN
cert/JURUNENSE.pfx Normal file

Binary file not shown.

View File

@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIGNDCCBRygAwIBAgIQPXJcTfmIIxc0dhkm872DGTANBgkqhkiG9w0BAQsFADCB
jzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
Ey5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB
MB4XDTIzMDUzMDAwMDAwMFoXDTI0MDUyOTIzNTk1OVowGjEYMBYGA1UEAwwPKi5q
dXJ1bmVuc2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+98
NUp5GOf7/tsmydF+rNVPmDbkJ3YVYu7QMN1QLbaP50kG5I5JBhirWFfP8R8WVE5M
WHPMcMdj1B3n8dYm+IDNfvIwoZVR5khOogWlOsNc/+/581Nw5crY6Lt+JF81Fglz
rDtiaCvpRdiihn9KVTIi98HOcigxG7rUk32oiFtpkIxAW0AbZCcJWC8CN2uzkudI
t7O4b1nguMSmSyCNqtKHZY4nVRKKfrPbJN7rc0TZMjEpbfbpr+gLduuoiQsb1YwX
SbPa42QPA9a10HruFAA4CRqdMtawaZir2Vqqcs5WY8wG+uTYFedA3qiZ1P00NHmk
8zooKE2CtQyeMbKkTwIDAQABo4IC/jCCAvowHwYDVR0jBBgwFoAUjYxexFStiuF3
6Zv5mwXhuAGNYeEwHQYDVR0OBBYEFE/J6yZvQbIdBxLNS+t2GbqLvgTDMA4GA1Ud
DwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
BgEFBQcDAjBJBgNVHSAEQjBAMDQGCysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEW
F2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEE
eDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29S
U0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzAB
hhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTApBgNVHREEIjAggg8qLmp1cnVuZW5z
ZS5jb22CDWp1cnVuZW5zZS5jb20wggF8BgorBgEEAdZ5AgQCBIIBbASCAWgBZgB1
AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABiGoxLmkAAAQDAEYw
RAIgTWumUgIKUROJcoqAEpRp5PydRzMxvKD33G8bb7TGRZcCIAYgfTDGJpCykGCN
dH0ngsuZ8zKQlsg5xQAq/3XcIYMbAHUA2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0
vaQ9MEjX+6sAAAGIajEuyAAABAMARjBEAiBYx57ghakyP/o/gO7cijhU1/pMMbd/
4cFJ5ByVFpPm+QIgXJJDn/4Nq5QOopgwyJPiYDwU+z951kxC/HeGh9bLEt0AdgDu
zdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYhqMS6XAAAEAwBHMEUC
IQD917OeqnMe9oQKlVv//E32VqqJUfpTkXbGEZ8q6ckX3AIgb5l//jjQ0RZnM3RA
Ucw/unwxGcPP7Bo6HdRDYcMEkBkwDQYJKoZIhvcNAQELBQADggEBADsmDG2V6ZHU
RxrRN4UdpKJSyYUZxnSMGTTo8t9nSEQ5WM3byZybQYcUm66wHi50lPwLNJPEV3rd
2XhvJyESA2UpAxK12sWMPRXpa5WbEtDSq9xHPknzA2RsZHhh8P8vw2AwRfS/EQll
UGFQkyqBA2MkdIw1ldPMnZM3FH6VXjrkq5CV6ib+TO0OnNNBIJRePHlSAMslxqiT
wN7bvbWQMebapiZ/8CIx1CcRZLCBQBETFA71iPWqKAJVFPp1bh8XbHixv7Rfpn0F
G2/HkK51y/ZYyKbgwW5WDq4/SabJD8palSlw8HBpMGXuZCCrxpd6kssj6Q9nmGSV
gr5tfdYId24=
-----END CERTIFICATE-----

24
cert/glpi-selfsigned.crt Normal file
View File

@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID9zCCAt+gAwIBAgIUEJEiXtLMas40jSAsZ45nXAsKNjgwDQYJKoZIhvcNAQEL
BQAwgYoxCzAJBgNVBAYTAkJSMQ0wCwYDVQQIDARQQVJBMQ4wDAYDVQQHDAVCRUxF
TTESMBAGA1UECgwJSlVSVU5FTlNFMQswCQYDVQQLDAJUSTESMBAGA1UEAwwJSlVS
VU5FTlNFMScwJQYJKoZIhvcNAQkBFhhTVVBPUlRFQEpVUlVORU5TRS5DT00uQlIw
HhcNMjQxMjAzMTIzNDAwWhcNMjcxMjAzMTIzNDAwWjCBijELMAkGA1UEBhMCQlIx
DTALBgNVBAgMBFBBUkExDjAMBgNVBAcMBUJFTEVNMRIwEAYDVQQKDAlKVVJVTkVO
U0UxCzAJBgNVBAsMAlRJMRIwEAYDVQQDDAlKVVJVTkVOU0UxJzAlBgkqhkiG9w0B
CQEWGFNVUE9SVEVASlVSVU5FTlNFLkNPTS5CUjCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAIUGlPdS7LH1im7EX/tseOi1pSZKfmMgM8MX9ij5BGbxy4Wr
TRCKC0A9MJ1OKPk7Tv76hX0F+ZI08DEQ0knB7UFfHKTO/VeKD48xCDbJVx8piqoO
LyjQ+2nv+hq0//jbvHzrvgwNHGnUXK7w5Oip20qzCI5c/rHCELp3hQpenugQnkgC
FnbYe17QeimpWDL5kZrIV/jkLfWHGp6NxYt3XhJgbB2BHZL9cQBJSV/OH9zpRZKB
KRMARbQiqzNBLE1zJCPRCo4d97ksY2W1fD+YqYVcGV+A0304iiLpF0/jVVoE3EMG
xVq5H5nikITVhxeg4lSD9Wi8T+qfWUEjOkUykR8CAwEAAaNTMFEwHQYDVR0OBBYE
FIbD7xsUZ/a/M6oHKPHkYPpWPVzsMB8GA1UdIwQYMBaAFIbD7xsUZ/a/M6oHKPHk
YPpWPVzsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACx7PrmU
xUbZc8hy5WDVuVgzKbxyGKvuiNRHzPsbg/iQZdt5yCwDMszN88GESiAa+n9pIoIs
UN8jU2c5uZAUDsVdueWLCdX6djq5sR0ta3HUOP4HyZwo/XMZEdMG2Nb+eBfLl4/m
GOZs9xyzkK2Unxe6Zz1ZvXZNVzTs47SOPL4EpKyHlOsDp9OlqDWQ+h2LfEVYXyKV
WGxRQORcvUsKfLHOrKoZ/OyWLBK1G70hPJRwXjJ+wHeVRHyxsjVR308IgTtkYyYK
ykleFGaYbrixHPgMvjiZxAHFwjSNoAknB5iqI+HSbvOQG7DwYarlsrXTfqT1D1+o
jvnZcdeb6p1OTtg=
-----END CERTIFICATE-----

28
cert/glpi-selfsigned.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCFBpT3Uuyx9Ypu
xF/7bHjotaUmSn5jIDPDF/Yo+QRm8cuFq00QigtAPTCdTij5O07++oV9BfmSNPAx
ENJJwe1BXxykzv1Xig+PMQg2yVcfKYqqDi8o0Ptp7/oatP/427x8674MDRxp1Fyu
8OToqdtKswiOXP6xwhC6d4UKXp7oEJ5IAhZ22Hte0HopqVgy+ZGayFf45C31hxqe
jcWLd14SYGwdgR2S/XEASUlfzh/c6UWSgSkTAEW0IqszQSxNcyQj0QqOHfe5LGNl
tXw/mKmFXBlfgNN9OIoi6RdP41VaBNxDBsVauR+Z4pCE1YcXoOJUg/VovE/qn1lB
IzpFMpEfAgMBAAECggEAM1zRutctZh8ZBuDS8Ji27J9qN2ku+KYv5kXDuZlArmDx
BNkaBedPJcwaj7pkjqrsOv5O+XGLpfzDuyY0E9+JdKK9RBNZ9WlszYyQj9rYxUL8
c+HLKrbaRFKw3owBg7yQQCmj9TJAxMoGyVNhB0bCUcrj5FgazVbRr7XDTDgxogdu
HCtjWP5gmp0sFAghVxqyPTBEW1cgJGWoy+mFceij5n5GRp4rHt1uhUcQvw3Msp5Y
5KHSru2ckfkJNnogSxf2VVKgtyzsQJGwi2Owg/bpkSaBMgKqSjfHfWnTA6V7g8Ml
XyGq9WQ8fDBVOTbxTw6HQ9Yq7oG8+EcmTsbHCrPwjQKBgQC47toH5eTp55Tx3y/h
kWYKNDVrsqhiyoHySrietaxnaaNScjJ0OmHZ+TJy6FetjZtHjFWOLwIAIZGU4y5c
roIaT4kQqnDGkqfaiOFikfybj+NJqY1ucvtNeJrbwSQ/Cu8TEEFtD+iF++xzdtCI
ZGVOGw1ESbl245M8SrUViVJO6wKBgQC4JT9PZU4tm7IYEYj+c5rzfpsz/G1CgV0h
jbZpzxRY9RvD6lclpo/kHECs6nReusZUy8D9wmMr5THHubwXoophDunQV3yoUOmj
+tZrAqwURWdjBBQ4eMJd2fUep336nzQLOkwf76aNCZ70CnY3c0A1kCpEW+RlgP5m
I1UsDGvBnQKBgBA7Jne6/bRp1vDDnfg2QrZyjp29OHozO+SAGmQTneYVp3f8/eCl
nyD6disPqWJaI17MOlYYWhyY1aYzqkYIKvMUN/t2eh9zj7fme6GjHoCoyFIWx4sC
HHxYMX9IHF5MH1+U9akU1FuuGLqpmvPdm+aXCTsNHXIJ10pbZDlXrBmxAoGAQEnA
sJdNk96nbn+wtCToE9o/lQarnmxLd0tiQ85n7Camat+FTT+5PIogij3QIsJSO4hm
+DDFLq31kyTk5dt5NClgt7vTaW/WIcmQ0gs8yFbyoT7rUEvYj6toSCtxb+3k3Yac
zQl9u/9/3vNIElPKNuj92J+8PTOrnTz4n0g21oECgYB4h412DwbXMU5vo57brNut
cvLC7yk8CVBolNCGOXa0S+/wR8W/VNmuaaC/vFVTrkx0OCk/HTDlEbPexS85hjVw
MqUHYfn+rHjZzLwdWzWAdDqR+2rD1QjiaGQcAZmDiALPAmKaiKOBcq5/D9NQKloc
RjobbZeKQ9z+xfcDhRLKSQ==
-----END PRIVATE KEY-----

36
cert/jurunense.com.crt Normal file
View File

@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIGNDCCBRygAwIBAgIQPXJcTfmIIxc0dhkm872DGTANBgkqhkiG9w0BAQsFADCB
jzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
Ey5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB
MB4XDTIzMDUzMDAwMDAwMFoXDTI0MDUyOTIzNTk1OVowGjEYMBYGA1UEAwwPKi5q
dXJ1bmVuc2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+98
NUp5GOf7/tsmydF+rNVPmDbkJ3YVYu7QMN1QLbaP50kG5I5JBhirWFfP8R8WVE5M
WHPMcMdj1B3n8dYm+IDNfvIwoZVR5khOogWlOsNc/+/581Nw5crY6Lt+JF81Fglz
rDtiaCvpRdiihn9KVTIi98HOcigxG7rUk32oiFtpkIxAW0AbZCcJWC8CN2uzkudI
t7O4b1nguMSmSyCNqtKHZY4nVRKKfrPbJN7rc0TZMjEpbfbpr+gLduuoiQsb1YwX
SbPa42QPA9a10HruFAA4CRqdMtawaZir2Vqqcs5WY8wG+uTYFedA3qiZ1P00NHmk
8zooKE2CtQyeMbKkTwIDAQABo4IC/jCCAvowHwYDVR0jBBgwFoAUjYxexFStiuF3
6Zv5mwXhuAGNYeEwHQYDVR0OBBYEFE/J6yZvQbIdBxLNS+t2GbqLvgTDMA4GA1Ud
DwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
BgEFBQcDAjBJBgNVHSAEQjBAMDQGCysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEW
F2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEE
eDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29S
U0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzAB
hhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTApBgNVHREEIjAggg8qLmp1cnVuZW5z
ZS5jb22CDWp1cnVuZW5zZS5jb20wggF8BgorBgEEAdZ5AgQCBIIBbASCAWgBZgB1
AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABiGoxLmkAAAQDAEYw
RAIgTWumUgIKUROJcoqAEpRp5PydRzMxvKD33G8bb7TGRZcCIAYgfTDGJpCykGCN
dH0ngsuZ8zKQlsg5xQAq/3XcIYMbAHUA2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0
vaQ9MEjX+6sAAAGIajEuyAAABAMARjBEAiBYx57ghakyP/o/gO7cijhU1/pMMbd/
4cFJ5ByVFpPm+QIgXJJDn/4Nq5QOopgwyJPiYDwU+z951kxC/HeGh9bLEt0AdgDu
zdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYhqMS6XAAAEAwBHMEUC
IQD917OeqnMe9oQKlVv//E32VqqJUfpTkXbGEZ8q6ckX3AIgb5l//jjQ0RZnM3RA
Ucw/unwxGcPP7Bo6HdRDYcMEkBkwDQYJKoZIhvcNAQELBQADggEBADsmDG2V6ZHU
RxrRN4UdpKJSyYUZxnSMGTTo8t9nSEQ5WM3byZybQYcUm66wHi50lPwLNJPEV3rd
2XhvJyESA2UpAxK12sWMPRXpa5WbEtDSq9xHPknzA2RsZHhh8P8vw2AwRfS/EQll
UGFQkyqBA2MkdIw1ldPMnZM3FH6VXjrkq5CV6ib+TO0OnNNBIJRePHlSAMslxqiT
wN7bvbWQMebapiZ/8CIx1CcRZLCBQBETFA71iPWqKAJVFPp1bh8XbHixv7Rfpn0F
G2/HkK51y/ZYyKbgwW5WDq4/SabJD8palSlw8HBpMGXuZCCrxpd6kssj6Q9nmGSV
gr5tfdYId24=
-----END CERTIFICATE-----

27
cert/jurunense.com.key Normal file
View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA8+98NUp5GOf7/tsmydF+rNVPmDbkJ3YVYu7QMN1QLbaP50kG
5I5JBhirWFfP8R8WVE5MWHPMcMdj1B3n8dYm+IDNfvIwoZVR5khOogWlOsNc/+/5
81Nw5crY6Lt+JF81FglzrDtiaCvpRdiihn9KVTIi98HOcigxG7rUk32oiFtpkIxA
W0AbZCcJWC8CN2uzkudIt7O4b1nguMSmSyCNqtKHZY4nVRKKfrPbJN7rc0TZMjEp
bfbpr+gLduuoiQsb1YwXSbPa42QPA9a10HruFAA4CRqdMtawaZir2Vqqcs5WY8wG
+uTYFedA3qiZ1P00NHmk8zooKE2CtQyeMbKkTwIDAQABAoIBAQCtshfVsoPsMjQD
03UZPC1hUDru/hcT6kdsPPTN9qkDA/4QCLX5xT9GMgbATzboUOSLf31pdntayv/Q
qMLiN0VkqgKppDbwt+yrd01WnYJ8B2SPcgefNgkr93bgsbEuoQSh/nT5bQezeaEP
dSS1dKovZBX2KXChZPEi97Qqmc2J2Xm5GMTnxYhfewkMt5YqbwHD4zesnZCW4hjZ
9UP2YMjb0JeI1TOnDKiNSaZ5gGAWLeMYRV1qu6yZOUTG2v7zhhTW2Aqpxu0nU+Cp
s7+7oh/2bXGgMVLLHUqL89g7B0KLksI6RMKatAOVWQHopnCPDpSA3Y7a85TRWNZW
RJwtU5DBAoGBAPxiWPYEcHmM4pF7F0EqqDIy3aljs6Gsqi4aQdsf5CE4P4dWprLP
Tg4DtjpKUt0jAN5+fXI3F/YmQbAUX43iK1K9jqN2LLbaR54URzPJ/5CO7luEScVE
z0NDuUQDPLxosjaV99e1BxaHG3NXzXXMqDb4aA6djXQ76VfqzNl8pCqRAoGBAPdu
Jql+IX2KlE43hGEBJjoC1B3Jm+PIt4hsEuq0A8JzVZLqgeCoN3Len2I7h/+p1nQ2
HmTk3QCF65OitdogBxg/pcJfc2XUruahWlTsrXEcraso3mNSRqKxhFGJj1s+/ykM
JFw3KTH0R6/k9+bQWUVBUuF0Tg1eoRrlqXG6wJDfAoGBAMev1K1KU+eINddfacXQ
x2V4Y3NbhEv9/mQduE90ix5Rj8o4IArIBP0HqM2z8p4uzMg9kmmk95t1J3H2nKf4
88gyXMIuhTBjwlhruO5b+43X2PWl1Gx1hfu1gMc0PIDh4WdY/tC31ZTYbzqylMiI
letwXXx64em+YWCDUXMesBFRAoGBALnbV9dBE08F5VjLgviKsHgq38JwSlTT1Gj5
JUx/Y8OQdtsgo+Zo9R2n8/kJ1qJIpPouHK6U6x0Ve1sugYMTQ8EHLi/PGxOGqso6
sWvRTIcGj71duY7Jop1a0pWcyr4zl97xa+6I0LzhTWfmigAqyKOo6eTIREjup/1Y
Petb6IHpAoGAcLSjSlqSOJrVDDqXGRnv1b/ThQDmay9vk0Mz8dytSw+L8BKy1whQ
J2XMqZYtq6H5psV1u6qaH4w+0a9s5lQrTDzm3XTU6tJYQC06KlaLk3/J1EAl2zG6
dQ46Ep3fcSt/MGvvoNvzaGRmhq8a/fPDq1/hvF0kIWnR43gi3v9BdI0=
-----END RSA PRIVATE KEY-----

36
cert/jurunense.crt Normal file
View File

@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIGPzCCBSegAwIBAgIRAOsZGPSnBumhZkpBFmGzLH8wDQYJKoZIhvcNAQELBQAw
gY8xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE3MDUGA1UE
AxMuU2VjdGlnbyBSU0EgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBD
QTAeFw0yNDA2MDMwMDAwMDBaFw0yNTA2MDMyMzU5NTlaMB0xGzAZBgNVBAMMEiou
anVydW5lbnNlLmNvbS5icjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AL2jeyLryQWyAMV9ZU+PrxkoHbYKJJGV+cS9oEutbmAKd+gWC73CizWmidWTd+0W
OnV94nx23w4GO99ZeRcUQOUQaU1hDAdt7sHgtEUFAg4FlIrNFAdWNPG8Fz9sK4Z4
QQ91mY26eH7i3/paO4HuuNTa9ai0g9GjKvBD7sU6MB0H14nNyJN4km07IsXq2yv1
M55NWJ7OwtiyqHhzGZGbV29iucrctO/QcQA75OW5uH5Vq893BkFuG3cbROCuVNuA
Pa2wh0oGiyrlaqQe+WG+hqStXM1YNQYCmSPKf6O6Ogjm6oNGi0Ri8LN6Ou2/9PGX
lRQ+KILIrlLrfVmvh4q2/zsCAwEAAaOCAwUwggMBMB8GA1UdIwQYMBaAFI2MXsRU
rYrhd+mb+ZsF4bgBjWHhMB0GA1UdDgQWBBTjZAm3a5xq9Le8HO3Q/T51FxWvETAO
BgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcD
AQYIKwYBBQUHAwIwSQYDVR0gBEIwQDA0BgsrBgEEAbIxAQICBzAlMCMGCCsGAQUF
BwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAIBgZngQwBAgEwgYQGCCsGAQUF
BwEBBHgwdjBPBggrBgEFBQcwAoZDaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0
aWdvUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEF
BQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wLwYDVR0RBCgwJoISKi5qdXJ1
bmVuc2UuY29tLmJyghBqdXJ1bmVuc2UuY29tLmJyMIIBfQYKKwYBBAHWeQIEAgSC
AW0EggFpAWcAdgDPEVbu1S58r/OHW9lpLpvpGnFnSrAX7KwB0lt3zsw7CAAAAY/f
7ksOAAAEAwBHMEUCIFWLlJdVKtigtLUxf60NSf0gJ9LVA/5QCOKNhVz38nG5AiEA
lzyk+XkIhOo5cElp+Si6qN5FYWGKVhr6zRN0IamHDm8AdgCi4wrkRe+9rZt+OO1H
Z3dT14JbhJTXK14bLMS5UKRH5wAAAY/f7krJAAAEAwBHMEUCIEM3Y9v9QJqJNQ9g
wtFyaD6WFEN4F8y8CYi/6+mZMNlIAiEAtkJKuVBvxJaz1Mbrz1LF3cdp6gZUmDCx
Whd/Wz2QMKQAdQBOdaMnXJoQwzhbbNTfP1LrHfDgjhuNacCx+mSxYpo53wAAAY/f
7kqjAAAEAwBGMEQCIDHip6dLR3iCW+sUD4nFYLQXWSo90IvdlrdCzRu4iMaEAiBs
Sq1W8g7LKgHy8wr89gnUSH/7eOlq3f+JRKtk5pMygDANBgkqhkiG9w0BAQsFAAOC
AQEArE9fX5VyPNx0zxHeHEOgDNoNoRhI1X3T72quTQVb4nbLjf23oHNWQ2GieCTL
CPAp1LdmctK25rD83hFD9cgovO2h1peYT63/DL1zsusDa1Qaa/4bi8OtqLe6BNE2
GyLM/yd3JR1YOP9gR9363B8NfxvDoBII3+iqBFfpUwjsa6DpFlCpqRDO9BTrq+KZ
4IRbJIBcEDNp+sajJqzpHU9N67a3sK7dyE73ByVwjGiuMN7vB2aqU4H/INEacbWw
RO1UJ11DaCyi/k5x56xTRKlBFwXQcLm8oZl7pBqYsKEyadu1Apf7YAQGd54OCPr7
mO2AEFA6SOmLDVFCBq58LGHjBA==
-----END CERTIFICATE-----

27
cert/jurunense.key Normal file
View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAvaN7IuvJBbIAxX1lT4+vGSgdtgokkZX5xL2gS61uYAp36BYL
vcKLNaaJ1ZN37RY6dX3ifHbfDgY731l5FxRA5RBpTWEMB23uweC0RQUCDgWUis0U
B1Y08bwXP2wrhnhBD3WZjbp4fuLf+lo7ge641Nr1qLSD0aMq8EPuxTowHQfXic3I
k3iSbTsixerbK/Uznk1Yns7C2LKoeHMZkZtXb2K5yty079BxADvk5bm4flWrz3cG
QW4bdxtE4K5U24A9rbCHSgaLKuVqpB75Yb6GpK1czVg1BgKZI8p/o7o6CObqg0aL
RGLws3o67b/08ZeVFD4ogsiuUut9Wa+Hirb/OwIDAQABAoIBAEdv/kL5b5ClrYS3
6CJAjkV7xzV8PKpbROvIQ0o+2wVy7BiRtXqWfrqHMgUyuEqnxP3dniQk44H09zj8
C5GWH5wqwoBTvqRN1VNTwpT9ffiqQXrIJnNdFjS6FkfeB8dwJZIdSusJA7tI2/cD
ZsdblmUY1tHmroGaZeJ8tMW3VciZNSKgYk9JzTNe0zJlnsimw9aZ8LcwFth9vwJI
tlI6x72IpBD2062n81Xasm1pe1atPYXcWkF7divgWJ3ATZSx2VpUMZF8xy9Sjevg
JD5dr4AtAZ8HUBOeTecq4VlCHmSSARzEsb8ttMOByahIODA/ktwcGkdlRZD7OOtH
KCVz8AECgYEA7nkRU+s2+xw7Gn+DtY/U0hwNL3KU7K9yhilJ7ca2F41tDB6q0qb6
5GNHpQ3RabBPwCTwTsKJzUtNc3BppsUWe7quvywZ/+tPVOgwycBVhstHxLPGSEMW
6xPuY1KwGM5TeGdCbUXG6y3QJEb4wWq/J/ELTM1XmxQOj/8T4HB737sCgYEAy5OV
FW2Qb1x9OgkXKnBvOY05SFoswAGM33JrcjDrSOvpDXgm4rxabvAYf3gNtn9K5VRQ
9eaG0X8GA+UkirJf/TgNGy3eWgNs97h3ZJJK02hINZcSWVHJUhc8FaMhHK4LrAZj
MwZptbThiDIfoHEyUU8s/DDiQfet3y8jf3wopoECgYEAuixSVs2fEtOrYLiEPs6X
O6EiuhQeJ9mg8xRw3uzvY9vJcljOy74IyRyo5javcm9vE3bDFPnTUy6ivKjaEpRz
RQ0tN5page1W9dZ/oEJDgwRYdzxSZD/cOJJK3cfEKtmJWMpklaKP9TLC+E9gDMAl
lC0ewUreRfeWltxwzBuE2dkCgYEAx0MJphO8UIRjPq8vMacj9104OI2rR7U8wmoo
qXkglBv13e1BgqWCjxwLnplQMtWd5aMGK+sdA2ol5SIhBnFaa2y1x2i6P7kiq8av
do2LGCr2ox3gI/Vd7TA466TlAEGLwzHtX0BjsCwApWMKeezSp6usCJ2AmblpQw/M
2zgYQgECgYEAgijd2EVLLvpl83Lp2ExuReUHe6uHxL2TvP2R0JiiNvUxZFrThPCQ
BIo3aZ8UgMshdehFBKtRMiXK2HGsQGGYTZAP0fFrV8CdW8Da991SIcIPYDpSnuHK
sfdXhZ7wjE9VTd3drKOx+tvjSyfiuTn1Q8C1At2Q1R03RVSL2Z4vTlw=
-----END RSA PRIVATE KEY-----

36
cert/jurunense1ano.crt Normal file
View File

@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIGNDCCBRygAwIBAgIQPXJcTfmIIxc0dhkm872DGTANBgkqhkiG9w0BAQsFADCB
jzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
Ey5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB
MB4XDTIzMDUzMDAwMDAwMFoXDTI0MDUyOTIzNTk1OVowGjEYMBYGA1UEAwwPKi5q
dXJ1bmVuc2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+98
NUp5GOf7/tsmydF+rNVPmDbkJ3YVYu7QMN1QLbaP50kG5I5JBhirWFfP8R8WVE5M
WHPMcMdj1B3n8dYm+IDNfvIwoZVR5khOogWlOsNc/+/581Nw5crY6Lt+JF81Fglz
rDtiaCvpRdiihn9KVTIi98HOcigxG7rUk32oiFtpkIxAW0AbZCcJWC8CN2uzkudI
t7O4b1nguMSmSyCNqtKHZY4nVRKKfrPbJN7rc0TZMjEpbfbpr+gLduuoiQsb1YwX
SbPa42QPA9a10HruFAA4CRqdMtawaZir2Vqqcs5WY8wG+uTYFedA3qiZ1P00NHmk
8zooKE2CtQyeMbKkTwIDAQABo4IC/jCCAvowHwYDVR0jBBgwFoAUjYxexFStiuF3
6Zv5mwXhuAGNYeEwHQYDVR0OBBYEFE/J6yZvQbIdBxLNS+t2GbqLvgTDMA4GA1Ud
DwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
BgEFBQcDAjBJBgNVHSAEQjBAMDQGCysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEW
F2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEE
eDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29S
U0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzAB
hhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTApBgNVHREEIjAggg8qLmp1cnVuZW5z
ZS5jb22CDWp1cnVuZW5zZS5jb20wggF8BgorBgEEAdZ5AgQCBIIBbASCAWgBZgB1
AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABiGoxLmkAAAQDAEYw
RAIgTWumUgIKUROJcoqAEpRp5PydRzMxvKD33G8bb7TGRZcCIAYgfTDGJpCykGCN
dH0ngsuZ8zKQlsg5xQAq/3XcIYMbAHUA2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0
vaQ9MEjX+6sAAAGIajEuyAAABAMARjBEAiBYx57ghakyP/o/gO7cijhU1/pMMbd/
4cFJ5ByVFpPm+QIgXJJDn/4Nq5QOopgwyJPiYDwU+z951kxC/HeGh9bLEt0AdgDu
zdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYhqMS6XAAAEAwBHMEUC
IQD917OeqnMe9oQKlVv//E32VqqJUfpTkXbGEZ8q6ckX3AIgb5l//jjQ0RZnM3RA
Ucw/unwxGcPP7Bo6HdRDYcMEkBkwDQYJKoZIhvcNAQELBQADggEBADsmDG2V6ZHU
RxrRN4UdpKJSyYUZxnSMGTTo8t9nSEQ5WM3byZybQYcUm66wHi50lPwLNJPEV3rd
2XhvJyESA2UpAxK12sWMPRXpa5WbEtDSq9xHPknzA2RsZHhh8P8vw2AwRfS/EQll
UGFQkyqBA2MkdIw1ldPMnZM3FH6VXjrkq5CV6ib+TO0OnNNBIJRePHlSAMslxqiT
wN7bvbWQMebapiZ/8CIx1CcRZLCBQBETFA71iPWqKAJVFPp1bh8XbHixv7Rfpn0F
G2/HkK51y/ZYyKbgwW5WDq4/SabJD8palSlw8HBpMGXuZCCrxpd6kssj6Q9nmGSV
gr5tfdYId24=
-----END CERTIFICATE-----

40
cert/jurunense1ano.pem Normal file
View File

@@ -0,0 +1,40 @@
Bag Attributes
localKeyID: 2D 25 1B 5D 87 26 79 F5 37 F4 D2 91 90 99 0A FC 83 B8 DE 6D
subject=/CN=*.jurunense.com
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Domain Validation Secure Server CA
-----BEGIN CERTIFICATE-----
MIIGNDCCBRygAwIBAgIQPXJcTfmIIxc0dhkm872DGTANBgkqhkiG9w0BAQsFADCB
jzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
Ey5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB
MB4XDTIzMDUzMDAwMDAwMFoXDTI0MDUyOTIzNTk1OVowGjEYMBYGA1UEAwwPKi5q
dXJ1bmVuc2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+98
NUp5GOf7/tsmydF+rNVPmDbkJ3YVYu7QMN1QLbaP50kG5I5JBhirWFfP8R8WVE5M
WHPMcMdj1B3n8dYm+IDNfvIwoZVR5khOogWlOsNc/+/581Nw5crY6Lt+JF81Fglz
rDtiaCvpRdiihn9KVTIi98HOcigxG7rUk32oiFtpkIxAW0AbZCcJWC8CN2uzkudI
t7O4b1nguMSmSyCNqtKHZY4nVRKKfrPbJN7rc0TZMjEpbfbpr+gLduuoiQsb1YwX
SbPa42QPA9a10HruFAA4CRqdMtawaZir2Vqqcs5WY8wG+uTYFedA3qiZ1P00NHmk
8zooKE2CtQyeMbKkTwIDAQABo4IC/jCCAvowHwYDVR0jBBgwFoAUjYxexFStiuF3
6Zv5mwXhuAGNYeEwHQYDVR0OBBYEFE/J6yZvQbIdBxLNS+t2GbqLvgTDMA4GA1Ud
DwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
BgEFBQcDAjBJBgNVHSAEQjBAMDQGCysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEW
F2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEE
eDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29S
U0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzAB
hhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTApBgNVHREEIjAggg8qLmp1cnVuZW5z
ZS5jb22CDWp1cnVuZW5zZS5jb20wggF8BgorBgEEAdZ5AgQCBIIBbASCAWgBZgB1
AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABiGoxLmkAAAQDAEYw
RAIgTWumUgIKUROJcoqAEpRp5PydRzMxvKD33G8bb7TGRZcCIAYgfTDGJpCykGCN
dH0ngsuZ8zKQlsg5xQAq/3XcIYMbAHUA2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0
vaQ9MEjX+6sAAAGIajEuyAAABAMARjBEAiBYx57ghakyP/o/gO7cijhU1/pMMbd/
4cFJ5ByVFpPm+QIgXJJDn/4Nq5QOopgwyJPiYDwU+z951kxC/HeGh9bLEt0AdgDu
zdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYhqMS6XAAAEAwBHMEUC
IQD917OeqnMe9oQKlVv//E32VqqJUfpTkXbGEZ8q6ckX3AIgb5l//jjQ0RZnM3RA
Ucw/unwxGcPP7Bo6HdRDYcMEkBkwDQYJKoZIhvcNAQELBQADggEBADsmDG2V6ZHU
RxrRN4UdpKJSyYUZxnSMGTTo8t9nSEQ5WM3byZybQYcUm66wHi50lPwLNJPEV3rd
2XhvJyESA2UpAxK12sWMPRXpa5WbEtDSq9xHPknzA2RsZHhh8P8vw2AwRfS/EQll
UGFQkyqBA2MkdIw1ldPMnZM3FH6VXjrkq5CV6ib+TO0OnNNBIJRePHlSAMslxqiT
wN7bvbWQMebapiZ/8CIx1CcRZLCBQBETFA71iPWqKAJVFPp1bh8XbHixv7Rfpn0F
G2/HkK51y/ZYyKbgwW5WDq4/SabJD8palSlw8HBpMGXuZCCrxpd6kssj6Q9nmGSV
gr5tfdYId24=
-----END CERTIFICATE-----

BIN
cert/jurunense1ano.pfx Normal file

Binary file not shown.

4
nest-cli.json Normal file
View File

@@ -0,0 +1,4 @@
{
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}

11989
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

90
package.json Normal file
View File

@@ -0,0 +1,90 @@
{
"name": "api-padrao",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/axios": "^3.1.3",
"@nestjs/common": "^7.5.1",
"@nestjs/core": "^7.5.1",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^7.5.1",
"@nestjs/typeorm": "^10.0.2",
"aws-sdk": "^2.1692.0",
"axios": "^1.7.9",
"fs": "0.0.1-security",
"guid-typescript": "^1.0.9",
"https": "^1.0.0",
"md5": "^2.3.0",
"md5-typescript": "^1.0.5",
"multer": "^1.4.5-lts.2",
"oracledb": "^5.5.0",
"passport": "^0.7.0",
"passport-http-bearer": "^1.0.1",
"passport-jwt": "^4.0.1",
"path": "^0.12.7",
"pg": "^8.13.3",
"reflect-metadata": "^0.1.14",
"rimraf": "^3.0.2",
"rxjs": "^7.8.0",
"typeorm": "^0.3.20"
},
"devDependencies": {
"@nestjs/cli": "^7.5.1",
"@nestjs/schematics": "^7.1.3",
"@nestjs/testing": "^7.5.1",
"@types/express": "^4.17.8",
"@types/jest": "^26.0.15",
"@types/multer": "^1.4.12",
"@types/node": "^14.14.6",
"@types/supertest": "^2.0.10",
"@typescript-eslint/eslint-plugin": "^4.6.1",
"@typescript-eslint/parser": "^4.6.1",
"eslint": "^7.12.1",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.6.3",
"prettier": "^2.1.2",
"supertest": "^6.0.0",
"ts-jest": "^26.4.3",
"ts-loader": "^8.0.8",
"ts-node": "^9.0.0",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.0.5"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}

View File

@@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

12
src/app.controller.ts Normal file
View File

@@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}

46
src/app.module.ts Normal file
View File

@@ -0,0 +1,46 @@
import { BaseModule } from './core/services/base.module';
import { BaseService } from './core/services/base.service';
import { LogisticModule } from './logistic/logistic.module';
import { OrdersPaymentModule } from './orders-payment/orders-payment.module';
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable prettier/prettier */
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { typeOrmConfig, typeOrmPgConfig } from './core/configs/typeorm.config';
import { ProductsModule } from './products/products.module';
import { AuthModule } from './auth/auth/auth.module';
import { DataConsultModule } from './data-consult/data-consult.module';
import { OrdersModule } from './orders/orders.module';
import { OcorrencesController } from './crm/occurrences/ocorrences.controller';
import { OccurrencesModule } from './crm/occurrences/occurrences.module';
import { ReasonTableModule } from './crm/reason-table/reason-table.module';
import { NegotiationsModule } from './crm/negotiations/negotiations.module';
import { HttpModule } from '@nestjs/axios';
import { LogisticController } from './logistic/logistic.controller';
import { LogisticService } from './logistic/logistic.service';
@Module({
imports: [
BaseModule,
LogisticModule,
OrdersPaymentModule,
HttpModule,
NegotiationsModule,
OccurrencesModule,
ReasonTableModule,
DataConsultModule,
ProductsModule,
AuthModule,
OrdersModule,
TypeOrmModule.forRoot(typeOrmConfig),
TypeOrmModule.forRoot(typeOrmPgConfig),
],
controllers: [
OcorrencesController, AppController, LogisticController,],
providers: [
BaseService, AppService, LogisticService,],
})
export class AppModule { }

8
src/app.service.ts Normal file
View File

@@ -0,0 +1,8 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}

View File

@@ -0,0 +1,72 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
import {
Body,
Controller,
HttpException,
HttpStatus,
Post,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersService } from '../users/users.service';
import { UserModel } from 'src/core/models/user.model';
import { ResultModel } from 'src/core/models/result.model';
import { ResetPasswordModel } from 'src/core/models/reset-password.model';
import { ChangePasswordModel } from 'src/core/models/change-password.model';
@Controller('api/v1/auth')
export class AuthController {
constructor(
private usersService: UsersService,
private authService: AuthService,
) { }
@Post('login')
async login(@Body() model: UserModel): Promise<any> {
const user = await this.usersService.authenticate(model);
if (!user)
throw new HttpException(
new ResultModel(false, 'Usuário ou senha inválidos.', null, null),
HttpStatus.UNAUTHORIZED,
);
const token = await this.authService.createToken(
user.id,
user.sellerId,
user.username,
user.email,
user.storeId
);
return {
id: user.id,
sellerId: user.sellerId,
name: user.name,
username: user.name,
storeId: user.storeId,
email: user.email,
token: token,
};
}
@Post('reset-password')
async resetPassword(@Body() resetPassword: ResetPasswordModel) {
const response = await this.usersService.resetPassword(resetPassword);
if (response == null) {
throw new HttpException('Usuário não foi encontrado', HttpStatus.NOT_FOUND);
}
return { message: 'Senha alterada com sucesso! Foi enviado email com a nova senha!' };
}
@Post('change-password')
async changePassword(@Body() changePassword: ChangePasswordModel) {
const response = await this.usersService.changePassword(changePassword);
if (response == null) {
throw new HttpException('Usuário não foi encontrado', HttpStatus.NOT_FOUND);
}
return { message: 'Senha alterada com sucesso!' };
}
}

View File

@@ -0,0 +1,26 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { UsersModule } from '../users/users.module';
@Module({
imports: [
UsersModule,
PassportModule.register({
defaultStrategy: 'jwt',
}),
JwtModule.register({
secret: '4557C0D7-DFB0-40DA-BF83-91A75103F7A9',
signOptions: {
expiresIn: 3600,
},
}),
],
controllers: [AuthController],
providers: [AuthService],
exports: [AuthService],
})
export class AuthModule {}

View File

@@ -0,0 +1,32 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Injectable } from '@nestjs/common';
import { JwtService, JwtSignOptions } from '@nestjs/jwt';
import { UsersService } from '../users/users.service';
import { JwtPayload } from '../models/jwt-payload.model';
@Injectable()
export class AuthService {
constructor(
private readonly usersService: UsersService,
private readonly jwtService: JwtService,
) {}
async createToken(id: number, sellerId: number, username: string, email: string, storeId: string) {
const user: JwtPayload = {
id: id,
sellerId: sellerId,
storeId: storeId,
username: username,
email: email,
};
const options: JwtSignOptions = { expiresIn: '8h' };
return this.jwtService.sign(user, options);
}
async validateUser(payload: JwtPayload): Promise<any> {
//return await this.accountService.findOneByUsername(payload.username);
return payload;
}
}

View File

@@ -0,0 +1,9 @@
/* eslint-disable prettier/prettier */
export interface JwtPayload {
id: number;
sellerId: number;
storeId: string;
username: string;
email: string;
}

View File

@@ -0,0 +1,24 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { JwtPayload } from '../models/jwt-payload.model';
import { AuthService } from '../auth/auth.service';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKeyProvider: '4557C0D7-DFB0-40DA-BF83-91A75103F7A9', //secretOrKey
});
}
async validate(payload: JwtPayload) {
const user = await this.authService.validateUser(payload);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}

View File

@@ -0,0 +1,10 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
@Module({
imports: [],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}

View File

@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UsersService } from './users.service';
describe('UsersService', () => {
let service: UsersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UsersService],
}).compile();
service = module.get<UsersService>(UsersService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@@ -0,0 +1,152 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
import md5 = require('md5');
import { Guid } from "guid-typescript";
import { typeOrmConfig } from 'src/core/configs/typeorm.config';
import { UserModel } from 'src/core/models/user.model';
@Injectable()
export class UsersService {
async authenticate(user: any): Promise<any> {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCEMPR.MATRICULA AS "id"
,PCEMPR.NOME AS "name"
,PCEMPR.CODUSUR AS "sellerId"
,PCEMPR.CODFILIAL AS "storeId"
,PCEMPR.EMAIL AS "email"
,PCEMPR.DTDEMISSAO as "dataDesligamento"
,PCEMPR.SITUACAO as "situacao"
FROM PCEMPR
WHERE PCEMPR.USUARIOBD = '${user.userName}'
AND PCEMPR.SENHABD = CRYPT('${user.password.toUpperCase()}', PCEMPR.USUARIOBD) `;
const users = await queryRunner.manager.query(sql);
if (users.length == 0) {
return null;
}
const userDb = users[0];
if ( userDb.dataDesligamento !== null ) {
throw new HttpException('Usuário desligado da empresa, login não permitido!', HttpStatus.FORBIDDEN);
}
if ( userDb.situacao == 'I' ) {
throw new HttpException('Usuário inativo, login não permitido!', HttpStatus.FORBIDDEN);
}
return userDb;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async resetPassword(user: any): Promise<any> {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
let sql =
'SELECT PCUSUARI.CODUSUR as "sellerId" ' +
' ,PCUSUARI.NOME as "name" ' +
' ,PCUSUARI.EMAIL as "email" ' +
' FROM PCUSUARI ' +
` WHERE REGEXP_REPLACE(PCUSUARI.CPF, '[^0-9]', '') = REGEXP_REPLACE(:1, '[^0-9]', '') ` +
` AND PCUSUARI.EMAIL = :2 `;
const users = await queryRunner.manager.query(sql, [
user.document,
user.email,
]);
if (users.length == 0) {
return null;
}
const guid = Guid.create();
console.log(guid.toString());
const password = guid.toString().substring(0, 8);
const newPassword = md5(password).toUpperCase();
console.log("Senha:" + newPassword)
sql = `UPDATE PCUSUARI SET ` +
` SENHALOGIN = :1 ` +
`WHERE CODUSUR = :2`;
await queryRunner.manager.query(sql, [newPassword, users[0].sellerId]);
const sqlEmail = `INSERT INTO CORRESPONDENCIAS ( CORRESPONDENCIA_ID, DTINCLUSAO, TITULO, MENSAGEM, EMAIL, DESTINATARIO )
VALUES ( SEQ_CORRESPONDENCIAS.NEXTVAL, SYSDATE, 'Alteração de email - CoteLivia',
'Sua senha para acesso ao portal COTELIVIA é ${password}', '${users[0].email}', '${users[0].email}' )`;
await queryRunner.manager.query(sqlEmail);
await queryRunner.commitTransaction();
const userDb = users[0];
return userDb;
} catch (error) {
await queryRunner.rollbackTransaction();
console.log(error);
throw new Error(error);
}
finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async changePassword(user: any): Promise<any> {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
console.log(JSON.stringify(user));
try {
let sql =
'SELECT PCUSUARI.CODUSUR as "sellerId" ' +
' ,PCUSUARI.NOME as "name" ' +
' ,PCUSUARI.EMAIL as "email" ' +
' FROM PCUSUARI ' +
` WHERE PCUSUARI.CODUSUR = :1` +
` AND PCUSUARI.SENHALOGIN = :2 `;
const users = await queryRunner.manager.query(sql, [
user.id,
md5(user.password).toUpperCase(),
]);
if (users.length == 0) {
return null;
}
sql = `UPDATE PCUSUARI SET ` +
` SENHALOGIN = :1 ` +
`WHERE CODUSUR = :2`;
await queryRunner.manager.query(sql, [md5(user.newPassword).toUpperCase(), users[0].sellerId]);
await queryRunner.commitTransaction();
const userDb = users[0];
return userDb;
} catch (error) {
await queryRunner.rollbackTransaction();
console.log(error);
throw new Error(error);
}
finally {
await queryRunner.release();
await dataSource.destroy();
}
}
}

View File

@@ -0,0 +1,22 @@
/* eslint-disable prettier/prettier */
import { DataSourceOptions } from 'typeorm/data-source';
export const typeOrmConfig: DataSourceOptions = {
type: 'oracle',
connectString: '(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.1.241)(PORT = 1521)))(CONNECT_DATA = (SERVICE_NAME = WINT)))',
username: 'SEVEN',
password: 'USR54SEV',
synchronize: false,
logging: false,
entities: [__dirname + '/../**/*.entity.{js,ts}'],
};
export const typeOrmPgConfig: DataSourceOptions = {
type: 'postgres',
host: '10.1.1.222',
port: 5432,
username: 'ti',
password: 'ti',
database: 'ksdb',
synchronize: true,
}

View File

@@ -0,0 +1,25 @@
export class Invoice {
customer: string;
invoiceNumber: number;
loadingNumber: number;
reasonId: number;
reasonText: string;
status: string;
}
export class CarInDelivery {
finalKm: number;
invoices: Invoice[];
licensePlate: string;
loadingNumber: number;
observation: string;
images: string[];
userId: number;
qtdPaletesPbr: number;
qtdPaletesCim: number;
qtdPaletesDes: number;
remnant: string;
observationRemnant: string;
imagesRemnant: string[];
}

View File

@@ -0,0 +1,18 @@
export class CarOutDelivery {
helpers: Helper[]; // Array de objetos auxiliares
licensePlate: string; // Placa do veículo
numberLoading: number[]; // Número do carregamento
palletCount: number; // Quantidade de pallets
photos: string[]; // Array de URLs das fotos
startKm: number; // Quilometragem de início (como string)
userCode: number; // Código do usuário
vehicleCode: number; // Código do veículo
}
export class Helper {
id: number;
name: string;
phone: string;
}

View File

@@ -0,0 +1,6 @@
/* eslint-disable prettier/prettier */
export class ChangePasswordModel {
id: number;
password: string;
newPassword: string;
}

View File

@@ -0,0 +1,6 @@
/* eslint-disable prettier/prettier */
export class ExposedProduct {
ean: string;
storeId: string;
userId: number;
}

View File

@@ -0,0 +1,5 @@
/* eslint-disable prettier/prettier */
export class ResetPasswordModel {
document: string;
email: string;
}

View File

@@ -0,0 +1,9 @@
/* eslint-disable prettier/prettier */
export class ResultModel {
constructor(
public success: boolean,
public message: string,
public data: any,
public errors: any) {};
}

View File

@@ -0,0 +1,8 @@
export class UserModel {
id: number;
password: string;
application: string;
storeId: string;
sellerId: number;
email: string;
}

View File

@@ -0,0 +1,94 @@
import { DropAction } from './../../../node_modules/aws-sdk/clients/mailmanager.d';
/*
https://docs.nestjs.com/controllers#controllers
*/
import {
Body, Controller, Get, HttpException, HttpStatus, Post, Query, Req, UseInterceptors,
UploadedFile
} from '@nestjs/common';
import { BaseService } from './base.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';
import * as fs from "fs";
@Controller('api/v1/base')
export class BaseController {
constructor(public readonly baseService: BaseService) { }
// @UseGuards(JwtAuthGuard)
@Get('execute-view')
/* @ApiOperation({
summary: 'Executa uma view com ou sem parâmetros',
})
@ApiResponse({
status: 200,
description: 'Dados retornados com sucesso.',
})
@ApiResponse({
status: 400,
description: 'O nome da view é obrigatório.',
})
@ApiResponse({
status: 500,
description: 'Erro ao executar a view.',
})*/
async executeView(
@Query('viewName') viewName: string,
@Query() params: Record<string, any>,
) {
if (!viewName) {
throw new HttpException(
'O nome da view é obrigatório.',
HttpStatus.BAD_REQUEST,
);
}
try {
return await this.baseService.executeView(viewName, params);
} catch (error) {
throw new HttpException(
`Erro ao executar a view: ${error.message}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
@Post('send-image')
@UseInterceptors(
FileInterceptor('file', {
storage: diskStorage({
// Pasta onde os arquivos serão salvos; certifique-se que essa pasta exista ou crie-a automaticamente
destination: './uploads',
filename: (req, file, callback) => {
// Gera um nome único para o arquivo
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
const fileExtName = extname(file.originalname);
callback(null, `${file.fieldname}-${uniqueSuffix}${fileExtName}`);
},
}),
// Opcional: definir limites (ex.: tamanho máximo do arquivo)
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
}),
)
async sendImage(
@UploadedFile() file: Express.Multer.File,
@Body('licensePlate') licensePlate: string,
) {
if (!file) {
throw new HttpException('Nenhum arquivo enviado', HttpStatus.BAD_REQUEST);
}
// Aqui você pode processar o arquivo (ex.: enviar para o S3) ou armazená-lo no disco mesmo.
// Neste exemplo, retornamos a URL do arquivo salvo localmente.
this.baseService.sendImages('./uploads/'+file.filename);
fs.unlink('./uploads/'+file.filename, () => {});
return {
success: true,
message: 'Upload realizado com sucesso',
url: `https://jur-saidaretornoveiculo.s3.sa-east-1.amazonaws.com/${file.filename}`,
licensePlate,
};
}
}

View File

@@ -0,0 +1,15 @@
import { BaseController } from './base.controller';
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
import { BaseService } from './base.service';
@Module({
imports: [],
controllers: [
BaseController,],
providers: [BaseService,],
})
export class BaseModule { }

View File

@@ -0,0 +1,289 @@
import { Inject, Injectable, InternalServerErrorException } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { typeOrmConfig } from '../configs/typeorm.config';
import { S3 } from 'aws-sdk';
import * as fs from "fs";
@Injectable()
export class BaseService {
constructor() { }
async findAll(table: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [rows] = await queryRunner.query(`SELECT * FROM ${table}`);
return rows;
} catch (error) {
this.handleDatabaseError(error, `Erro ao buscar todos os registros da tabela ${table}`);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async findOne(table: string, id: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [rows] = await queryRunner.query(`SELECT * FROM ${table} WHERE id = '${id}'`);
return rows[0];
} catch (error) {
this.handleDatabaseError(error, `Erro ao buscar o registro com ID ${id} na tabela ${table}`);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async create(table: string, data: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const columns = Object.keys(data).map((key) => `${key}`).join(', ');
const values = Object.values(data);
const placeholders = values.map(() => '?').join(', ');
const query = `INSERT INTO ${table} (${columns}) VALUES (${placeholders})`;
const [result] = await queryRunner.query(query, values);
return result;
} catch (error) {
this.handleDatabaseError(error, `Erro ao criar um registro na tabela ${table}`);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async update(table: string, where: any, data: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [result] = await queryRunner.query(`UPDATE ${table} SET ${data} WHERE ${where}`);
return result;
} catch (error) {
this.handleDatabaseError(error, `Erro ao atualizar o registro com ${where} na tabela ${table}`);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async delete(table: string, where: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [result] = await queryRunner.query(`DELETE FROM ${table} WHERE ${where}`);
return result;
} catch (error) {
this.handleDatabaseError(error, `Erro ao deletar o registro com ID ${where} na tabela ${table}`);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async query(queryString: string, params: any[]): Promise<any[]> {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [rows] = await queryRunner.query(queryString, params);
return rows as any[];
} catch (error) {
this.handleDatabaseError(error, `Erro ao executar a consulta SQL personalizada`);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async executeView(viewName: string, params: Record<string, any>) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
// Valida se o nome da view foi fornecido
if (!viewName) {
throw new Error('O nome da view é obrigatório.');
}
console.log(`Iniciando execução da view: ${viewName}`);
console.log('Parâmetros recebidos:', params);
const conditions: string[] = [];
const values: any[] = [];
// Remove o parâmetro viewName dos parâmetros antes de processar
const filteredParams = { ...params };
delete filteredParams.viewName;
// Adiciona as condições baseadas nos parâmetros fornecidos
if (filteredParams && Object.keys(filteredParams).length > 0) {
console.log('Adicionando condições para os parâmetros fornecidos...');
for (const [key, value] of Object.entries(filteredParams)) {
// Verifica se a chave e o valor são válidos
if (value !== undefined && value !== null && value !== '') {
console.log(`Parâmetro válido: ${key} = '${value}'`);
conditions.push(`${key} = '${value}'`); // Adiciona aspas para evitar problemas de SQL injection
values.push(value);
} else {
console.warn(`Parâmetro ignorado: ${key} = '${value}'`);
}
}
} else {
console.log('Nenhum parâmetro válido foi fornecido.');
}
// Monta a cláusula WHERE somente se houver condições
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
const query = `SELECT * FROM ${ viewName } ${whereClause}`;
console.log(`Consulta SQL montada: ${ query }`);
console.log(`{Valores para a consulta:, ${values}`);
// Executa a consulta
const rows = await queryRunner.query(query);
console.log(`Consulta executada com sucesso.Linhas retornadas: ${ JSON.stringify(rows) }`);
return rows;
} catch (error) {
console.error(`Erro ao executar a view ${ viewName }: `, error.message);
this.handleDatabaseError(
error,
`Erro ao executar a view ${ viewName } com parâmetros.`,
);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async executeProcedure(procedureName: string, params: Record<string, any>) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const placeholders = Object.keys(params)
.map(() => '?')
.join(', ');
const values = Object.values(params);
const query = `EXECUTE IMMEDIATE ${ procedureName }(${ placeholders })`;
// Log da query e dos valores
console.log('Query executada:', query);
console.log('Valores:', values);
const [result] = await queryRunner.query(query, values);
// Verifica e converte campos que contenham JSON strings para objetos
const parsedResult = Array.isArray(result)
? result.map((row) => {
const parsedRow = { ...row };
for (const [key, value] of Object.entries(parsedRow)) {
try {
// Tenta converter strings JSON para objetos
if (typeof value === 'string' && value.trim().startsWith('{') && value.trim().endsWith('}')) {
parsedRow[key] = JSON.parse(value);
}
} catch (error) {
// Ignora se a conversão falhar
console.warn(`Campo ${ key } não é um JSON válido.Mantendo como string.`);
}
}
return parsedRow;
})
: result;
// Retorna os valores e o resultado
return {
message: 'Procedure executada com sucesso.',
executedQuery: query,
values: values,
result: parsedResult,
};
} catch (error) {
this.handleDatabaseError(
error,
`Erro ao executar a procedure ${ procedureName } com parâmetros.`,
);
}
}
private handleDatabaseError(error: any, message: string): never {
console.error(message, error); // Log detalhado do erro
throw new InternalServerErrorException({
message,
sqlMessage: error.sqlMessage || error.message,
sqlState: error.sqlState,
});
}
async sendImages(file: string) {
// for (const file of files) {
// const file = 'C:\\Temp\\brasil_2.jpg'
if (file.endsWith(".jpg")) {
const fileName = file; //directoryImages + '\\' + file;
fs.readFile(fileName, (err, data) => {
if (err) throw err;
if (err) {
console.log(`WRITE ERROR: ${err}`);
} else {
this.uploadS3(data, 'jur-saidaretornoveiculo', file.replace('./uploads/', ''));
}
});
}
//}
}
async uploadS3(file, bucket, name) {
const s3 = this.getS3();
const params = {
Bucket: bucket,
Key: String(name),
Body: file,
};
return new Promise((resolve, reject) => {
s3.upload(params, (err, data) => {
if (err) {
console.log(JSON.stringify(err));
reject(err.message);
}
resolve(data);
});
});
}
getS3() {
return new S3({
accessKeyId: "AKIAVHJOO6W765ZT2PNI", //process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: "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", // process.env.AWS_SECRET_ACCESS_KEY,
});
}
}

View File

@@ -0,0 +1,11 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Controller } from '@nestjs/common';
@Controller()
export class NegotiationsController { }

View File

@@ -0,0 +1,19 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
import { NegotiationsController } from './negotiations.controller';
import { NegotiationsService } from './negotiations.service';
@Module({
imports: [],
controllers: [
NegotiationsController,],
providers: [
NegotiationsService,],
})
export class NegotiationsModule { }

View File

@@ -0,0 +1,11 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/providers#services
*/
import { Injectable } from '@nestjs/common';
@Injectable()
export class NegotiationsService { }

View File

@@ -0,0 +1,17 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
import { OccurrencesService } from './occurrences.service';
@Module({
imports: [],
controllers: [],
providers: [
OccurrencesService,],
})
export class OccurrencesModule { }

View File

@@ -0,0 +1,10 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/providers#services
*/
import { Injectable } from '@nestjs/common';
@Injectable()
export class OccurrencesService { }

View File

@@ -0,0 +1,10 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Controller } from '@nestjs/common';
@Controller()
export class OcorrencesController { }

View File

@@ -0,0 +1,32 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
@Controller('api/v1/crm/reason')
export class ReasonTableController {
@Get()
async getReasons() {
return null;
}
@Post()
async createReasons() {
return null;
}
@Put('/:id')
async updateReasons(@Param('id') id: number) {
return null;
}
@Delete('/:id')
async deleteReasons(@Param('id') id: number) {
return null;
}
}

View File

@@ -0,0 +1,19 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
import { ReasonTableController } from './reason-table.controller';
import { ReasonTableService } from './reason-table.service';
@Module({
imports: [],
controllers: [
ReasonTableController,],
providers: [
ReasonTableService,],
})
export class ReasonTableModule { }

View File

@@ -0,0 +1,10 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars *//*
https://docs.nestjs.com/providers#services
*/
import { Injectable } from '@nestjs/common';
@Injectable()
export class ReasonTableService { }

View File

@@ -0,0 +1,44 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Controller, Get, Param } from '@nestjs/common';
import { DataConsultService } from './data-consult.service';
@Controller('api/v1/data-consult')
export class DataConsultController {
constructor(private readonly dataConsultService: DataConsultService) {}
@Get('stores')
async stores() {
return this.dataConsultService.stores();
}
@Get('sellers')
async sellers() {
return this.dataConsultService.sellers();
}
@Get('billings')
async billings() {
return this.dataConsultService.billings();
}
@Get('customers/:filter')
async customer(@Param('filter') filter: string) {
return this.dataConsultService.customers(filter);
}
@Get('products/:filter')
async products(@Param('filter') filter: string) {
return this.dataConsultService.products(filter);
}
}

View File

@@ -0,0 +1,19 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { DataConsultService } from './data-consult.service';
import { DataConsultController } from './data-consult.controller';
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
@Module({
imports: [],
controllers: [
DataConsultController,],
providers: [
DataConsultService,],
})
export class DataConsultModule { }

View File

@@ -0,0 +1,170 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/providers#services
*/
import { Injectable } from '@nestjs/common';
import { typeOrmConfig } from 'src/core/configs/typeorm.config';
import { DataSource } from 'typeorm';
@Injectable()
export class DataConsultService {
async stores() {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCFILIAL.CODIGO as "id"
,PCFILIAL.RAZAOSOCIAL as "name"
,PCFILIAL.CODIGO || ' - ' || PCFILIAL.FANTASIA as "store"
FROM PCFILIAL
WHERE PCFILIAL.CODIGO NOT IN ('99', '69')
ORDER BY TO_NUMBER(PCFILIAL.CODIGO)`;
const stores = await queryRunner.manager.query(sql);
return stores;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async sellers() {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCUSUARI.CODUSUR as "id"
,PCUSUARI.NOME as "name"
FROM PCUSUARI
WHERE PCUSUARI.DTTERMINO IS NULL
AND PCUSUARI.TIPOVEND NOT IN ('P')
ORDER BY PCUSUARI.NOME`;
const sellers = await queryRunner.manager.query(sql);
return sellers;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async billings() {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCCOB.CODCOB as "id"
,PCCOB.CODCOB||' - '||PCCOB.COBRANCA as "description"
FROM PCCOB
WHERE PCCOB.CODCOB NOT IN ('DEVP', 'DEVT', 'DESD')
ORDER BY PCCOB.COBRANCA`;
const sellers = await queryRunner.manager.query(sql);
return sellers;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async customers(filter: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
let sql = `SELECT PCCLIENT.CODCLI as "id"
,PCCLIENT.CODCLI || ' - '|| PCCLIENT.CLIENTE||
' ( '||REGEXP_REPLACE(PCCLIENT.CGCENT, '[^0-9]', '')||' )' as "name"
FROM PCCLIENT
WHERE PCCLIENT.CODCLI = REGEXP_REPLACE('${filter}', '[^0-9]', '')
ORDER BY PCCLIENT.CLIENTE`;
let customers = await queryRunner.manager.query(sql);
if (customers.length == 0) {
sql = `SELECT PCCLIENT.CODCLI as "id"
,PCCLIENT.CODCLI || ' - '|| PCCLIENT.CLIENTE||
' ( '||REGEXP_REPLACE(PCCLIENT.CGCENT, '[^0-9]', '')||' )' as "name"
FROM PCCLIENT
WHERE REGEXP_REPLACE(PCCLIENT.CGCENT, '[^0-9]', '') = REGEXP_REPLACE('${filter}', '[^0-9]', '')
ORDER BY PCCLIENT.CLIENTE`;
customers = await queryRunner.manager.query(sql);
}
if (customers.length == 0) {
sql = `SELECT PCCLIENT.CODCLI as "id"
,PCCLIENT.CODCLI || ' - '|| PCCLIENT.CLIENTE||
' ( '||REGEXP_REPLACE(PCCLIENT.CGCENT, '[^0-9]', '')||' )' as "name"
FROM PCCLIENT
WHERE PCCLIENT.CLIENTE LIKE '${filter.toUpperCase().replace('@', '%')}%'
ORDER BY PCCLIENT.CLIENTE`;
customers = await queryRunner.manager.query(sql);
}
return customers;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async products(filter: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
let sql = `SELECT PCPRODUT.CODPROD as "id"
,PCPRODUT.CODPROD || ' - '|| PCPRODUT.DESCRICAO||
' ( '||REGEXP_REPLACE(PCPRODUT.CODAUXILIAR, '[^0-9]', '')||' )' as "description"
FROM PCPRODUT
WHERE PCPRODUT.CODPROD = REGEXP_REPLACE('${filter}', '[^0-9]', '')
ORDER BY PCPRODUT.DESCRICAO`;
let products = await queryRunner.manager.query(sql);
if (products.length == 0) {
sql = `SELECT PCPRODUT.CODPROD as "id"
,PCPRODUT.CODPROD || ' - '|| PCPRODUT.DESCRICAO||
' ( '||REGEXP_REPLACE(PCPRODUT.CODAUXILIAR, '[^0-9]', '')||' )' as "description"
FROM PCPRODUT
WHERE PCPRODUT.CODAUXILIAR = REGEXP_REPLACE('${filter}', '[^0-9]', '')
ORDER BY PCPRODUT.DESCRICAO`;
products = await queryRunner.manager.query(sql);
}
if (products.length == 0) {
sql = `SELECT PCPRODUT.CODPROD as "id"
,PCPRODUT.CODPROD || ' - '|| PCPRODUT.DESCRICAO||
' ( '||REGEXP_REPLACE(PCPRODUT.CODAUXILIAR, '[^0-9]', '')||' )' as "description"
FROM PCPRODUT
WHERE PCPRODUT.DESCRICAO LIKE '${filter}%'
ORDER BY PCPRODUT.DESCRICAO`;
products = await queryRunner.manager.query(sql);
}
return products;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
}

View File

@@ -0,0 +1,51 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { LogisticService } from './logistic.service';
import { CarOutDelivery } from 'src/core/models/car-out-delivery.model';
import { CarInDelivery } from 'src/core/models/car-in-delivery.model';
@Controller('api/v1/logistic')
export class LogisticController {
constructor( private readonly logisticService: LogisticService) {}
@Get('expedicao')
getExpedicao() {
try {
return this.logisticService.getExpedicao();
} catch (err) {
console.log(err);
}
}
@Get('employee')
getEmployee() {
return this.logisticService.getEmployee();
}
@Get('deliveries/:placa')
getDelivery(@Param('placa') placa: string) {
return this.logisticService.getDeliveries(placa);
}
@Get('status-car/:placa')
getStatusCar(@Param('placa') placa: string) {
return this.logisticService.getStatusCar(placa);
}
@Post('create')
createOutCar(@Body() data: CarOutDelivery) {
return this.logisticService.createCarOut(data);
}
@Post('return-car')
createinCar(@Body() data: CarInDelivery) {
return this.logisticService.createCarIn(data);
}
}

View File

@@ -0,0 +1,15 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { LogisticController } from './logistic.controller';
import { LogisticService } from './logistic.service';
import { Module } from '@nestjs/common';
@Module({
imports: [],
controllers: [
LogisticController,],
providers: [
LogisticService,],
})
export class LogisticModule { }

View File

@@ -0,0 +1,353 @@
import { Length } from './../../node_modules/aws-sdk/clients/quicksight.d';
import { count } from './../../node_modules/aws-sdk/clients/health.d';
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Get, HttpException, HttpStatus, Injectable, Query, UseGuards } from '@nestjs/common';
import { stringify } from 'querystring';
import { typeOrmConfig, typeOrmPgConfig } from 'src/core/configs/typeorm.config';
import { CarOutDelivery } from 'src/core/models/car-out-delivery.model';
import { BaseService } from 'src/core/services/base.service';
import { DataSource } from 'typeorm';
import { CarInDelivery } from 'src/core/models/car-in-delivery.model';
@Injectable()
export class LogisticService {
async getExpedicao() {
const dataSource = new DataSource(typeOrmPgConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sqlWMS = `select dados.*,
( select count(distinct v.numero_carga) quantidade_cargas_embarcadas
from volume v, carga c2
where v.numero_carga = c2.numero
and c2.data_integracao >= TO_DATE('01/02/2025', 'DD/MM/YYYY')
and TO_DATE(RIGHT(c2.observacao, 10), 'DD/MM/YYYY') = dados.dataHoje
and v.embarcado = 'S' ) quantidade_cargas_embarcadas
FROM ( select date_trunc('day', (CURRENT_DATE + INTERVAL '1 day'))::date data_saida, --TO_DATE(RIGHT(c.observacao, 10), 'DD/MM/YYYY') data_saida,
date_trunc('day', (CURRENT_DATE + INTERVAL '1 day'))::date dataHoje,
SUM(c.qt_itens_conferidos) total_itens_conferidos,
SUM(c.qt_itens_separados) total_itens_separados,
SUM(c.qt_total_itens) quantidade_total_itens,
SUM(c.qt_total_pedidos) quantidade_total,
SUM(m.qt * p.peso_unidade) total_kg,
COUNT(DISTINCT c.numero) quantidade_cargas,
COUNT(DISTINCT (CASE WHEN m.data_fim_separacao is not null then c.numero else null end)) quantidade_cargas_separacao_finalizadas,
COUNT(DISTINCT (CASE WHEN m.data_fim_conferencia is not null then c.numero else null end)) quantidade_cargas_conferencia_finalizadas,
SUM(case when m.data_inicio_separacao is null then m.qt * p.peso_unidade else 0 end) total_peso_separacao_nao_iniciada,
SUM(case when m.data_inicio_separacao is not null and m.data_fim_separacao is null then m.qt * p.peso_unidade else 0 end) total_peso_em_separacao,
SUM(case when m.data_fim_separacao is not null then m.qt * p.peso_unidade else 0 end) total_peso_separado,
SUM(case when m.data_fim_separacao is not null and m.data_inicio_conferencia is null then m.qt * p.peso_unidade else 0 end) total_conferencia_nao_iniciada,
SUM(case when m.data_fim_separacao is not null and m.data_inicio_conferencia is not null and m.data_fim_conferencia is null then m.qt * p.peso_unidade else 0 end) total_peso_em_conferencia,
SUM(case when m.data_fim_conferencia is not null then m.qt * p.peso_unidade else 0 end) total_peso_conferido
from movimentacao m , carga c , produto p
where m.numero_carga = c.numero
and m.produto_id = p.id
and m.data_integracao >= TO_DATE('01/01/2025', 'DD/MM/YYYY')
and c.data_faturamento IS NULL
and c.destino not like '%TRANSF%'
and m.empresa_id in ( 3, 4 )
--group by TO_DATE(RIGHT(c.observacao, 10), 'DD/MM/YYYY')
) dados
where dados.data_saida >= current_date
ORDER BY dados.data_saida desc `;
const sql = `SELECT COUNT(DISTINCT PCCARREG.NUMCAR) as "qtde"
,SUM(PCPEDI.QT * PCPRODUT.PESOBRUTO) as "totalKG"
,SUM(CASE WHEN PCPEDC.DTINICIALSEP IS NULL THEN PCPEDI.QT ELSE 0 END * PCPRODUT.PESOBRUTO) as "total_nao_iniciado"
,SUM(CASE WHEN PCPEDC.DTINICIALSEP IS NOT NULL
AND PCPEDC.DTFINALSEP IS NULL THEN PCPEDI.QT ELSE 0 END * PCPRODUT.PESOBRUTO) as "total_em_separacao"
,SUM(CASE WHEN PCPEDC.DTFINALSEP IS NOT NULL THEN PCPEDI.QT ELSE 0 END * PCPRODUT.PESOBRUTO) as "total_separado"
,SUM(CASE WHEN PCPEDC.DTFINALSEP IS NOT NULL
AND PCPEDC.DTINICIALCHECKOUT IS NULL THEN PCPEDI.QT ELSE 0 END * PCPRODUT.PESOBRUTO) as "total_conferencia_nao_iniciada"
,SUM(CASE WHEN PCPEDC.DTFINALSEP IS NOT NULL
AND PCPEDC.DTINICIALCHECKOUT IS NOT NULL
AND PCPEDC.DTFINALCHECKOUT IS NULL THEN PCPEDI.QT ELSE 0 END * PCPRODUT.PESOBRUTO) as "total_em_conferencia"
,SUM(CASE WHEN PCPEDC.DTFINALSEP IS NOT NULL
AND PCPEDC.DTFINALCHECKOUT IS NOT NULL THEN PCPEDI.QT ELSE 0 END * PCPRODUT.PESOBRUTO) as "total_coferencia_finalizada"
FROM PCPEDI, PCPEDC, PCPRODUT, PCCARREG
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND PCPEDI.CODPROD = PCPRODUT.CODPROD
AND PCPEDI.NUMCAR = PCCARREG.NUMCAR
AND PCPEDC.CODFILIAL = 12
AND PCPEDI.TIPOENTREGA IN ('EN', 'EF')
AND PCCARREG.DTSAIDA = TRUNC(SYSDATE)`;
const mov = await queryRunner.manager.query(sqlWMS);
const hoje = new Date();
// Criar uma nova data para amanhã
let amanha = new Date(hoje);
amanha.setDate(hoje.getDate() + 1);
const amanhaString = amanha.toISOString().split('T')[0];
amanha = new Date(amanhaString);
console.log(amanha);
console.log(JSON.stringify(mov));
const movFiltered = mov.filter((m) => m.data_saida.toISOString().split('T')[0] == amanha.toISOString().split('T')[0]);
return movFiltered;
} catch (e) {
console.log(e);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getDeliveries(placa: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCCARREG.NUMCAR as "id"
,PCCARREG.DTSAIDA as "createDate"
,PCCARREG.DESTINO as "comment"
,PCCARREG.TOTPESO as "weight"
,PCCARREG.NUMNOTAS as "invoices"
,( SELECT COUNT(DISTINCT NVL(PCCLIENTENDENT.CODPRACAENT, PCPEDC.CODPRACA))
FROM PCPEDC, PCCLIENTENDENT
WHERE PCPEDC.NUMCAR = PCCARREG.NUMCAR
AND PCPEDC.CODENDENTCLI = PCCLIENTENDENT.CODENDENTCLI (+) ) as "citys"
,( SELECT COUNT(DISTINCT PCPEDC.CODCLI) FROM PCPEDC
WHERE PCPEDC.NUMCAR = PCCARREG.NUMCAR) as "deliveries"
,PCCARREG.CODMOTORISTA as "driverId"
,PCEMPR.NOME as "driverName"
,PCVEICUL.CODVEICULO as "carId"
,PCVEICUL.DESCRICAO as "carDescription"
,PCVEICUL.PLACA as "identification"
,PCCARREG.CODFUNCAJUD as "helperId"
,PCCARREG.CODFUNCAJUD2 as "helperId1"
,PCCARREG.CODFUNCAJUD3 as "helperId2"
FROM PCCARREG, PCVEICUL, PCEMPR
WHERE PCCARREG.CODVEICULO = PCVEICUL.codveiculo (+)
AND PCCARREG.CODMOTORISTA = PCEMPR.MATRICULA (+)
AND PCCARREG.DTFECHA IS NULL
AND PCCARREG.DTSAIDA >= TRUNC(SYSDATE)`;
const deliveries = await queryRunner.manager.query(sql);
return deliveries;
} catch (e) {
console.log(e);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getStatusCar(placa: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT ESTSAIDAVEICULO.CODSAIDA FROM ESTSAIDAVEICULO, PCVEICUL
WHERE ESTSAIDAVEICULO.CODVEICULO = PCVEICUL.CODVEICULO
AND PCVEICUL.PLACA = '${placa}'
AND ESTSAIDAVEICULO.DTRETORNO IS NULL`;
const outCar = await queryRunner.manager.query(sql);
return { veiculoEmViagem: ( outCar.length > 0 ) ? true : false };
} catch (e) {
console.log(e);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getEmployee() {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCEMPR.MATRICULA as "id"
,PCEMPR.NOME as "name"
,PCEMPR.FUNCAO as "fuctionName"
FROM PCEMPR, PCCONSUM
WHERE PCEMPR.DTDEMISSAO IS NULL
AND PCEMPR.CODSETOR = PCCONSUM.CODSETOREXPED
ORDER BY PCEMPR.NOME `;
const dataEmployee = await queryRunner.query(sql);
return dataEmployee;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async createCarOut(data: CarOutDelivery) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sqlSequence = `SELECT ESS_SAIDAVEICULO.NEXTVAL as "id" FROM DUAL`;
const dataSequence = await queryRunner.query(sqlSequence);
let i = 0;
let helperId1: number = 0;
let helperId2: number = 0;
let helperId3: number = 0;
let image1: string = '';
let image2: string = '';
let image3: string = '';
let image4: string = '';
data.helpers.forEach(helper => {
switch (i) {
case 0:
helperId1 = helper.id;
break;
case 1:
helperId2 = helper.id;
break;
case 2:
helperId3 = helper.id;
break;
}
i++;
});
for (let y = 0; y < data.photos.length; y++) {
const sqlImage = `INSERT INTO ESTSAIDAVEICULOIMAGENS ( CODSAIDA, TIPO, URL )
VALUES (${dataSequence[0].id}, 'SA', '${data.photos[y]}' )`;
await queryRunner.query(sqlImage);
}
const sqlSaidaVeiculo = `INSERT INTO ESTSAIDAVEICULO ( CODSAIDA, CODVEICULO, DTSAIDA, QTAJUDANTES, CODFUNCSAIDA )
VALUES ( ${dataSequence[0].id}, ${data.vehicleCode}, SYSDATE, ${data.helpers.length},
${data.userCode} )`;
await queryRunner.query(sqlSaidaVeiculo);
for (let y = 0; y < data.numberLoading.length; y++) {
const sqlLoading = `INSERT INTO ESTSAIDAVEICULOCARREG ( CODSAIDA, NUMCAR )
VALUES ( ${dataSequence[0].id}, ${data.numberLoading[y]})`;
await queryRunner.query(sqlLoading);
const sql = `UPDATE PCCARREG SET
DTSAIDAVEICULO = SYSDATE
,CODFUNCAJUD = ${helperId1}
,CODFUNCAJUD2 = ${helperId2}
,CODFUNCAJUD3 = ${helperId3}
,KMINICIAL = ${data.startKm}
WHERE NUMCAR = ${data.numberLoading[y]}`;
await queryRunner.query(sql);
}
await queryRunner.commitTransaction();
return { message: 'Dados da saída de veículo gravada com sucesso!'}
} catch (e) {
await queryRunner.rollbackTransaction();
throw e;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async createCarIn(data: CarInDelivery) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sqlOutCar = `SELECT ESTSAIDAVEICULO.CODSAIDA as "id"
FROM PCCARREG, PCVEICUL, ESTSAIDAVEICULO, ESTSAIDAVEICULOCARREG
WHERE PCCARREG.CODVEICULO = PCVEICUL.CODVEICULO
AND PCCARREG.NUMCAR = ESTSAIDAVEICULOCARREG.NUMCAR
AND ESTSAIDAVEICULOCARREG.CODSAIDA = ESTSAIDAVEICULO.CODSAIDA
-- AND ESTSAIDAVEICULO.DTRETORNO IS NULL
AND PCVEICUL.PLACA = '${data.licensePlate}'`;
const dataOutCar = await queryRunner.query(sqlOutCar);
if ( dataOutCar.length == 0 ) {
throw new HttpException('Não foi localiza viagens em aberto para este veículo.', HttpStatus.BAD_REQUEST );
}
let i = 0;
let image1: string = '';
let image2: string = '';
let image3: string = '';
let image4: string = '';
for (let y = 0; y < data.invoices.length; y++) {
const invoice = data.invoices[y];
const sqlInvoice = `INSERT INTO ESTRETORNONF ( CODSAIDA, NUMCAR, NUMNOTA, SITUACAO, MOTIVO )
VALUES ( ${dataOutCar[0].id}, ${invoice.loadingNumber}, ${invoice.invoiceNumber},
'${invoice.status}', '${invoice.reasonText}')`;
await queryRunner.query(sqlInvoice);
}
const updateCarreg = `UPDATE PCCARREG SET
PCCARREG.DTRETORNO = SYSDATE
,PCCARREG.KMFINAL = ${data.finalKm}
WHERE PCCARREG.NUMCAR IN ( SELECT SC.NUMCAR
FROM ESTSAIDAVEICULOCARREG SC
WHERE SC.CODSAIDA = ${dataOutCar[0].id} )`;
await queryRunner.query(updateCarreg);
for (let i = 0; i < data.images.length; i++) {
const sqlImage = `INSERT INTO ESTSAIDAVEICULOIMAGENS ( CODSAIDA, TIPO, URL )
VALUES (${dataOutCar[0].id}, 'RE', '${data.images[i]}' )`;
await queryRunner.query(sqlImage);
}
const sqlInCar = `UPDATE ESTSAIDAVEICULO SET
ESTSAIDAVEICULO.DTRETORNO = SYSDATE
,ESTSAIDAVEICULO.QTPALETES_PBR = ${data.qtdPaletesPbr}
,ESTSAIDAVEICULO.QTPALETES_CIM = ${data.qtdPaletesCim}
,ESTSAIDAVEICULO.QTPALETES_DES = ${data.qtdPaletesDes}
,ESTSAIDAVEICULO.codfuncretorno = ${data.userId}
,ESTSAIDAVEICULO.obsretorno = '${data.observation}'
,ESTSAIDAVEICULO.HOUVESOBRA = '${data.remnant}'
,ESTSAIDAVEICULO.OBSSOBRA = '${data.observationRemnant}'
WHERE ESTSAIDAVEICULO.CODSAIDA = ${dataOutCar[0].id}`;
await queryRunner.query(sqlInCar);
for (let i = 0; i < data.imagesRemnant.length; i++) {
const sqlImage = `INSERT INTO ESTSAIDAVEICULOIMAGENS ( CODSAIDA, TIPO, URL )
VALUES (${dataOutCar[0].id}, 'SO', '${data.imagesRemnant[i]}' )`;
await queryRunner.query(sqlImage);
}
await queryRunner.commitTransaction();
return { message: 'Dados de retorno do veículo gravada com sucesso!'}
} catch (e) {
await queryRunner.rollbackTransaction();
console.log(e);
throw e;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
}

27
src/main.ts Normal file
View File

@@ -0,0 +1,27 @@
/* eslint-disable prettier/prettier */
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as fs from 'fs';
async function bootstrap() {
// const privateKey = fs.readFileSync('cert/portal_juru.key', 'utf8');
// const certificate = fs.readFileSync('cert/portal_juru.crt', 'utf8');
// const httpsOptions = { key: privateKey, cert: certificate };
// const app = await NestFactory.create(AppModule, {
// httpsOptions,
// });
const app = await NestFactory.create(AppModule);
// const app = await NestFactory.create(AppModule);
//Configurando o CORS
app.enableCors({
origin: '*', //'http://portal.jurunense.com', // Especifique a origem permitida ou use '*' para permitir todas
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', // Métodos HTTP permitidos
credentials: true, // Permitir envio de cookies
allowedHeaders: 'Content-Type, Accept', // Cabeçalhos permitidos
});
await app.listen(3001);
}
bootstrap();

View File

@@ -0,0 +1,40 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { OrdersPaymentService } from './orders-payment.service';
@Controller('api/v1/orders-payment')
export class OrdersPaymentController {
constructor(private readonly orderPaymentService: OrdersPaymentService){}
@Get('orders/:id')
findOrders(@Param('id') storeId: string) {
return this.orderPaymentService.findOrders(storeId, 0);
}
@Get('orders/:id/:orderId')
findOrder(@Param('id') storeId: string,
@Param('orderId') orderId: number) {
return this.orderPaymentService.findOrders(storeId, orderId);
}
@Get('payments/:id')
findPayments(@Param('id') orderId: number) {
return this.orderPaymentService.findPayments(orderId);
}
@Post('payments/create')
createPayment(@Body() data: any) {
return this.orderPaymentService.createPayment(data);
}
@Post('invoice/create')
createInvoice(@Body() data: any) {
return this.orderPaymentService.createInvoice(data);
}
}

View File

@@ -0,0 +1,19 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
import { OrdersPaymentController } from './orders-payment.controller';
import { OrdersPaymentService } from './orders-payment.service';
@Module({
imports: [],
controllers: [
OrdersPaymentController,],
providers: [
OrdersPaymentService,],
})
export class OrdersPaymentModule { }

View File

@@ -0,0 +1,141 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/providers#services
*/
import { Injectable } from '@nestjs/common';
import { typeOrmConfig } from 'src/core/configs/typeorm.config';
import { DataSource } from 'typeorm';
@Injectable()
export class OrdersPaymentService {
async findOrders(storeId: string, orderId: number) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCPEDC.DATA as "createDate"
,PCPEDC.CODFILIAL as "storeId"
,PCPEDC.NUMPED as "orderId"
,PCPEDC.CODCLI as "customerId"
,PCCLIENT.CLIENTE as "customerName"
,PCPEDC.CODUSUR as "sellerId"
,PCUSUARI.NOME as "sellerName"
,PCPEDC.CODCOB as "billingId"
,PCCOB.COBRANCA as "billingName"
,PCPEDC.CODPLPAG as "planId"
,PCPLPAG.DESCRICAO as "planName"
,ROUND(PCPEDC.VLATEND,2) as "amount"
,NVL(PCPLPAG.NUMPARCELAS,1) as "installments"
,( SELECT SUM(ESTPAGAMENTO.VALOR) FROM ESTPAGAMENTO
WHERE ESTPAGAMENTO.NUMORCA = PCPEDC.NUMPED ) as "amountPaid"
FROM PCPEDC, PCCLIENT, PCUSUARI, PCCOB, PCPLPAG
WHERE PCPEDC.CODCLI = PCCLIENT.CODCLI
AND PCPEDC.CODUSUR = PCUSUARI.CODUSUR
AND PCPEDC.CODPLPAG = PCPLPAG.CODPLPAG
AND PCPEDC.CODCOB = PCCOB.CODCOB
AND PCPEDC.CONDVENDA = 7
AND PCPEDC.POSICAO IN ('L')
AND PCPEDC.DATA >= TRUNC(SYSDATE) - 5
AND PCPEDC.CODFILIAL = ${storeId} `;
let sqlWhere = '';
if ( orderId > 0) {
sqlWhere += ` AND PCPEDC.NUMPED = ${orderId}`;
}
const orders = await queryRunner.manager.query(sql + sqlWhere);
return orders;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async findPayments(orderId: number) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT
ESTPAGAMENTO.NUMORCA as "orderId"
,ESTPAGAMENTO.DTPAGAMENTO as "payDate"
,ESTPAGAMENTO.CARTAO as "card"
,ESTPAGAMENTO.PARCELAS as "installments"
,ESTPAGAMENTO.NOMEBANDEIRA as "flagName"
,ESTPAGAMENTO.FORMAPAGTO as "type"
,ESTPAGAMENTO.VALOR as "amount"
,ESTPAGAMENTO.CODFUNC as "userId"
,ESTPAGAMENTO.NSU as "nsu"
,ESTPAGAMENTO.CODAUTORIZACAO as "auth"
FROM ESTPAGAMENTO
WHERE ESTPAGAMENTO.NUMORCA = ${orderId}`;
const payments = await queryRunner.manager.query(sql);
console.log(JSON.stringify(payments));
return payments;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async createPayment(payment: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sql = `INSERT INTO ESTPAGAMENTO ( NUMORCA, DTPAGAMENTO, CARTAO, CODAUTORIZACAO, CODRESPOSTA, DTREQUISICAO, DTSERVIDOR, IDTRANSACAO,
NSU, PARCELAS, VALOR, NOMEBANDEIRA, FORMAPAGTO, DTPROCESSAMENTO, CODFUNC )
VALUES ( ${payment.orderId}, TRUNC(SYSDATE), '${payment.card}', '${payment.auth}', '00', SYSDATE, SYSDATE, NULL /*'${payment.transcationId}'*/,
'${payment.nsu}', ${payment.installments}, ${payment.amount}, '${payment.flagName}',
'${payment.paymentType}', SYSDATE, ${payment.userId} ) `;
await queryRunner.manager.query(sql);
await queryRunner.commitTransaction();
} catch ( error ) {
await queryRunner.rollbackTransaction();
console.log(error);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async createInvoice(data: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sql = `BEGIN
ESK_FATURAMENTO.FATURAMENTO_VENDA_ASSISTIDA(${data.orderId}, ${data.userId});
END;`;
await queryRunner.manager.query(sql);
await queryRunner.commitTransaction();
} catch ( error ) {
await queryRunner.rollbackTransaction();
console.log(error);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
}

View File

@@ -0,0 +1,55 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
import { OrdersService } from './orders.service';
@Controller('api/v1/orders')
export class OrdersController {
constructor( private readonly ordersService: OrdersService) {}
@Get('find')
findOrders(@Query() query) {
return this.ordersService.findOrders(query);
}
@Get('invoice/:chavenfe')
findInvoice(@Param('chavenfe') chavenfe: string) {
return this.ordersService.findInvoice(chavenfe);
}
@Get('itens/:id')
getItens(@Param('id') id: string) {
return this.ordersService.getItens(id);
}
@Get('cut-itens/:id')
getCutItens(@Param('id') id: string) {
return this.ordersService.getCutItens(id);
}
@Get('delivery/:id')
getOrderDelivery(@Param('id') id: string) {
return this.ordersService.getOrderDelivery(id);
}
@Get('transfer/:id')
getTransfer(@Param('id') id: number) {
return this.ordersService.getTransfer(id);
}
@Get('status/:id')
getStatusOrder(@Param('id') id: number) {
return this.ordersService.getStatusOrder(id);
}
@Post('invoice-check')
createInvoiceCheck(@Body() invoice: any) {
return this.ordersService.createInvoiceCheck(invoice);
}
}

View File

@@ -0,0 +1,19 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { OrdersService } from './orders.service';
import { OrdersController } from './orders.controller';
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
@Module({
imports: [],
controllers: [
OrdersController,],
providers: [
OrdersService,],
})
export class OrdersModule { }

View File

@@ -0,0 +1,648 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/providers#services
*/
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { typeOrmConfig } from 'src/core/configs/typeorm.config';
import { DataSource } from 'typeorm';
@Injectable()
export class OrdersService {
async findOrders(query) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
let sql = `SELECT PCPEDC.DATA as "createDate"
,PCPEDC.CODFILIAL || CASE WHEN PCPEDC.CODFILIALLOJA IS NOT NULL THEN
' - Pre-Box ('||PCPEDC.CODFILIALLOJA||')'
ELSE NULL END as "storeId"
,PCPEDC.NUMPED as "orderId"
,PCPEDC.CODCLI as "customerId"
,PCPEDC.CODCLI||' - '||PCCLIENT.CLIENTE as "customerName"
,PCPEDC.CODUSUR as "sellerId"
,PCPEDC.CODUSUR||' - '||PCUSUARI.NOME as "sellerName"
,PCSUPERV.NOME as "store"
,( SELECT CASE WHEN PCPEDI.TIPOENTREGA = 'EN' THEN 'Entrega ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'EF' THEN 'Entrega Futura ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'RP' THEN 'Retira Posterior ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'RI' THEN 'Retira Imediata ('||PCPEDI.TIPOENTREGA||')'
ELSE 'Não Informado' END
FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND ROWNUM = 1 ) as "deliveryType"
,CASE WHEN NVL(PCPEDC.CODENDENTCLI,0) = 0 THEN
( SELECT PCPRACA.CODPRACA||'-'||PCPRACA.PRACA
FROM PCPRACA
WHERE PCPRACA.CODPRACA = PCPEDC.CODPRACA )
ELSE ( SELECT PCPRACA.CODPRACA||'-'||PCPRACA.PRACA
FROM PCCLIENTENDENT, PCPRACA
WHERE PCCLIENTENDENT.CODCLI = PCPEDC.CODCLI
AND PCCLIENTENDENT.CODENDENTCLI = PCPEDC.CODENDENTCLI
AND PCCLIENTENDENT.CODPRACAENT = PCPRACA.CODPRACA ) END as "deliveryLocal"
,CASE WHEN NVL(PCPEDC.CODENDENTCLI,0) = 0 THEN
( SELECT PCROTAEXP.CODROTA||'-'||PCROTAEXP.DESCRICAO
FROM PCPRACA, PCROTAEXP
WHERE PCPRACA.CODPRACA = PCPEDC.CODPRACA
AND PCPRACA.ROTA = PCROTAEXP.CODROTA )
ELSE ( SELECT PCROTAEXP.CODROTA||'-'||PCROTAEXP.DESCRICAO
FROM PCCLIENTENDENT, PCPRACA, PCROTAEXP
WHERE PCCLIENTENDENT.CODCLI = PCPEDC.CODCLI
AND PCCLIENTENDENT.CODENDENTCLI = PCPEDC.CODENDENTCLI
AND PCCLIENTENDENT.CODPRACAENT = PCPRACA.CODPRACA
AND PCPRACA.ROTA = PCROTAEXP.CODROTA ) END as "masterDeliveryLocal"
,CASE WHEN PCPEDC.CONDVENDA = 1 THEN 'TV1 - Retira Imediata'
WHEN PCPEDC.CONDVENDA = 7 THEN 'TV7 - Faturamento'
WHEN PCPEDC.CONDVENDA = 8 THEN 'TV8 - Entrega (' ||
( SELECT PCPEDI.TIPOENTREGA FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND ROWNUM = 1 ) ||')'
WHEN PCPEDC.CONDVENDA = 10 THEN 'TV10 - Transferência'
ELSE 'Outros' END as "orderType"
,CASE WHEN PCPEDC.POSICAO = 'P' THEN 'Pendente'
WHEN PCPEDC.POSICAO = 'B' THEN 'Bloqueado'
WHEN PCPEDC.POSICAO = 'L' THEN 'Liberado'
WHEN PCPEDC.POSICAO = 'M' THEN 'Montado'
WHEN PCPEDC.POSICAO = 'F' THEN 'Faturado'
WHEN PCPEDC.POSICAO = 'C' THEN 'Cancelado'
END as "status"
,CASE WHEN PCPEDC.CONDVENDA IN (1,7) THEN PCPEDC.VLATEND ELSE PCPEDC.VLTOTAL END as "amount"
,PCPEDC.DTENTREGA as "deliveryDate"
,CASE WHEN PCPEDC.tipoprioridadeentrega = 'B' THEN 'Baixa'
WHEN PCPEDC.TIPOPRIORIDADEENTREGA = 'M' THEN 'Média'
WHEN PCPEDC.TIPOPRIORIDADEENTREGA = 'A' THEN 'Alta'
ELSE 'Não Definido' END as "deliveryPriority"
,PCPEDC.NUMCAR as "shipmentId"
,PCPEDC.DTLIBERA as "releaseDate"
,PCPEDC.CODFUNCLIBERA as "releaseUser"
,PCPEDC.CODFUNCLIBERA||'-'||
(SELECT PCEMPR.NOME FROM PCEMPR WHERE PCEMPR.MATRICULA = PCPEDC.CODFUNCLIBERA) as "releaseUserName"
,PCCARREG.DTSAIDA as "shipmentDate"
,PCCARREG.DATAMON as "shipmentDateCreate"
,CASE WHEN PCPEDC.NUMCAR = 0 THEN NULL
ELSE PCCARREG.DTFECHA END as "shipmentCloseDate"
,PCPEDC.CODPLPAG as "paymentId"
,PCPLPAG.DESCRICAO as "paymentName"
,PCPEDC.CODCOB as "billingId"
,PCPEDC.CODCOB||'-'||
PCCOB.COBRANCA as "billingName"
,PCPEDC.DTFAT as "invoiceDate"
,PCPEDC.HORAFAT as "invoiceHour"
,PCPEDC.MINUTOFAT as "invoiceMinute"
,PCPEDC.NUMNOTA as "invoiceNumber"
,PCPEDC.MOTIVOPOSICAO as "BloqDescription"
,PCNFSAID.DTCANHOTO as "confirmDeliveryDate"
,PCPEDC.TOTPESO as "totalWeigth"
,CASE WHEN PCNFSAID.DTCANHOTO IS NOT NULL THEN 4
WHEN PCPEDC.POSICAO = 'F' THEN 3
WHEN PCPEDC.DTFINALSEP IS NOT NULL THEN 2
WHEN PCPEDC.POSICAO = 'M' THEN 1
WHEN PCPEDC.POSICAO IN ('L', 'P', 'B') THEN 0
ELSE 0 END as "processOrder"
,( SELECT COUNT(1) FROM PCPREST, PCNFSAID, PCPEDC PED_VGER
WHERE PCPREST.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA
AND PCNFSAID.NUMTRANSVENDA = PED_VGER.NUMTRANSVENDA
AND PED_VGER.NUMPED = PCPEDC.NUMPEDENTFUT
AND PCPREST.DTPAG IS NULL
AND PCPREST.CODCOB = 'VGER' ) as "payment"
,MOTORISTA.MATRICULA || ' - ' || MOTORISTA.NOME as "driver"
,PCPEDC.NUMPEDENTFUT as "orderSaleId"
,PCVEICUL.DESCRICAO||' ( '|| PCVEICUL.PLACA||' )' as "carDescription"
,PCVEICUL.PLACA as "carIdentification"
,PCPEDC.CODFORNECFRETE||' - '||PCFORNEC.FORNECEDOR as "carrier"
,CASE WHEN (SELECT COUNT(1) FROM PCNFENT, PCFILIAL
WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL
AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC
AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA ) = 0
AND PCPEDC.CONDVENDA = 10
AND PCPEDC.POSICAO = 'F' THEN 'Em Trânsito'
WHEN PCPEDC.POSICAO = 'M'
AND PCPEDC.CONDVENDA = 10 THEN 'Em Separação'
WHEN PCPEDC.POSICAO IN ( 'L', 'P' )
AND PCPEDC.CONDVENDA = 10 THEN 'Aguardando Separação'
WHEN PCPEDC.CONDVENDA NOT IN ( 10 ) THEN NULL
ELSE 'Concluída' END as "statusTransfer"
,PCPEDC.CODFILIALLOJA as "storePreBox"
FROM PCPEDC, PCCLIENT, PCUSUARI, PCSUPERV, PCCOB, PCPLPAG, PCCARREG, PCNFSAID,
PCEMPR MOTORISTA, PCVEICUL, PCFORNEC
WHERE PCPEDC.CODCLI = PCCLIENT.CODCLI
AND PCPEDC.CODUSUR = PCUSUARI.CODUSUR
AND PCPEDC.CODPLPAG = PCPLPAG.CODPLPAG
AND PCPEDC.CODCOB = PCCOB.CODCOB
AND PCPEDC.CODSUPERVISOR = PCSUPERV.CODSUPERVISOR
AND PCPEDC.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA (+)
AND PCPEDC.NUMCAR = PCCARREG.NUMCAR (+)
AND PCCARREG.CODMOTORISTA = MOTORISTA.MATRICULA (+)
AND PCCARREG.CODVEICULO = PCVEICUL.CODVEICULO (+)
AND PCPEDC.CODFORNECFRETE = PCFORNEC.CODFORNEC (+)`;
let sqlWhere = "";
if (query.storeId) {
sqlWhere += ` AND PCPEDC.CODFILIAL = '${query.storeId}'`;
}
if (query.storeStockId) {
sqlWhere += ` AND EXISTS(SELECT PCPEDI.CODPROD FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND PCPEDI.CODFILIALRETIRA = '${query.storeStockId}' )`;
}
if (query.sellerId) {
sqlWhere += ` AND PCPEDC.CODUSUR = ${query.sellerId}`;
}
if (query.customerId) {
sqlWhere += ` AND PCPEDC.CODCLI = ${query.customerId}`;
}
if (query.billingId) {
sqlWhere += ` AND PCPEDC.CODCOB = '${query.billingId}'`;
}
if (query.orderId) {
sqlWhere += ` AND ( PCPEDC.NUMPED = ${query.orderId} or PCPEDC.NUMPEDENTFUT = ${query.orderId} )`;
}
if (query.invoiceId) {
sqlWhere += ` AND PCPEDC.NUMNOTA = ${query.invoiceId}`;
}
if (query.productId) {
sqlWhere += ` AND EXISTS(SELECT PCPEDI.CODPROD FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND PCPEDI.CODPROD = ${query.productId} )`;
}
if (query.createDateIni) {
sqlWhere += ` AND PCPEDC.DATA >= TO_DATE('${query.createDateIni}', 'YYYY-MM-DD')`;
}
if (query.createDateEnd) {
sqlWhere += ` AND PCPEDC.DATA <= TO_DATE('${query.createDateEnd}', 'YYYY-MM-DD')`;
}
if (query.invoiceDateIni) {
sqlWhere += ` AND PCPEDC.DTFAT >= TO_DATE('${query.invoiceDateIni}', 'YYYY-MM-DD')`;
}
if (query.invoiceDateEnd) {
sqlWhere += ` AND PCPEDC.DTFAT <= TO_DATE('${query.invoiceDateEnd}', 'YYYY-MM-DD')`;
}
if (query.shippimentId) {
sqlWhere += ` AND PCPEDC.NUMCAR = ${query.shippimentId}`;
}
if (query.deliveryType) {
const deliveryType: string[] = query.deliveryType.split(',');
const listDeliveryType = deliveryType.map(type => `'${type}'`)
sqlWhere += ` AND EXISTS(SELECT PCPEDI.CODPROD FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND PCPEDI.TIPOENTREGA IN ( ${listDeliveryType} ) )`;
}
if (query.status) {
const statusOrder: string[] = query.status.split(',');
const listStatusOrder = statusOrder.map(status => `'${status}'`)
sqlWhere += ` AND PCPEDC.POSICAO IN ( ${listStatusOrder} )`;
}
if (query.type) {
const typeOrder: string[] = query.type.split(',');
const listTypeOrder = typeOrder.map(type => `'${type}'`)
sqlWhere += ` AND PCPEDC.CONDVENDA IN ( ${listTypeOrder} )`;
}
if (query.onlyPendentingTransfer && query.onlyPendentingTransfer == "S") {
sqlWhere += ` AND NOT EXISTS(SELECT PCNFENT.NUMTRANSENT FROM PCNFENT, PCFILIAL
WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL
AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC
AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA ) `
}
sql += sqlWhere;
sql += ' AND ROWNUM < 5000';
const orders = await queryRunner.manager.query(sql);
return orders;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async findInvoice(chavenfe: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `select pcnfsaid.codfilial as "storeId",
pcnfsaid.dtsaida as "invoiceDate",
pcnfsaid.numped as "orderId",
pcnfsaid.numnota as "invoiceId",
pcnfsaid.numtransvenda as "transactionId",
pcnfsaid.codcli as "customerId",
pcclient.cliente as "customer",
pcnfsaid.codusur as "sellerId",
pcusuari.nome as "sellerName",
( select sum(pcmov.qt) from pcmov where pcmov.numtransvenda = pcnfsaid.numtransvenda ) as "itensQt",
null as "itens"
from pcnfsaid, pcclient, pcusuari
where pcnfsaid.codcli = pcclient.codcli
and pcnfsaid.codusur = pcusuari.codusur
and pcnfsaid.chavenfe = '${chavenfe}'`;
const invoice = await queryRunner.manager.query(sql);
if ( invoice == null || invoice.length == 0 ) {
throw new HttpException('Nota fiscal não foi localizada na sistema', HttpStatus.BAD_REQUEST);
}
const sqlItem = `select pcmov.codprod as "productId"
,pcprodut.descricao as "productName"
,pcprodut.embalagem as "package"
,pcmov.qt as "qt"
,pcprodut.codauxiliar as "ean"
,pcprodut.multiplo as "multiple"
,pcprodut.tipoproduto as "productType"
,REPLACE(CASE WHEN INSTR(PCPRODUT.URLIMAGEM, ';') > 0 THEN
SUBSTR(PCPRODUT.URLIMAGEM,1,INSTR(PCPRODUT.URLIMAGEM, ';') - 1)
WHEN PCPRODUT.URLIMAGEM IS NOT NULL THEN
PCPRODUT.URLIMAGEM
ELSE NULL END, '167.249.211.178:8001', '10.1.1.191') as "image"
from pcmov, pcprodut
where pcmov.codprod = pcprodut.codprod
and pcmov.numtransvenda = ${invoice[0].transactionId}`;
const itens = await queryRunner.manager.query(sqlItem);
const sqlProduct = `SELECT PCPRODUT.URLIMAGEM FROM PCPRODUT WHERE CODPROD = `
invoice[0].itens = [...itens];
return invoice[0];
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getItens(orderId: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCPEDI.CODPROD as "productId"
, PCPRODUT.DESCRICAO as "description"
, PCPRODUT.EMBALAGEM as "pacth"
, NVL(PCPEDI.COMPLEMENTO,
( SELECT TV7I.COMPLEMENTO FROM PCPEDC, PCPEDC TV7, PCPEDITEMP TV7I
WHERE TV7.NUMPED = PCPEDC.NUMPEDENTFUT
AND PCPEDC.NUMPED = PCPEDI.NUMPED
AND TV7.NUMPEDRCA = TV7I.NUMPEDRCA
AND TV7I.CODPROD = PCPEDI.codprod
AND TV7I.NUMSEQ = PCPEDI.NUMSEQ ) ) as "color"
, PCPEDI.CODFILIALRETIRA as "stockId"
, PCPEDI.QT as "quantity"
, PCPEDI.PVENDA as "salePrice"
, CASE WHEN PCPEDI.TIPOENTREGA = 'RI' THEN 'RETIRA IMEDIATA'
WHEN PCPEDI.TIPOENTREGA = 'RP' THEN 'RETIRA POSTERIOR'
WHEN PCPEDI.TIPOENTREGA = 'EN' THEN 'ENTREGA'
WHEN PCPEDI.TIPOENTREGA = 'EF' THEN 'ENTREGA FUTURA'
END as "deliveryType"
, ( PCPEDI.QT *
PCPEDI.PVENDA ) as "total"
, ( PCPEDI.QT * PCPRODUT.PESOBRUTO ) as "weigth"
, PCDEPTO.DESCRICAO as "department"
, PCMARCA.MARCA as "brand"
FROM PCPEDI, PCPRODUT, PCDEPTO, PCMARCA
WHERE PCPEDI.CODPROD = PCPRODUT.CODPROD
AND PCPRODUT.CODEPTO = PCDEPTO.CODEPTO
AND PCPRODUT.CODMARCA = PCMARCA.CODMARCA
AND PCPEDI.NUMPED = ${orderId}`;
const itens = await queryRunner.manager.query(sql);
return itens;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getCutItens(orderId: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCCORTEI.CODPROD as "productId"
, PCPRODUT.DESCRICAO as "description"
, PCPRODUT.EMBALAGEM as "pacth"
, PCCORTEI.CODFILIAL as "stockId"
, ( PCCORTEI.QTSEPARADA +
PCCORTEI.QTCORTADA ) as "saleQuantity"
, PCCORTEI.QTCORTADA as "cutQuantity"
, PCCORTEI.QTSEPARADA as "separedQuantity"
FROM PCCORTEI, PCPRODUT
WHERE PCCORTEI.CODPROD = PCPRODUT.CODPROD
AND PCCORTEI.NUMPED = ${orderId}`;
const itens = await queryRunner.manager.query(sql);
return itens;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getOrderDelivery(orderId: string){
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCPRACA.CODPRACA as "placeId"
,PCPRACA.PRACA as "placeName"
,NVL(ENDENT.ENDERENT, PCCLIENT.ENDERENT) as "street"
,NVL(ENDENT.NUMEROENT, PCCLIENT.NUMEROENT) as "addressNumber"
,NVL(ENDENT.BAIRROENT, PCCLIENT.BAIRROENT) as "bairro"
,NVL(ENDENT.MUNICENT, PCCLIENT.MUNICENT) as "city"
,NVL(ENDENT.ESTENT, PCCLIENT.ESTENT) as "state"
,NVL(ENDENT.COMPLEMENTOENT, PCCLIENT.COMPLEMENTOENT) as "addressComplement"
,NVL(ENDENT.CEPENT, PCCLIENT.CEPENT) as "cep"
,PCPEDC.OBS1 as "commentOrder1"
,PCPEDC.OBS2 as "commentOrder2"
,PCPEDC.OBSENTREGA1 as "commentDelivery1"
,PCPEDC.OBSENTREGA2 as "commentDelivery2"
,PCPEDC.OBSENTREGA3 as "commentDelivery3"
,PCPEDC.OBSENTREGA4 as "commentDelivery4"
,PCPEDC.NUMCAR as "shippimentId"
,PCCARREG.DTSAIDA as "shippimentDate"
,PCCARREG.DESTINO as "shippimentComment"
,PCROTAEXP.DESCRICAO as "place"
,PCEMPR.MATRICULA||'-'||
PCEMPR.NOME as "driver"
,PCVEICUL.PLACA||' - '||PCVEICUL.DESCRICAO as "car"
,CASE WHEN PCCARREG.DTFECHA < PCCARREG.DTSAIDA THEN NULL
ELSE PCCARREG.DTFECHA END as "closeDate"
,SEPARADOR.NOME as "separatorName"
,CONFERENTE.NOME as "confName"
,PCPEDC.DTLIBERA as "releaseDate"
FROM PCPEDC, PCCLIENT, PCPRACA, PCCLIENTENDENT ENDENT, PCCARREG, PCVEICUL, PCEMPR, PCROTAEXP,
PCEMPR SEPARADOR, PCEMPR CONFERENTE
WHERE NVL(ENDENT.CODPRACAENT, PCPEDC.CODPRACA) = PCPRACA.CODPRACA
AND PCPEDC.CODCLI = PCCLIENT.CODCLI
AND PCPEDC.CODENDENTCLI = ENDENT.CODENDENTCLI (+)
AND PCPEDC.CODCLI = ENDENT.CODCLI (+)
AND PCPEDC.NUMCAR = PCCARREG.NUMCAR (+)
AND PCCARREG.CODMOTORISTA = PCEMPR.MATRICULA (+)
AND PCCARREG.CODVEICULO = PCVEICUL.CODVEICULO (+)
AND PCCARREG.CODROTAPRINC = PCROTAEXP.CODROTA (+)
AND PCPEDC.CODFUNCSEP = SEPARADOR.MATRICULA (+)
AND PCPEDC.CODFUNCCONF = CONFERENTE.MATRICULA (+)
AND PCPEDC.NUMPED = ${orderId}`;
const orderDelivery = await queryRunner.manager.query(sql);
if ( orderDelivery.length > 0 ) {
return orderDelivery[0];
} else {
return null;
}
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getTransfer(orderId: number) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT L.NUMPED as "orderId"
,L.DTTRANSF as "transferDate"
,L.NUMNOTA as "invoiceId"
,L.NUMTRANSVENDA as "transactionId"
,L.NUMCARANTERIOR as "oldShipment"
,L.NUMCARATUAL as "newShipment"
,L.MOTIVOTRANSF as "transferText"
,L.codmotivo||'-'||PCTABDEV.MOTIVO as "cause"
,L.codfunctransf||'-'||PCEMPR.NOME as "userName"
,L.rotinatransf as "program"
FROM PCLOGTRANSFNFCARREG L, PCTABDEV, PCEMPR
WHERE L.CODMOTIVO = PCTABDEV.coddevol (+)
AND L.CODFUNCTRANSF = PCEMPR.MATRICULA (+)
AND L.NUMTRANSVENDA IN ( SELECT PCPEDC.NUMTRANSVENDA FROM PCPEDC WHERE PCPEDC.NUMPED = ${orderId} )`;
const transferOrder = await queryRunner.manager.query(sql);
if ( transferOrder.length > 0 ) {
return transferOrder;
} else {
return null;
}
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getStatusOrder(orderId: number) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT pcpedc.numped AS "orderId",
'Digitação pedido' AS "status",
TO_DATE (TO_CHAR(pcpedc.data, 'DD/MM/YYYY') || ' ' || pcpedc.hora || ':' || pcpedc.minuto,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pcpedc.codemitente || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId} AND pcpedc.codemitente = pcempr.matricula(+)
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Montagem de carga' AS "status",
TO_DATE (
TO_CHAR(pccarreg.datamon, 'DD/MM/YYYY')
|| ' '
|| pccarreg.horamon
|| ':'
|| pccarreg.minutomon,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pccarreg.codfuncmon || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr, pccarreg
WHERE pcpedc.numped = ${orderId}
AND pccarreg.codfuncmon = pcempr.matricula(+)
AND pcpedc.numcar = pccarreg.numcar
AND pcpedc.numcar > 0
AND pccarreg.datamon is not null
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Emissão do mapa' AS "status",
CASE WHEN PCPEDC.DTEMISSAOMAPA IS NOT NULL THEN
TO_DATE (
TO_CHAR(pcpedc.dtemissaomapa, 'DD/MM/YYYY')
|| ' '
|| NVL(pcpedc.horaemissaomapa, '00')
|| ':'
|| nvl(pcpedc.minutoemissaomapa, '01'),
'DD/MM/YYYY HH24:MI') ELSE NULL END
AS "statusDate",
pcpedc.codfuncemissaomapa || '-' || pcempr.nome AS "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncemissaomapa = pcempr.matricula(+)
AND PCPEDC.DTEMISSAOMAPA IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Inicio de Separação' AS "status",
pcpedc.dtinicialsep as "statusDate",
pcpedc.codfuncsep || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncsep = pcempr.matricula(+)
AND PCPEDC.dtinicialsep IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Fim de Separação' AS "status",
pcpedc.dtfinalsep as "statusDate",
pcpedc.codfuncsep || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId} AND pcpedc.codfuncsep = pcempr.matricula(+)
and pcpedc.dtfinalsep is not null
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Inicio conferência' AS "status",
pcpedc.dtinicialcheckout AS "statusDate",
pcpedc.codfuncconf || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncconf = pcempr.matricula(+)
AND pcpedc.dtinicialcheckout IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Fim conferência' AS "status",
pcpedc.dtfinalcheckout AS "statusDate",
pcpedc.codfuncconf || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncconf = pcempr.matricula(+)
AND pcpedc.dtfinalcheckout IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Faturamento' AS "status",
TO_DATE (
TO_CHAR(pcpedc.dtfat, 'DD/MM/YYYY') || ' ' || pcpedc.horafat || ':' || pcpedc.minutofat,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pcempr.matricula || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr, pccarreg, pcnfsaid
WHERE pcpedc.numped = ${orderId}
AND pcpedc.numcar = pccarreg.numcar
and pcpedc.numtransvenda = pcnfsaid.numtransvenda
AND nvl(pcnfsaid.codemitente, decode(pcpedc.numcar,0,-1,pccarreg.codfuncfat)) = pcempr.matricula(+)
AND pcpedc.dtfat IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Entrega' AS "status",
pcnfsaid.dtcanhoto AS "statusDate",
CASE WHEN PCNFSAID.NUMCAR > 0 THEN
pcnfsaid.codfunccanhoto || '-' || pcempr.nome
ELSE '' END "userName"
,NULL as "comments"
FROM pcpedc, pcnfsaid, pcempr, pccarreg
WHERE pcpedc.numped = ${orderId}
AND pcpedc.numtransvenda = pcnfsaid.numtransvenda
AND pcnfsaid.numcar = pccarreg.numcar (+)
AND pcnfsaid.codfunccanhoto = pcempr.matricula(+)
AND pcnfsaid.dtcanhoto IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Transf entre carregamento' AS "status",
pclogtransfnfcarreg.dttransf AS "statusDate",
pclogtransfnfcarreg.codfunctransf || '-' || pcempr.nome "userName",
'ORIG: '||pclogtransfnfcarreg.numcaranterior || ' ->
DEST.: ' ||pclogtransfnfcarreg.numcaratual as "comments"
FROM pclogtransfnfcarreg, pcpedc, pcempr
WHERE pclogtransfnfcarreg.numnota = pcpedc.numnota (+)
AND pcpedc.numped = ${orderId}
AND pclogtransfnfcarreg.codfunctransf = pcempr.matricula(+)
ORDER BY 3`;
const statusOrder = await queryRunner.manager.query(sql);
if ( statusOrder.length > 0 ) {
return statusOrder;
} else {
return null;
}
} catch(e) {
console.log(e);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async createInvoiceCheck(invoice: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
// TO_DATE('YYYY-MM-DDTHH24:MI:SS.000Z','${invoice.startDate}'),
// TO_DATE('YYYY-MM-DDTHH24:MI:SS.000Z','${invoice.endDate}'),
try {
const sqlSequence = 'SELECT ESSCONFERENCIANF.NEXTVAL as "id" FROM DUAL';
const dbSequence = await queryRunner.manager.query(sqlSequence);
const checkId = dbSequence[0].id;
const sql = `INSERT INTO ESTCONFERENCIANF ( ID, NUMTRANSVENDA, CODFILIAL, NUMNOTA, DTINICIO, DTFIM, CODFUNCCONF )
VALUES ( ${checkId}, ${invoice.transactionId}, ${invoice.storeId}, ${invoice.invoiceId},
TO_DATE(SUBSTR(REPLACE(REPLACE('${invoice.startDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS'),
TO_DATE(SUBSTR(REPLACE(REPLACE('${invoice.endDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS'),
${invoice.userId} )`;
await queryRunner.manager.query(sql);
for ( const item of invoice.itens ) {
const sqlItem = `INSERT INTO ESTCONFERENCIANFITENS ( IDCONF, NUMTRANSVENDA, CODPROD, NUMSEQ, QT, DTCONF )
VALUES ( ${checkId}, ${invoice.transactionId}, ${item.productId}, ${item.seq}, ${item.qt},
TO_DATE(SUBSTR(REPLACE(REPLACE('${item.confDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS') )`;
await queryRunner.manager.query(sqlItem);
}
await queryRunner.commitTransaction();
return { message: 'Conferência salva com sucesso!' }
} catch(erro) {
await queryRunner.rollbackTransaction();
console.log(erro);
throw new HttpException(erro.message, HttpStatus.BAD_REQUEST);
}
finally {
await queryRunner.release();
await dataSource.destroy();
}
}
}

View File

@@ -0,0 +1,31 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { ProductsService } from './products.service';
import { ExposedProduct } from 'src/core/models/exposed-product.model';
@Controller('api/v1/products')
export class ProductsController {
constructor(private readonly productsService: ProductsService) { }
@Get('products-ecommerce')
async productsEcommerce() {
return this.productsService.getProductsEcommerce();
}
@Get('product-validation/:storeId/:filtro')
async productValidation(@Param('storeId') storeId: string, @Param('filtro') filtro: string) {
return this.productsService.productsValidation(storeId, filtro);
}
@Post('exposed-product')
async exposedProduct(@Body() exposedProduct: ExposedProduct) {
return this.productsService.exposedProduct(exposedProduct);
}
}

View File

@@ -0,0 +1,19 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
import { ProductsService } from './products.service';
import { ProductsController } from './products.controller';
@Module({
imports: [],
controllers: [
ProductsController,],
providers: [
ProductsService,],
})
export class ProductsModule { }

View File

@@ -0,0 +1,122 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/providers#services
*/
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { typeOrmConfig } from 'src/core/configs/typeorm.config';
import { ExposedProduct } from 'src/core/models/exposed-product.model';
import { DataSource } from 'typeorm';
@Injectable()
export class ProductsService {
async productsValidation(storeId: string, filtro: string): Promise<any> {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCPRODUT.DESCRICAO as "descricao"
,PCPRODUT.CODPROD as "codigoProduto"
,PCPRODUT.CODAUXILIAR as "codigoAuxiliar"
,PCMARCA.MARCA as "marca"
,REPLACE(NVL(URLIMAGEM, 'http://10.1.1.191/si.png'), 'http://167.249.211.178:8001/', 'http://10.1.1.191/') as "images"
,CASE WHEN PCPRODUT.TIPOPRODUTO = 'A' THEN 'AUTOSSERVICO'
WHEN PCPRODUT.TIPOPRODUTO = 'S' THEN 'SHOWROOM'
WHEN PCPRODUT.TIPOPRODUTO = 'E' THEN 'ELETROMOVEIS'
ELSE 'OUTROS' END as "tipoProduto"
,PCTABPR.PVENDA1 as "precoVenda"
,( PCEST.QTESTGER - PCEST.QTRESERV - PCEST.QTBLOQUEADA ) as "qtdeEstoqueLoja"
,( SELECT ( ESTOQUE_CD.QTESTGER - ESTOQUE_CD.QTRESERV - ESTOQUE_CD.QTBLOQUEADA )
FROM PCEST ESTOQUE_CD
WHERE ESTOQUE_CD.CODPROD = PCPRODUT.CODPROD
AND ESTOQUE_CD.CODFILIAL = 6 ) as "qtdeEstoqueCD"
FROM PCPRODUT, PCEST, PCTABPR, PCMARCA
WHERE PCPRODUT.CODPROD = PCEST.CODPROD
AND PCPRODUT.CODPROD = PCTABPR.CODPROD
AND PCPRODUT.CODMARCA = PCMARCA.CODMARCA
AND PCTABPR.NUMREGIAO = 1
AND PCEST.CODFILIAL = '${storeId}'
AND ( PCPRODUT.CODAUXILIAR = REGEXP_REPLACE('${filtro}', '[^0-9]', '') OR
PCPRODUT.CODPROD = REGEXP_REPLACE('${filtro}', '[^0-9]', '') OR
PCPRODUT.DESCRICAO LIKE '%'||'${filtro}'||'%' )`;
const products = await queryRunner.manager.query(sql);
if (products.length == 0) {
throw new HttpException('Produto não localizado!', HttpStatus.NOT_FOUND);
}
const product = products[0];
if ( product.images == null ) {
product.images = [];
} else {
const imagesString: string = product.images;
if (imagesString.indexOf(';') > 0) {
const imagesArray = imagesString.split(';');
product.images = imagesArray;
} else {
const imagesArray: string[] = [];
imagesArray.push(product.images);
product.images = imagesArray;
}
}
return product;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async exposedProduct(product: ExposedProduct) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const sqlInsert = `INSERT INTO ESTPRODUTOEXPOSICAO ( CODFILIAL, DATA, CODAUXILIAR, CODFUNC )
VALUES ( '${product.storeId}', TRUNC(SYSDATE), ${product.ean}, ${product.userId})`;
await queryRunner.query(sqlInsert);
await queryRunner.commitTransaction();
return { message: 'Registro incluído com sucesso!'}
} catch (err) {
await queryRunner.rollbackTransaction();
throw err;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getProductsEcommerce() {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sqlInsert = `SELECT P.CODPROD as "productIdErp"
,P.VTEXSKUID as "productId"
,ROUND(P.PVENDA,2) as "price"
,ROUND(P.PRECOKIT,2) as "priceKit"
FROM ESVPRODUTOSECOMMERCE P
WHERE P.VTEXSKUID > 0
AND P.CODPROD IN (52057, 33702, 46410, 24518, 25816)`;
const products = await queryRunner.query(sqlInsert);
return products;
} catch (err) {
throw err;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
}

24
test/app.e2e-spec.ts Normal file
View File

@@ -0,0 +1,24 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});

9
test/jest-e2e.json Normal file
View File

@@ -0,0 +1,9 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}

4
tsconfig.build.json Normal file
View File

@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}

15
tsconfig.json Normal file
View File

@@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true
}
}