impl modulo orde node 22
This commit is contained in:
3
.env
3
.env
@@ -11,8 +11,9 @@ POSTGRES_USER=ti
|
|||||||
POSTGRES_PASSWORD=ti
|
POSTGRES_PASSWORD=ti
|
||||||
POSTGRES_DB=ksdb
|
POSTGRES_DB=ksdb
|
||||||
|
|
||||||
|
|
||||||
JWT_SECRET=4557C0D7-DFB0-40DA-BF83-91A75103F7A9
|
JWT_SECRET=4557C0D7-DFB0-40DA-BF83-91A75103F7A9
|
||||||
JWT_EXPIRES_IN=8h
|
JWT_EXPIRES_IN=8h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
217
package-lock.json
generated
217
package-lock.json
generated
@@ -10,6 +10,7 @@
|
|||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nestjs/axios": "^4.0.0",
|
"@nestjs/axios": "^4.0.0",
|
||||||
|
"@nestjs/bull": "^11.0.2",
|
||||||
"@nestjs/common": "^11.0.12",
|
"@nestjs/common": "^11.0.12",
|
||||||
"@nestjs/config": "^4.0.2",
|
"@nestjs/config": "^4.0.2",
|
||||||
"@nestjs/core": "^11.0.12",
|
"@nestjs/core": "^11.0.12",
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
"@types/estree": "^1.0.7",
|
"@types/estree": "^1.0.7",
|
||||||
"aws-sdk": "^2.1692.0",
|
"aws-sdk": "^2.1692.0",
|
||||||
"axios": "^1.8.4",
|
"axios": "^1.8.4",
|
||||||
|
"bullmq": "^5.45.2",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.1",
|
"class-validator": "^0.14.1",
|
||||||
"fs": "0.0.1-security",
|
"fs": "0.0.1-security",
|
||||||
@@ -1582,6 +1584,84 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
|
||||||
"integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw=="
|
"integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/@nestjs/axios": {
|
"node_modules/@nestjs/axios": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.0.tgz",
|
||||||
@@ -1593,6 +1673,34 @@
|
|||||||
"rxjs": "^7.0.0"
|
"rxjs": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nestjs/bull": {
|
||||||
|
"version": "11.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/bull/-/bull-11.0.2.tgz",
|
||||||
|
"integrity": "sha512-RjyP9JZUuLmMhmq1TMNIZqolkAd14az1jyXMMVki+C9dYvaMjWzBSwcZAtKs9Pk15Rm7qN1xn3R11aMV2Xv4gg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nestjs/bull-shared": "^11.0.2",
|
||||||
|
"tslib": "2.8.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
|
||||||
|
"@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
|
||||||
|
"bull": "^3.3 || ^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@nestjs/bull-shared": {
|
||||||
|
"version": "11.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/bull-shared/-/bull-shared-11.0.2.tgz",
|
||||||
|
"integrity": "sha512-dFlttJvBqIFD6M8JVFbkrR4Feb39OTAJPJpFVILU50NOJCM4qziRw3dSNG84Q3v+7/M6xUGMFdZRRGvBBKxoSA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "2.8.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
||||||
|
"@nestjs/core": "^10.0.0 || ^11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nestjs/cli": {
|
"node_modules/@nestjs/cli": {
|
||||||
"version": "11.0.5",
|
"version": "11.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.5.tgz",
|
||||||
@@ -3811,6 +3919,34 @@
|
|||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
|
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/bullmq": {
|
||||||
|
"version": "5.45.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.45.2.tgz",
|
||||||
|
"integrity": "sha512-wHZfcD4z4aLolxREmwNNDSbfh7USeq2e3yu5W2VGkzHMUcrH0fzZuRuCMsjD0XKS9ViK1U854oM9yWR6ftPeDA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cron-parser": "^4.9.0",
|
||||||
|
"ioredis": "^5.4.1",
|
||||||
|
"msgpackr": "^1.11.2",
|
||||||
|
"node-abort-controller": "^3.1.1",
|
||||||
|
"semver": "^7.5.4",
|
||||||
|
"tslib": "^2.0.0",
|
||||||
|
"uuid": "^9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bullmq/node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/busboy": {
|
"node_modules/busboy": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||||
@@ -4508,6 +4644,18 @@
|
|||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/cron-parser": {
|
||||||
|
"version": "4.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz",
|
||||||
|
"integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"luxon": "^3.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
@@ -4743,6 +4891,16 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/detect-libc": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/detect-newline": {
|
"node_modules/detect-newline": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
|
||||||
@@ -6314,6 +6472,7 @@
|
|||||||
"version": "5.6.0",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.6.0.tgz",
|
||||||
"integrity": "sha512-tBZlIIWbndeWBWCXWZiqtOF/yxf6yZX3tAlTJ7nfo5jhd6dctNxF7QnYlZLZ1a0o0pDoen7CgZqO+zjNaFbJAg==",
|
"integrity": "sha512-tBZlIIWbndeWBWCXWZiqtOF/yxf6yZX3tAlTJ7nfo5jhd6dctNxF7QnYlZLZ1a0o0pDoen7CgZqO+zjNaFbJAg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ioredis/commands": "^1.1.1",
|
"@ioredis/commands": "^1.1.1",
|
||||||
"cluster-key-slot": "^1.1.0",
|
"cluster-key-slot": "^1.1.0",
|
||||||
@@ -7984,6 +8143,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
|
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/luxon": {
|
||||||
|
"version": "3.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.1.tgz",
|
||||||
|
"integrity": "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.25.7",
|
"version": "0.25.7",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
||||||
@@ -8222,6 +8390,37 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/msgpackr": {
|
||||||
|
"version": "1.11.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz",
|
||||||
|
"integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optionalDependencies": {
|
||||||
|
"msgpackr-extract": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/msgpackr-extract": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"node-gyp-build-optional-packages": "5.2.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"download-msgpackr-prebuilds": "bin/download-prebuilds.js"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/multer": {
|
"node_modules/multer": {
|
||||||
"version": "1.4.5-lts.2",
|
"version": "1.4.5-lts.2",
|
||||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.2.tgz",
|
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.2.tgz",
|
||||||
@@ -8318,8 +8517,7 @@
|
|||||||
"node_modules/node-abort-controller": {
|
"node_modules/node-abort-controller": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
|
||||||
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==",
|
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/node-emoji": {
|
"node_modules/node-emoji": {
|
||||||
"version": "1.11.0",
|
"version": "1.11.0",
|
||||||
@@ -8330,6 +8528,21 @@
|
|||||||
"lodash": "^4.17.21"
|
"lodash": "^4.17.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-gyp-build-optional-packages": {
|
||||||
|
"version": "5.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
|
||||||
|
"integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"detect-libc": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-gyp-build-optional-packages": "bin.js",
|
||||||
|
"node-gyp-build-optional-packages-optional": "optional.js",
|
||||||
|
"node-gyp-build-optional-packages-test": "build-test.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-int64": {
|
"node_modules/node-int64": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nestjs/axios": "^4.0.0",
|
"@nestjs/axios": "^4.0.0",
|
||||||
|
"@nestjs/bull": "^11.0.2",
|
||||||
"@nestjs/common": "^11.0.12",
|
"@nestjs/common": "^11.0.12",
|
||||||
"@nestjs/config": "^4.0.2",
|
"@nestjs/config": "^4.0.2",
|
||||||
"@nestjs/core": "^11.0.12",
|
"@nestjs/core": "^11.0.12",
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
"@types/estree": "^1.0.7",
|
"@types/estree": "^1.0.7",
|
||||||
"aws-sdk": "^2.1692.0",
|
"aws-sdk": "^2.1692.0",
|
||||||
"axios": "^1.8.4",
|
"axios": "^1.8.4",
|
||||||
|
"bullmq": "^5.45.2",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.1",
|
"class-validator": "^0.14.1",
|
||||||
"fs": "0.0.1-security",
|
"fs": "0.0.1-security",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import { ProductsModule } from './products/products.module';
|
import { ProductsModule } from './products/products.module';
|
||||||
import { AuthModule } from './auth/auth/auth.module';
|
import { AuthModule } from './auth/auth/auth.module';
|
||||||
import { DataConsultModule } from './data-consult/data-consult.module';
|
import { DataConsultModule } from './data-consult/data-consult.module';
|
||||||
import { OrdersModule } from './orders/orders.module';
|
import { OrdersModule } from './orders/modules/orders.module';
|
||||||
import { OcorrencesController } from './crm/occurrences/ocorrences.controller';
|
import { OcorrencesController } from './crm/occurrences/ocorrences.controller';
|
||||||
import { OccurrencesModule } from './crm/occurrences/occurrences.module';
|
import { OccurrencesModule } from './crm/occurrences/occurrences.module';
|
||||||
import { ReasonTableModule } from './crm/reason-table/reason-table.module';
|
import { ReasonTableModule } from './crm/reason-table/reason-table.module';
|
||||||
@@ -51,6 +51,6 @@
|
|||||||
OrdersModule,
|
OrdersModule,
|
||||||
],
|
],
|
||||||
controllers: [OcorrencesController, LogisticController ],
|
controllers: [OcorrencesController, LogisticController ],
|
||||||
providers: [ LogisticService, ],
|
providers: [ LogisticService, ],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { CommandBus } from '@nestjs/cqrs';
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
import { CqrsModule } from '@nestjs/cqrs';
|
import { CqrsModule } from '@nestjs/cqrs';
|
||||||
import { AuthenticateUserCommand } from './authenticate-user.command';
|
import { AuthenticateUserCommand } from './commands/authenticate-user.command';
|
||||||
import { LoginResponseDto } from './dto/LoginResponseDto';
|
import { LoginResponseDto } from './dto/LoginResponseDto';
|
||||||
import { LoginDto } from './dto/login.dto';
|
import { LoginDto } from './dto/login.dto';
|
||||||
import { ResultModel } from 'src/core/models/result.model';
|
import { ResultModel } from 'src/core/models/result.model';
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { UsersModule } from '../users/users.module';
|
|||||||
import { AuthController } from './auth.controller';
|
import { AuthController } from './auth.controller';
|
||||||
import { CqrsModule } from '@nestjs/cqrs';
|
import { CqrsModule } from '@nestjs/cqrs';
|
||||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
import { AuthenticateUserHandler } from './authenticate-user.service';
|
import { AuthenticateUserHandler } from './commands/authenticate-user.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -29,7 +29,7 @@ import { AuthenticateUserHandler } from './authenticate-user.service';
|
|||||||
UsersModule,
|
UsersModule,
|
||||||
],
|
],
|
||||||
controllers: [AuthController],
|
controllers: [AuthController],
|
||||||
providers: [AuthService, JwtStrategy, AuthenticateUserHandler],
|
providers: [AuthService, JwtStrategy],
|
||||||
exports: [AuthService],
|
exports: [AuthService],
|
||||||
})
|
})
|
||||||
export class AuthModule {}
|
export class AuthModule {}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||||
import { AuthenticateUserCommand } from './authenticate-user.command';
|
import { AuthenticateUserCommand } from './authenticate-user.command';
|
||||||
import { UserRepository } from '../users/UserRepository';
|
import { UserRepository } from '../../users/UserRepository';
|
||||||
import { Result } from '../models/result';
|
import { Result } from '../../models/result';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { UserModel } from 'src/core/models/user.model';
|
import { UserModel } from 'src/core/models/user.model';
|
||||||
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm'; // <-- importe aqui
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
import { UserRepository } from './UserRepository';
|
import { UserRepository } from './UserRepository';
|
||||||
|
import { AuthenticateUserHandler } from '../auth/commands/authenticate-user.service';
|
||||||
import { AuthenticateUserHandler } from '../auth/authenticate-user.service';
|
|
||||||
import { ResetPasswordService } from './reset-password.service';
|
import { ResetPasswordService } from './reset-password.service';
|
||||||
import { ChangePasswordService } from './change-password.service';
|
import { ChangePasswordService } from './change-password.service';
|
||||||
import { EmailService } from './email.service';
|
import { EmailService } from './email.service';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { AuthenticateUserHandler } from '../auth/authenticate-user.service';
|
import { AuthenticateUserHandler } from '../auth/commands/authenticate-user.service';
|
||||||
import { ResetPasswordService } from './reset-password.service';
|
import { ResetPasswordService } from './reset-password.service';
|
||||||
import { ChangePasswordService } from './change-password.service';
|
import { ChangePasswordService } from './change-password.service';
|
||||||
import { AuthenticateUserCommand } from '../auth/authenticate-user.command';
|
import { AuthenticateUserCommand } from '../auth/commands/authenticate-user.command';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export class LogisticService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getDeliveries(placa: string) {
|
async getDeliveries(placa: string) {
|
||||||
const dataSource = new DataSource(createPostgresConfig(this.configService));
|
const dataSource = new DataSource(createOracleConfig(this.configService));
|
||||||
await dataSource.initialize();
|
await dataSource.initialize();
|
||||||
const queryRunner = dataSource.createQueryRunner();
|
const queryRunner = dataSource.createQueryRunner();
|
||||||
await queryRunner.connect();
|
await queryRunner.connect();
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ async function bootstrap() {
|
|||||||
|
|
||||||
app.useGlobalInterceptors(new ResponseInterceptor());
|
app.useGlobalInterceptors(new ResponseInterceptor());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
app.useGlobalPipes(
|
app.useGlobalPipes(
|
||||||
new ValidationPipe({
|
new ValidationPipe({
|
||||||
whitelist: true,
|
whitelist: true,
|
||||||
|
|||||||
@@ -1,14 +1,113 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable, Inject } from '@nestjs/common';
|
||||||
import { FindOrdersDto } from '../dto/find-orders.dto';
|
import { FindOrdersDto } from '../dto/find-orders.dto';
|
||||||
|
import { InvoiceDto } from '../dto/find-invoice.dto';
|
||||||
|
import { CutItemDto } from '../dto/CutItemDto';
|
||||||
import { OrdersRepository } from '../repositories/orders.repository';
|
import { OrdersRepository } from '../repositories/orders.repository';
|
||||||
|
import { OrderItemDto } from '../dto/OrderItemDto';
|
||||||
|
import { IRedisClient } from 'src/core/configs/cache/IRedisClient';
|
||||||
|
import { RedisClientToken } from 'src/core/configs/cache/redis-client.adapter.provider';
|
||||||
|
import { getOrSetCache } from 'src/shared/cache.util';
|
||||||
|
import { createHash } from 'crypto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OrdersService {
|
export class OrdersService {
|
||||||
constructor(private readonly ordersRepository: OrdersRepository) {}
|
private readonly TTL_ORDERS = 60 * 10; // 10 minutos
|
||||||
|
private readonly TTL_INVOICE = 60 * 60; // 1 hora
|
||||||
|
private readonly TTL_ITENS = 60 * 10; // 10 minutos
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly ordersRepository: OrdersRepository,
|
||||||
|
@Inject(RedisClientToken) private readonly redisClient: IRedisClient,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buscar pedidos com cache baseado nos filtros
|
||||||
|
*/
|
||||||
async findOrders(query: FindOrdersDto) {
|
async findOrders(query: FindOrdersDto) {
|
||||||
return await this.ordersRepository.findOrders(query);
|
const key = `orders:query:${this.hashObject(query)}`;
|
||||||
|
|
||||||
|
return getOrSetCache(
|
||||||
|
this.redisClient,
|
||||||
|
key,
|
||||||
|
this.TTL_ORDERS,
|
||||||
|
() => this.ordersRepository.findOrders(query),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
}
|
* Buscar nota fiscal por chave NFe com cache
|
||||||
|
*/
|
||||||
|
async findInvoice(chavenfe: string): Promise<InvoiceDto> {
|
||||||
|
const key = `orders:invoice:${chavenfe}`;
|
||||||
|
|
||||||
|
return getOrSetCache(this.redisClient, key, this.TTL_INVOICE, async () => {
|
||||||
|
const invoiceData = await this.ordersRepository.findInvoice(chavenfe);
|
||||||
|
|
||||||
|
const invoice: InvoiceDto = {
|
||||||
|
storeId: invoiceData.storeId,
|
||||||
|
invoiceDate: new Date(invoiceData.invoiceDate),
|
||||||
|
orderId: invoiceData.orderId,
|
||||||
|
invoiceId: invoiceData.invoiceId,
|
||||||
|
transactionId: invoiceData.transactionId,
|
||||||
|
customerId: invoiceData.customerId,
|
||||||
|
customer: invoiceData.customer,
|
||||||
|
sellerId: invoiceData.sellerId,
|
||||||
|
sellerName: invoiceData.sellerName,
|
||||||
|
itensQt: invoiceData.itensQt,
|
||||||
|
itens: invoiceData.itens,
|
||||||
|
};
|
||||||
|
|
||||||
|
return invoice;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buscar itens de pedido com cache
|
||||||
|
*/
|
||||||
|
async getItens(orderId: string): Promise<OrderItemDto[]> {
|
||||||
|
const key = `orders:itens:${orderId}`;
|
||||||
|
|
||||||
|
return getOrSetCache(this.redisClient, key, this.TTL_ITENS, async () => {
|
||||||
|
const itens = await this.ordersRepository.getItens(orderId);
|
||||||
|
|
||||||
|
return itens.map(item => ({
|
||||||
|
productId: Number(item.productId),
|
||||||
|
description: item.description,
|
||||||
|
pacth: item.pacth,
|
||||||
|
color: item.color,
|
||||||
|
stockId: Number(item.stockId),
|
||||||
|
quantity: Number(item.quantity),
|
||||||
|
salePrice: Number(item.salePrice),
|
||||||
|
deliveryType: item.deliveryType,
|
||||||
|
total: Number(item.total),
|
||||||
|
weight: Number(item.weight),
|
||||||
|
department: item.department,
|
||||||
|
brand: item.brand,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCutItens(orderId: string): Promise<CutItemDto[]> {
|
||||||
|
const itens = await this.ordersRepository.getCutItens(orderId);
|
||||||
|
|
||||||
|
return itens.map(item => ({
|
||||||
|
productId: Number(item.productId),
|
||||||
|
description: item.description,
|
||||||
|
pacth: item.pacth,
|
||||||
|
stockId: Number(item.stockId),
|
||||||
|
saleQuantity: Number(item.saleQuantity),
|
||||||
|
cutQuantity: Number(item.cutQuantity),
|
||||||
|
separedQuantity: Number(item.separedQuantity),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilitário para gerar hash MD5 de objetos
|
||||||
|
*/
|
||||||
|
private hashObject(obj: any): string {
|
||||||
|
const str = JSON.stringify(obj, Object.keys(obj).sort());
|
||||||
|
return createHash('md5').update(str).digest('hex');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
76
src/orders/controllers/orders.controller.ts
Normal file
76
src/orders/controllers/orders.controller.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
Param,
|
||||||
|
Query,
|
||||||
|
UsePipes,
|
||||||
|
UseGuards,
|
||||||
|
UseInterceptors,
|
||||||
|
ValidationPipe,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { ResponseInterceptor } from '../../common/response.interceptor';
|
||||||
|
import { OrdersService } from '../application/orders.service';
|
||||||
|
import { FindOrdersDto } from '../dto/find-orders.dto';
|
||||||
|
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
|
||||||
|
import { InvoiceDto } from '../dto/find-invoice.dto';
|
||||||
|
import { OrderItemDto } from "../dto/OrderItemDto";
|
||||||
|
import { CutItemDto } from '../dto/CutItemDto';
|
||||||
|
|
||||||
|
|
||||||
|
@ApiTags('Orders')
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@UseInterceptors(ResponseInterceptor)
|
||||||
|
@Controller('api/v1/orders')
|
||||||
|
export class OrdersController {
|
||||||
|
constructor(private readonly ordersService: OrdersService) {}
|
||||||
|
|
||||||
|
@Get('find')
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true }))
|
||||||
|
findOrders(@Query() query: FindOrdersDto) {
|
||||||
|
return this.ordersService.findOrders(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('invoice/:chavenfe')
|
||||||
|
@ApiOperation({ summary: 'Busca NF pela chave' })
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true }))
|
||||||
|
async getInvoice(@Param('chavenfe') chavenfe: string): Promise<InvoiceDto> {
|
||||||
|
try {
|
||||||
|
return await this.ordersService.findInvoice(chavenfe);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Erro ao buscar nota fiscal',
|
||||||
|
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Get('itens/:orderId')
|
||||||
|
@ApiOperation({ summary: 'Busca PELO numero do pedido' })
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true }))
|
||||||
|
async getItens(@Param('orderId') orderId: string): Promise<OrderItemDto[]> {
|
||||||
|
try {
|
||||||
|
return await this.ordersService.getItens(orderId);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Erro ao buscar itens do pedido',
|
||||||
|
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Get('cut-itens/:orderId')
|
||||||
|
@ApiOperation({ summary: 'Busca itens cortados do pedido' })
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true }))
|
||||||
|
async getCutItens(@Param('orderId') orderId: string): Promise<CutItemDto[]> {
|
||||||
|
try {
|
||||||
|
return await this.ordersService.getCutItens(orderId);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Erro ao buscar itens cortados',
|
||||||
|
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/orders/dto/CutItemDto.ts
Normal file
10
src/orders/dto/CutItemDto.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export class CutItemDto {
|
||||||
|
productId: number;
|
||||||
|
description: string;
|
||||||
|
pacth: string;
|
||||||
|
stockId: number;
|
||||||
|
saleQuantity: number;
|
||||||
|
cutQuantity: number;
|
||||||
|
separedQuantity: number;
|
||||||
|
}
|
||||||
|
|
||||||
14
src/orders/dto/OrderItemDto.ts
Normal file
14
src/orders/dto/OrderItemDto.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export class OrderItemDto {
|
||||||
|
productId: number;
|
||||||
|
description: string;
|
||||||
|
pacth: string;
|
||||||
|
color: string;
|
||||||
|
stockId: number;
|
||||||
|
quantity: number;
|
||||||
|
salePrice: number;
|
||||||
|
deliveryType: string;
|
||||||
|
total: number;
|
||||||
|
weight: number;
|
||||||
|
department: string;
|
||||||
|
brand: string;
|
||||||
|
}
|
||||||
29
src/orders/dto/find-invoice.dto.ts
Normal file
29
src/orders/dto/find-invoice.dto.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
export class FindInvoiceDto {
|
||||||
|
chavenfe: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class InvoiceItemDto {
|
||||||
|
productId: number;
|
||||||
|
productName: string;
|
||||||
|
package: string;
|
||||||
|
qt: number;
|
||||||
|
ean: string;
|
||||||
|
multiple: number;
|
||||||
|
productType: string;
|
||||||
|
image: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class InvoiceDto {
|
||||||
|
storeId: number;
|
||||||
|
invoiceDate: Date;
|
||||||
|
orderId: number;
|
||||||
|
invoiceId: number;
|
||||||
|
transactionId: number;
|
||||||
|
customerId: number;
|
||||||
|
customer: string;
|
||||||
|
sellerId: number;
|
||||||
|
sellerName: string;
|
||||||
|
itensQt: number;
|
||||||
|
itens: InvoiceItemDto[];
|
||||||
|
}
|
||||||
@@ -12,13 +12,13 @@ export class FindOrdersDto {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
storeId?: string;
|
codfilial?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
|
|
||||||
storeStockId?: string;
|
filialretira?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
|||||||
12
src/orders/modules/orders.module.ts
Normal file
12
src/orders/modules/orders.module.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { OrdersController } from '../controllers/orders.controller';
|
||||||
|
import { OrdersService } from '../application/orders.service';
|
||||||
|
import { OrdersRepository } from '../repositories/orders.repository';
|
||||||
|
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [],
|
||||||
|
controllers: [OrdersController],
|
||||||
|
providers: [OrdersService, OrdersRepository],
|
||||||
|
})
|
||||||
|
export class OrdersModule {}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// src/modules/orders/interfaces/controllers/orders.controller.ts
|
|
||||||
|
|
||||||
import {
|
|
||||||
Body,
|
|
||||||
Controller,
|
|
||||||
Get,
|
|
||||||
Param,
|
|
||||||
Post,
|
|
||||||
Query,
|
|
||||||
UsePipes,
|
|
||||||
UseGuards,
|
|
||||||
ValidationPipe,
|
|
||||||
} from '@nestjs/common';
|
|
||||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
|
||||||
import { ResponseInterceptor } from '../common/response.interceptor';
|
|
||||||
import { OrdersService } from './application/orders.service';
|
|
||||||
import { FindOrdersDto } from './dto/find-orders.dto';
|
|
||||||
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
|
|
||||||
|
|
||||||
@ApiTags('Orders')
|
|
||||||
@ApiBearerAuth()
|
|
||||||
@UseGuards(JwtAuthGuard)
|
|
||||||
@Controller('api/v1/orders')
|
|
||||||
export class OrdersController {
|
|
||||||
constructor(private readonly ordersService: OrdersService) {}
|
|
||||||
|
|
||||||
@Get('find')
|
|
||||||
@UsePipes(new ValidationPipe({ transform: true }))
|
|
||||||
findOrders(@Query() query: FindOrdersDto) {
|
|
||||||
return this.ordersService.findOrders(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// src/modules/orders/orders.module.ts
|
|
||||||
|
|
||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
import { OrdersService } from './application/orders.service';
|
|
||||||
import { OrdersController } from './orders.controller';
|
|
||||||
import { OrdersRepository } from './repositories/orders.repository';
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports: [
|
|
||||||
TypeOrmModule,
|
|
||||||
],
|
|
||||||
controllers: [OrdersController],
|
|
||||||
providers: [OrdersService, OrdersRepository],
|
|
||||||
})
|
|
||||||
export class OrdersModule {}
|
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
// src/modules/orders/infrastructure/repositories/orders.repository.ts
|
import { Injectable, HttpException, HttpStatus } from "@nestjs/common";
|
||||||
|
import { DataSource } from "typeorm";
|
||||||
|
import { InjectDataSource } from "@nestjs/typeorm";
|
||||||
|
import { FindOrdersDto } from "../dto/find-orders.dto";
|
||||||
|
import { OrderItemDto } from "../dto/OrderItemDto";
|
||||||
|
import { CutItemDto } from '../dto/CutItemDto';
|
||||||
|
|
||||||
|
|
||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { DataSource } from 'typeorm';
|
|
||||||
import { InjectDataSource } from '@nestjs/typeorm';
|
|
||||||
import { createOracleConfig } from '../../core/configs/typeorm.oracle.config';
|
|
||||||
import { FindOrdersDto } from '../dto/find-orders.dto';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OrdersRepository {
|
export class OrdersRepository {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectDataSource('oracle') private readonly dataSource: DataSource
|
@InjectDataSource("oracle") private readonly dataSource: DataSource
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async findOrders(query: FindOrdersDto): Promise<any[]> {
|
async findOrders(query: FindOrdersDto): Promise<any[]> {
|
||||||
await this.dataSource.initialize();
|
|
||||||
const queryRunner = this.dataSource.createQueryRunner();
|
const queryRunner = this.dataSource.createQueryRunner();
|
||||||
await queryRunner.connect();
|
await queryRunner.connect();
|
||||||
|
|
||||||
@@ -143,11 +143,13 @@ export class OrdersRepository {
|
|||||||
|
|
||||||
const conditions: string[] = [];
|
const conditions: string[] = [];
|
||||||
|
|
||||||
if (query.storeId) {
|
if (query.codfilial) {
|
||||||
conditions.push(`AND PCPEDC.CODFILIAL = :storeId`);
|
conditions.push(`AND PCPEDC.CODFILIAL = :storeId`);
|
||||||
}
|
}
|
||||||
if (query.storeStockId) {
|
if (query.filialretira) {
|
||||||
conditions.push(`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODFILIALRETIRA = :storeStockId)`);
|
conditions.push(
|
||||||
|
`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODFILIALRETIRA = :storeStockId)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (query.sellerId) {
|
if (query.sellerId) {
|
||||||
conditions.push(`AND PCPEDC.CODUSUR = :sellerId`);
|
conditions.push(`AND PCPEDC.CODUSUR = :sellerId`);
|
||||||
@@ -159,42 +161,65 @@ export class OrdersRepository {
|
|||||||
conditions.push(`AND PCPEDC.CODCOB = :billingId`);
|
conditions.push(`AND PCPEDC.CODCOB = :billingId`);
|
||||||
}
|
}
|
||||||
if (query.orderId) {
|
if (query.orderId) {
|
||||||
conditions.push(`AND (PCPEDC.NUMPED = :orderId OR PCPEDC.NUMPEDENTFUT = :orderId)`);
|
conditions.push(
|
||||||
|
`AND (PCPEDC.NUMPED = :orderId OR PCPEDC.NUMPEDENTFUT = :orderId)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (query.invoiceId) {
|
if (query.invoiceId) {
|
||||||
conditions.push(`AND PCPEDC.NUMNOTA = :invoiceId`);
|
conditions.push(`AND PCPEDC.NUMNOTA = :invoiceId`);
|
||||||
}
|
}
|
||||||
if (query.productId) {
|
if (query.productId) {
|
||||||
conditions.push(`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODPROD = :productId)`);
|
conditions.push(
|
||||||
|
`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODPROD = :productId)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (query.createDateIni) {
|
if (query.createDateIni) {
|
||||||
conditions.push(`AND PCPEDC.DATA >= TO_DATE(:createDateIni, 'YYYY-MM-DD')`);
|
conditions.push(
|
||||||
|
`AND PCPEDC.DATA >= TO_DATE(:createDateIni, 'YYYY-MM-DD')`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (query.createDateEnd) {
|
if (query.createDateEnd) {
|
||||||
conditions.push(`AND PCPEDC.DATA <= TO_DATE(:createDateEnd, 'YYYY-MM-DD')`);
|
conditions.push(
|
||||||
|
`AND PCPEDC.DATA <= TO_DATE(:createDateEnd, 'YYYY-MM-DD')`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (query.invoiceDateIni) {
|
if (query.invoiceDateIni) {
|
||||||
conditions.push(`AND PCPEDC.DTFAT >= TO_DATE(:invoiceDateIni, 'YYYY-MM-DD')`);
|
conditions.push(
|
||||||
|
`AND PCPEDC.DTFAT >= TO_DATE(:invoiceDateIni, 'YYYY-MM-DD')`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (query.invoiceDateEnd) {
|
if (query.invoiceDateEnd) {
|
||||||
conditions.push(`AND PCPEDC.DTFAT <= TO_DATE(:invoiceDateEnd, 'YYYY-MM-DD')`);
|
conditions.push(
|
||||||
|
`AND PCPEDC.DTFAT <= TO_DATE(:invoiceDateEnd, 'YYYY-MM-DD')`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (query.shippimentId) {
|
if (query.shippimentId) {
|
||||||
conditions.push(`AND PCPEDC.NUMCAR = :shippimentId`);
|
conditions.push(`AND PCPEDC.NUMCAR = :shippimentId`);
|
||||||
}
|
}
|
||||||
if (query.deliveryType) {
|
if (query.deliveryType) {
|
||||||
const types = query.deliveryType.split(',').map(t => `'${t}'`).join(',');
|
const types = query.deliveryType
|
||||||
conditions.push(`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.TIPOENTREGA IN (${types}))`);
|
.split(",")
|
||||||
|
.map((t) => `'${t}'`)
|
||||||
|
.join(",");
|
||||||
|
conditions.push(
|
||||||
|
`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.TIPOENTREGA IN (${types}))`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (query.status) {
|
if (query.status) {
|
||||||
const statusList = query.status.split(',').map(s => `'${s}'`).join(',');
|
const statusList = query.status
|
||||||
|
.split(",")
|
||||||
|
.map((s) => `'${s}'`)
|
||||||
|
.join(",");
|
||||||
conditions.push(`AND PCPEDC.POSICAO IN (${statusList})`);
|
conditions.push(`AND PCPEDC.POSICAO IN (${statusList})`);
|
||||||
}
|
}
|
||||||
if (query.type) {
|
if (query.type) {
|
||||||
const types = query.type.split(',').map(t => `'${t}'`).join(',');
|
const types = query.type
|
||||||
|
.split(",")
|
||||||
|
.map((t) => `'${t}'`)
|
||||||
|
.join(",");
|
||||||
conditions.push(`AND PCPEDC.CONDVENDA IN (${types})`);
|
conditions.push(`AND PCPEDC.CONDVENDA IN (${types})`);
|
||||||
}
|
}
|
||||||
if (query.onlyPendentingTransfer === 'S') {
|
if (query.onlyPendentingTransfer === "S") {
|
||||||
conditions.push(`
|
conditions.push(`
|
||||||
AND NOT EXISTS(SELECT 1 FROM PCNFENT, PCFILIAL
|
AND NOT EXISTS(SELECT 1 FROM PCNFENT, PCFILIAL
|
||||||
WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL
|
WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL
|
||||||
@@ -202,8 +227,8 @@ export class OrdersRepository {
|
|||||||
AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA)`);
|
AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
sql += '\n' + conditions.join('\n');
|
sql += "\n" + conditions.join("\n");
|
||||||
sql += '\nAND ROWNUM < 5000';
|
sql += "\nAND ROWNUM < 5000";
|
||||||
|
|
||||||
const orders = await queryRunner.manager.query(sql);
|
const orders = await queryRunner.manager.query(sql);
|
||||||
return orders;
|
return orders;
|
||||||
@@ -212,4 +237,132 @@ export class OrdersRepository {
|
|||||||
await this.dataSource.destroy();
|
await this.dataSource.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
async findInvoice(chavenfe: string): Promise<any> {
|
||||||
|
const queryRunner = this.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
|
||||||
|
JOIN pcclient ON pcnfsaid.codcli = pcclient.codcli
|
||||||
|
JOIN pcusuari ON pcnfsaid.codusur = pcusuari.codusur
|
||||||
|
WHERE pcnfsaid.chavenfe = '${chavenfe}'
|
||||||
|
`;
|
||||||
|
|
||||||
|
const invoice = await queryRunner.manager.query(sql);
|
||||||
|
if (!invoice || invoice.length === 0) {
|
||||||
|
throw new HttpException('Nota fiscal não foi localizada no 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
|
||||||
|
JOIN pcprodut ON pcmov.codprod = pcprodut.codprod
|
||||||
|
WHERE pcmov.numtransvenda = ${invoice[0].transactionId}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const itens = await queryRunner.manager.query(sqlItem);
|
||||||
|
invoice[0].itens = itens;
|
||||||
|
|
||||||
|
return invoice[0];
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getItens(orderId: string): Promise<OrderItemDto[]> {
|
||||||
|
const queryRunner = this.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async getCutItens(orderId: string): Promise<CutItemDto[]> {
|
||||||
|
const queryRunner = this.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
|
||||||
|
JOIN PCPRODUT ON PCCORTEI.CODPROD = PCPRODUT.CODPROD
|
||||||
|
WHERE PCCORTEI.NUMPED = ${orderId}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const itens = await queryRunner.manager.query(sql);
|
||||||
|
return itens;
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user