Compare commits
No commits in common. "develop" and "version-0.11.29" have entirely different histories.
develop
...
version-0.
27 changed files with 542 additions and 2026 deletions
36
Dockerfile
36
Dockerfile
|
|
@ -1,22 +1,34 @@
|
||||||
FROM node:20-slim
|
FROM node:23-slim AS base
|
||||||
|
|
||||||
RUN apt-get update -y \
|
ENV PNPM_HOME="/pnpm"
|
||||||
&& apt-get install -y openssl \
|
ENV PATH="$PNPM_HOME:$PATH"
|
||||||
&& npm install -g pnpm \
|
|
||||||
&& apt-get clean \
|
RUN corepack enable
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
RUN apt-get update && apt-get install -y openssl fontconfig
|
||||||
|
RUN fc-cache -f -v
|
||||||
|
RUN pnpm i -g prisma prisma-kysely
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package.json pnpm-lock.yaml ./
|
|
||||||
RUN pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
FROM base AS deps
|
||||||
|
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
|
||||||
|
RUN pnpm prisma generate
|
||||||
|
|
||||||
|
FROM base AS build
|
||||||
|
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
|
||||||
RUN pnpm prisma generate
|
RUN pnpm prisma generate
|
||||||
RUN pnpm run build
|
RUN pnpm run build
|
||||||
|
|
||||||
COPY entrypoint.sh /entrypoint.sh
|
FROM base AS prod
|
||||||
RUN chmod +x /entrypoint.sh
|
|
||||||
|
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
ENV NODE_ENV="production"
|
||||||
|
|
||||||
|
COPY --from=deps /app/node_modules /app/node_modules
|
||||||
|
COPY --from=build /app/dist /app/dist
|
||||||
|
COPY --from=base /app/static /app/static
|
||||||
|
|
||||||
|
RUN chmod u+x ./entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
"@vitest/ui": "^3.1.4",
|
"@vitest/ui": "^3.1.4",
|
||||||
"nodemon": "^3.1.9",
|
"nodemon": "^3.1.9",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.4.2",
|
||||||
"prisma": "6.16.2",
|
"prisma": "^6.3.0",
|
||||||
"prisma-kysely": "^1.8.0",
|
"prisma-kysely": "^1.8.0",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.2",
|
||||||
|
|
@ -40,14 +40,12 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@elastic/elasticsearch": "^8.17.0",
|
"@elastic/elasticsearch": "^8.17.0",
|
||||||
"@fast-csv/parse": "^5.0.2",
|
"@fast-csv/parse": "^5.0.2",
|
||||||
"@prisma/client": "6.16.2",
|
"@prisma/client": "^6.3.0",
|
||||||
"@scalar/express-api-reference": "^0.4.182",
|
"@scalar/express-api-reference": "^0.4.182",
|
||||||
"@tsoa/runtime": "^6.6.0",
|
"@tsoa/runtime": "^6.6.0",
|
||||||
"@types/html-to-text": "^9.0.4",
|
|
||||||
"canvas": "^3.1.0",
|
"canvas": "^3.1.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cron": "^3.3.1",
|
"cron": "^3.3.1",
|
||||||
"csv-parse": "^6.1.0",
|
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"dayjs-plugin-utc": "^0.1.2",
|
"dayjs-plugin-utc": "^0.1.2",
|
||||||
"docx-templates": "^4.13.0",
|
"docx-templates": "^4.13.0",
|
||||||
|
|
@ -55,7 +53,6 @@
|
||||||
"exceljs": "^4.4.0",
|
"exceljs": "^4.4.0",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
"fast-jwt": "^5.0.5",
|
"fast-jwt": "^5.0.5",
|
||||||
"html-to-text": "^9.0.5",
|
|
||||||
"jsbarcode": "^3.11.6",
|
"jsbarcode": "^3.11.6",
|
||||||
"json-2-csv": "^5.5.8",
|
"json-2-csv": "^5.5.8",
|
||||||
"kysely": "^0.27.5",
|
"kysely": "^0.27.5",
|
||||||
|
|
@ -63,7 +60,6 @@
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.5-lts.2",
|
"multer": "^1.4.5-lts.2",
|
||||||
"nodemailer": "^6.10.0",
|
"nodemailer": "^6.10.0",
|
||||||
"pnpm": "^10.18.3",
|
|
||||||
"prisma-extension-kysely": "^3.0.0",
|
"prisma-extension-kysely": "^3.0.0",
|
||||||
"promise.any": "^2.0.6",
|
"promise.any": "^2.0.6",
|
||||||
"thai-baht-text": "^2.0.5",
|
"thai-baht-text": "^2.0.5",
|
||||||
|
|
|
||||||
425
pnpm-lock.yaml
generated
425
pnpm-lock.yaml
generated
|
|
@ -15,17 +15,14 @@ importers:
|
||||||
specifier: ^5.0.2
|
specifier: ^5.0.2
|
||||||
version: 5.0.2
|
version: 5.0.2
|
||||||
'@prisma/client':
|
'@prisma/client':
|
||||||
specifier: 6.16.2
|
specifier: ^6.3.0
|
||||||
version: 6.16.2(prisma@6.16.2(typescript@5.7.2))(typescript@5.7.2)
|
version: 6.3.0(prisma@6.3.0(typescript@5.7.2))(typescript@5.7.2)
|
||||||
'@scalar/express-api-reference':
|
'@scalar/express-api-reference':
|
||||||
specifier: ^0.4.182
|
specifier: ^0.4.182
|
||||||
version: 0.4.182
|
version: 0.4.182
|
||||||
'@tsoa/runtime':
|
'@tsoa/runtime':
|
||||||
specifier: ^6.6.0
|
specifier: ^6.6.0
|
||||||
version: 6.6.0
|
version: 6.6.0
|
||||||
'@types/html-to-text':
|
|
||||||
specifier: ^9.0.4
|
|
||||||
version: 9.0.4
|
|
||||||
canvas:
|
canvas:
|
||||||
specifier: ^3.1.0
|
specifier: ^3.1.0
|
||||||
version: 3.1.0
|
version: 3.1.0
|
||||||
|
|
@ -35,9 +32,6 @@ importers:
|
||||||
cron:
|
cron:
|
||||||
specifier: ^3.3.1
|
specifier: ^3.3.1
|
||||||
version: 3.3.1
|
version: 3.3.1
|
||||||
csv-parse:
|
|
||||||
specifier: ^6.1.0
|
|
||||||
version: 6.1.0
|
|
||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.13
|
specifier: ^1.11.13
|
||||||
version: 1.11.13
|
version: 1.11.13
|
||||||
|
|
@ -59,9 +53,6 @@ importers:
|
||||||
fast-jwt:
|
fast-jwt:
|
||||||
specifier: ^5.0.5
|
specifier: ^5.0.5
|
||||||
version: 5.0.5
|
version: 5.0.5
|
||||||
html-to-text:
|
|
||||||
specifier: ^9.0.5
|
|
||||||
version: 9.0.5
|
|
||||||
jsbarcode:
|
jsbarcode:
|
||||||
specifier: ^3.11.6
|
specifier: ^3.11.6
|
||||||
version: 3.11.6
|
version: 3.11.6
|
||||||
|
|
@ -83,12 +74,9 @@ importers:
|
||||||
nodemailer:
|
nodemailer:
|
||||||
specifier: ^6.10.0
|
specifier: ^6.10.0
|
||||||
version: 6.10.0
|
version: 6.10.0
|
||||||
pnpm:
|
|
||||||
specifier: ^10.18.3
|
|
||||||
version: 10.28.0
|
|
||||||
prisma-extension-kysely:
|
prisma-extension-kysely:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.0.0(@prisma/client@6.16.2(prisma@6.16.2(typescript@5.7.2))(typescript@5.7.2))
|
version: 3.0.0(@prisma/client@6.3.0(prisma@6.3.0(typescript@5.7.2))(typescript@5.7.2))
|
||||||
promise.any:
|
promise.any:
|
||||||
specifier: ^2.0.6
|
specifier: ^2.0.6
|
||||||
version: 2.0.6
|
version: 2.0.6
|
||||||
|
|
@ -139,8 +127,8 @@ importers:
|
||||||
specifier: ^3.4.2
|
specifier: ^3.4.2
|
||||||
version: 3.4.2
|
version: 3.4.2
|
||||||
prisma:
|
prisma:
|
||||||
specifier: 6.16.2
|
specifier: ^6.3.0
|
||||||
version: 6.16.2(typescript@5.7.2)
|
version: 6.3.0(typescript@5.7.2)
|
||||||
prisma-kysely:
|
prisma-kysely:
|
||||||
specifier: ^1.8.0
|
specifier: ^1.8.0
|
||||||
version: 1.8.0(encoding@0.1.13)
|
version: 1.8.0(encoding@0.1.13)
|
||||||
|
|
@ -152,7 +140,7 @@ importers:
|
||||||
version: 5.7.2
|
version: 5.7.2
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^3.1.4
|
specifier: ^3.1.4
|
||||||
version: 3.1.4(@types/node@20.17.10)(@vitest/ui@3.1.4)(jiti@2.5.1)(yaml@2.6.1)
|
version: 3.1.4(@types/node@20.17.10)(@vitest/ui@3.1.4)(yaml@2.6.1)
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
|
@ -528,8 +516,8 @@ packages:
|
||||||
'@polka/url@1.0.0-next.29':
|
'@polka/url@1.0.0-next.29':
|
||||||
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||||
|
|
||||||
'@prisma/client@6.16.2':
|
'@prisma/client@6.3.0':
|
||||||
resolution: {integrity: sha512-E00PxBcalMfYO/TWnXobBVUai6eW/g5OsifWQsQDzJYm7yaY+IRLo7ZLsaefi0QkTpxfuhFcQ/w180i6kX3iJw==}
|
resolution: {integrity: sha512-BY3Fi28PUSk447Bpv22LhZp4HgNPo7NsEN+EteM1CLDnLjig5863jpW+3c3HHLFmml+nB/eJv1CjSriFZ8z7Cg==}
|
||||||
engines: {node: '>=18.18'}
|
engines: {node: '>=18.18'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
prisma: '*'
|
prisma: '*'
|
||||||
|
|
@ -540,29 +528,26 @@ packages:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@prisma/config@6.16.2':
|
|
||||||
resolution: {integrity: sha512-mKXSUrcqXj0LXWPmJsK2s3p9PN+aoAbyMx7m5E1v1FufofR1ZpPoIArjjzOIm+bJRLLvYftoNYLx1tbHgF9/yg==}
|
|
||||||
|
|
||||||
'@prisma/debug@5.3.1':
|
'@prisma/debug@5.3.1':
|
||||||
resolution: {integrity: sha512-eYrxqslEKf+wpMFIIHgbcNYuZBXUdiJLA85Or3TwOhgPIN1ZoXT9CwJph3ynW8H1Xg0LkdYLwVmuULCwiMoU5A==}
|
resolution: {integrity: sha512-eYrxqslEKf+wpMFIIHgbcNYuZBXUdiJLA85Or3TwOhgPIN1ZoXT9CwJph3ynW8H1Xg0LkdYLwVmuULCwiMoU5A==}
|
||||||
|
|
||||||
'@prisma/debug@6.16.2':
|
'@prisma/debug@6.3.0':
|
||||||
resolution: {integrity: sha512-bo4/gA/HVV6u8YK2uY6glhNsJ7r+k/i5iQ9ny/3q5bt9ijCj7WMPUwfTKPvtEgLP+/r26Z686ly11hhcLiQ8zA==}
|
resolution: {integrity: sha512-m1lQv//0Rc5RG8TBpNUuLCxC35Ghi5XfpPmL83Gh04/GICHD2J5H2ndMlaljrUNaQDF9dOxIuFAYP1rE9wkXkg==}
|
||||||
|
|
||||||
'@prisma/engines-version@6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43':
|
'@prisma/engines-version@6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0':
|
||||||
resolution: {integrity: sha512-ThvlDaKIVrnrv97ujNFDYiQbeMQpLa0O86HFA2mNoip4mtFqM7U5GSz2ie1i2xByZtvPztJlNRgPsXGeM/kqAA==}
|
resolution: {integrity: sha512-R/ZcMuaWZT2UBmgX3Ko6PAV3f8//ZzsjRIG1eKqp3f2rqEqVtCv+mtzuH2rBPUC9ujJ5kCb9wwpxeyCkLcHVyA==}
|
||||||
|
|
||||||
'@prisma/engines@5.3.1':
|
'@prisma/engines@5.3.1':
|
||||||
resolution: {integrity: sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==}
|
resolution: {integrity: sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==}
|
||||||
|
|
||||||
'@prisma/engines@6.16.2':
|
'@prisma/engines@6.3.0':
|
||||||
resolution: {integrity: sha512-7yf3AjfPUgsg/l7JSu1iEhsmZZ/YE00yURPjTikqm2z4btM0bCl2coFtTGfeSOWbQMmq45Jab+53yGUIAT1sjA==}
|
resolution: {integrity: sha512-RXqYhlZb9sx/xkUfYIZuEPn7sT0WgTxNOuEYQ7AGw3IMpP9QGVEDVsluc/GcNkM8NTJszeqk8AplJzI9lm7Jxw==}
|
||||||
|
|
||||||
'@prisma/fetch-engine@5.3.1':
|
'@prisma/fetch-engine@5.3.1':
|
||||||
resolution: {integrity: sha512-w1yk1YiK8N82Pobdq58b85l6e8akyrkxuzwV9DoiUTRf3gpsuhJJesHc4Yi0WzUC9/3znizl1UfCsI6dhkj3Vw==}
|
resolution: {integrity: sha512-w1yk1YiK8N82Pobdq58b85l6e8akyrkxuzwV9DoiUTRf3gpsuhJJesHc4Yi0WzUC9/3znizl1UfCsI6dhkj3Vw==}
|
||||||
|
|
||||||
'@prisma/fetch-engine@6.16.2':
|
'@prisma/fetch-engine@6.3.0':
|
||||||
resolution: {integrity: sha512-wPnZ8DMRqpgzye758ZvfAMiNJRuYpz+rhgEBZi60ZqDIgOU2694oJxiuu3GKFeYeR/hXxso4/2oBC243t/whxQ==}
|
resolution: {integrity: sha512-GBy0iT4f1mH31ePzfcpVSUa7JLRTeq4914FG2vR3LqDwRweSm4ja1o5flGDz+eVIa/BNYfkBvRRxv4D6ve6Eew==}
|
||||||
|
|
||||||
'@prisma/generator-helper@5.3.1':
|
'@prisma/generator-helper@5.3.1':
|
||||||
resolution: {integrity: sha512-zrYS0iHLgPlOJjYnd5KvVMMvSS+ktOL39EwooS5EnyvfzwfzxlKCeOUgxTfiKYs0WUWqzEvyNAYtramYgSknsQ==}
|
resolution: {integrity: sha512-zrYS0iHLgPlOJjYnd5KvVMMvSS+ktOL39EwooS5EnyvfzwfzxlKCeOUgxTfiKYs0WUWqzEvyNAYtramYgSknsQ==}
|
||||||
|
|
@ -570,8 +555,8 @@ packages:
|
||||||
'@prisma/get-platform@5.3.1':
|
'@prisma/get-platform@5.3.1':
|
||||||
resolution: {integrity: sha512-3IiZY2BUjKnAuZ0569zppZE6/rZbVAM09//c2nvPbbkGG9MqrirA8fbhhF7tfVmhyVfdmVCHnf/ujWPHJ8B46Q==}
|
resolution: {integrity: sha512-3IiZY2BUjKnAuZ0569zppZE6/rZbVAM09//c2nvPbbkGG9MqrirA8fbhhF7tfVmhyVfdmVCHnf/ujWPHJ8B46Q==}
|
||||||
|
|
||||||
'@prisma/get-platform@6.16.2':
|
'@prisma/get-platform@6.3.0':
|
||||||
resolution: {integrity: sha512-U/P36Uke5wS7r1+omtAgJpEB94tlT4SdlgaeTc6HVTTT93pXj7zZ+B/cZnmnvjcNPfWddgoDx8RLjmQwqGDYyA==}
|
resolution: {integrity: sha512-V8zZ1d0xfyi6FjpNP4AcYuwSpGcdmu35OXWnTPm8IW594PYALzKXHwIa9+o0f+Lo9AecFWrwrwaoYe56UNfTtQ==}
|
||||||
|
|
||||||
'@prisma/internals@5.3.1':
|
'@prisma/internals@5.3.1':
|
||||||
resolution: {integrity: sha512-zkW73hPHHNrMD21PeYgCTBfMu71vzJf+WtfydtJbS0JVJKyLfOel0iWSQg7wjNeQfccKp+NdHJ/5rTJ4NEUzgA==}
|
resolution: {integrity: sha512-zkW73hPHHNrMD21PeYgCTBfMu71vzJf+WtfydtJbS0JVJKyLfOel0iWSQg7wjNeQfccKp+NdHJ/5rTJ4NEUzgA==}
|
||||||
|
|
@ -691,12 +676,6 @@ packages:
|
||||||
resolution: {integrity: sha512-4mQYkQJO0HHaoFd8Z+vSdQAvYcCJ2bRLN9ewE+GneB8kvoLG/oM3ynroqzGQdoytH8BmhnJwD3aEUagfbK2x5g==}
|
resolution: {integrity: sha512-4mQYkQJO0HHaoFd8Z+vSdQAvYcCJ2bRLN9ewE+GneB8kvoLG/oM3ynroqzGQdoytH8BmhnJwD3aEUagfbK2x5g==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@selderee/plugin-htmlparser2@0.11.0':
|
|
||||||
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
|
|
||||||
|
|
||||||
'@standard-schema/spec@1.0.0':
|
|
||||||
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
|
|
||||||
|
|
||||||
'@swc/helpers@0.5.15':
|
'@swc/helpers@0.5.15':
|
||||||
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
|
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
|
||||||
|
|
||||||
|
|
@ -763,9 +742,6 @@ packages:
|
||||||
'@types/express@4.17.21':
|
'@types/express@4.17.21':
|
||||||
resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
|
resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
|
||||||
|
|
||||||
'@types/html-to-text@9.0.4':
|
|
||||||
resolution: {integrity: sha512-pUY3cKH/Nm2yYrEmDlPR1mR7yszjGx4DrwPjQ702C4/D5CwHuZTgZdIdwPkRbcuhs7BAh2L5rg3CL5cbRiGTCQ==}
|
|
||||||
|
|
||||||
'@types/http-assert@1.5.6':
|
'@types/http-assert@1.5.6':
|
||||||
resolution: {integrity: sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw==}
|
resolution: {integrity: sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw==}
|
||||||
|
|
||||||
|
|
@ -1096,14 +1072,6 @@ packages:
|
||||||
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
|
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
c12@3.1.0:
|
|
||||||
resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==}
|
|
||||||
peerDependencies:
|
|
||||||
magicast: ^0.3.5
|
|
||||||
peerDependenciesMeta:
|
|
||||||
magicast:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
cac@6.7.14:
|
cac@6.7.14:
|
||||||
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
|
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
@ -1153,10 +1121,6 @@ packages:
|
||||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||||
engines: {node: '>= 8.10.0'}
|
engines: {node: '>= 8.10.0'}
|
||||||
|
|
||||||
chokidar@4.0.3:
|
|
||||||
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
|
|
||||||
engines: {node: '>= 14.16.0'}
|
|
||||||
|
|
||||||
chownr@1.1.4:
|
chownr@1.1.4:
|
||||||
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||||
|
|
||||||
|
|
@ -1164,9 +1128,6 @@ packages:
|
||||||
resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==}
|
resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
citty@0.1.6:
|
|
||||||
resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
|
|
||||||
|
|
||||||
cjs-module-lexer@1.4.1:
|
cjs-module-lexer@1.4.1:
|
||||||
resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==}
|
resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==}
|
||||||
|
|
||||||
|
|
@ -1226,13 +1187,6 @@ packages:
|
||||||
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
|
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
|
||||||
engines: {'0': node >= 0.8}
|
engines: {'0': node >= 0.8}
|
||||||
|
|
||||||
confbox@0.2.2:
|
|
||||||
resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==}
|
|
||||||
|
|
||||||
consola@3.4.2:
|
|
||||||
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
|
|
||||||
engines: {node: ^14.18.0 || >=16.10.0}
|
|
||||||
|
|
||||||
console-log-level@1.4.1:
|
console-log-level@1.4.1:
|
||||||
resolution: {integrity: sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==}
|
resolution: {integrity: sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==}
|
||||||
|
|
||||||
|
|
@ -1289,9 +1243,6 @@ packages:
|
||||||
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
|
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
csv-parse@6.1.0:
|
|
||||||
resolution: {integrity: sha512-CEE+jwpgLn+MmtCpVcPtiCZpVtB6Z2OKPTr34pycYYoL7sxdOkXDdQ4lRiw6ioC0q6BLqhc6cKweCVvral8yhw==}
|
|
||||||
|
|
||||||
data-view-buffer@1.0.1:
|
data-view-buffer@1.0.1:
|
||||||
resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
|
resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
@ -1356,14 +1307,6 @@ packages:
|
||||||
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
|
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
|
||||||
engines: {node: '>=4.0.0'}
|
engines: {node: '>=4.0.0'}
|
||||||
|
|
||||||
deepmerge-ts@7.1.5:
|
|
||||||
resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==}
|
|
||||||
engines: {node: '>=16.0.0'}
|
|
||||||
|
|
||||||
deepmerge@4.3.1:
|
|
||||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
|
|
||||||
define-data-property@1.1.4:
|
define-data-property@1.1.4:
|
||||||
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
@ -1372,9 +1315,6 @@ packages:
|
||||||
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
defu@6.1.4:
|
|
||||||
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
|
|
||||||
|
|
||||||
del@6.1.1:
|
del@6.1.1:
|
||||||
resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==}
|
resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
@ -1383,9 +1323,6 @@ packages:
|
||||||
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
|
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
destr@2.0.5:
|
|
||||||
resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
|
|
||||||
|
|
||||||
destroy@1.2.0:
|
destroy@1.2.0:
|
||||||
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
|
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
|
||||||
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
|
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
|
||||||
|
|
@ -1410,19 +1347,6 @@ packages:
|
||||||
resolution: {integrity: sha512-tTmR3WhROYctuyVReQ+PfCU3zprmC45/VuSVzn8EjovzpRkXYUdXiDatB9M8pasj0V+wuuOyY8bcSHvlQ2GNag==}
|
resolution: {integrity: sha512-tTmR3WhROYctuyVReQ+PfCU3zprmC45/VuSVzn8EjovzpRkXYUdXiDatB9M8pasj0V+wuuOyY8bcSHvlQ2GNag==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
dom-serializer@2.0.0:
|
|
||||||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
|
||||||
|
|
||||||
domelementtype@2.3.0:
|
|
||||||
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
|
||||||
|
|
||||||
domhandler@5.0.3:
|
|
||||||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
|
||||||
engines: {node: '>= 4'}
|
|
||||||
|
|
||||||
domutils@3.2.2:
|
|
||||||
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
|
|
||||||
|
|
||||||
dotenv@16.0.3:
|
dotenv@16.0.3:
|
||||||
resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
|
resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
@ -1431,10 +1355,6 @@ packages:
|
||||||
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
|
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
dotenv@16.6.1:
|
|
||||||
resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
dunder-proto@1.0.0:
|
dunder-proto@1.0.0:
|
||||||
resolution: {integrity: sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==}
|
resolution: {integrity: sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
@ -1451,9 +1371,6 @@ packages:
|
||||||
ee-first@1.1.1:
|
ee-first@1.1.1:
|
||||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||||
|
|
||||||
effect@3.16.12:
|
|
||||||
resolution: {integrity: sha512-N39iBk0K71F9nb442TLbTkjl24FLUzuvx2i1I2RsEAQsdAdUTuUoW0vlfUXgkMTUOnYqKnWcFfqw4hK4Pw27hg==}
|
|
||||||
|
|
||||||
elastic-apm-node@3.52.2:
|
elastic-apm-node@3.52.2:
|
||||||
resolution: {integrity: sha512-NVFthDcoBOpTwtppF7b+BIeIu4Xon3RBNpddIaJv+DtjL6Q61x4j7ClYdiXjv3XKgyp7yUlOnLjU6PY/EYXwLQ==}
|
resolution: {integrity: sha512-NVFthDcoBOpTwtppF7b+BIeIu4Xon3RBNpddIaJv+DtjL6Q61x4j7ClYdiXjv3XKgyp7yUlOnLjU6PY/EYXwLQ==}
|
||||||
engines: {node: '>=8.6.0'}
|
engines: {node: '>=8.6.0'}
|
||||||
|
|
@ -1464,10 +1381,6 @@ packages:
|
||||||
emoji-regex@9.2.2:
|
emoji-regex@9.2.2:
|
||||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||||
|
|
||||||
empathic@2.0.0:
|
|
||||||
resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==}
|
|
||||||
engines: {node: '>=14'}
|
|
||||||
|
|
||||||
enabled@2.0.0:
|
enabled@2.0.0:
|
||||||
resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==}
|
resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==}
|
||||||
|
|
||||||
|
|
@ -1485,10 +1398,6 @@ packages:
|
||||||
end-of-stream@1.4.4:
|
end-of-stream@1.4.4:
|
||||||
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
|
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
|
||||||
|
|
||||||
entities@4.5.0:
|
|
||||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
|
||||||
engines: {node: '>=0.12'}
|
|
||||||
|
|
||||||
env-paths@2.2.1:
|
env-paths@2.2.1:
|
||||||
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
|
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
@ -1586,13 +1495,6 @@ packages:
|
||||||
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
|
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
|
||||||
engines: {node: '>= 0.10.0'}
|
engines: {node: '>= 0.10.0'}
|
||||||
|
|
||||||
exsolve@1.0.7:
|
|
||||||
resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==}
|
|
||||||
|
|
||||||
fast-check@3.23.2:
|
|
||||||
resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
|
|
||||||
engines: {node: '>=8.0.0'}
|
|
||||||
|
|
||||||
fast-csv@4.3.6:
|
fast-csv@4.3.6:
|
||||||
resolution: {integrity: sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==}
|
resolution: {integrity: sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
|
|
@ -1750,10 +1652,6 @@ packages:
|
||||||
resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
|
resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
giget@2.0.0:
|
|
||||||
resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
github-from-package@0.0.0:
|
github-from-package@0.0.0:
|
||||||
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
|
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
|
||||||
|
|
||||||
|
|
@ -1842,13 +1740,6 @@ packages:
|
||||||
resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==}
|
resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
html-to-text@9.0.5:
|
|
||||||
resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==}
|
|
||||||
engines: {node: '>=14'}
|
|
||||||
|
|
||||||
htmlparser2@8.0.2:
|
|
||||||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
|
||||||
|
|
||||||
http-errors@2.0.0:
|
http-errors@2.0.0:
|
||||||
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
|
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
@ -2107,10 +1998,6 @@ packages:
|
||||||
jackspeak@3.4.3:
|
jackspeak@3.4.3:
|
||||||
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
||||||
|
|
||||||
jiti@2.5.1:
|
|
||||||
resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
js-tokens@4.0.0:
|
js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
|
|
@ -2153,9 +2040,6 @@ packages:
|
||||||
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
|
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
|
||||||
engines: {node: '>= 0.6.3'}
|
engines: {node: '>= 0.6.3'}
|
||||||
|
|
||||||
leac@0.6.0:
|
|
||||||
resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==}
|
|
||||||
|
|
||||||
lie@3.3.0:
|
lie@3.3.0:
|
||||||
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
|
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
|
||||||
|
|
||||||
|
|
@ -2425,9 +2309,6 @@ packages:
|
||||||
node-addon-api@7.1.1:
|
node-addon-api@7.1.1:
|
||||||
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
||||||
|
|
||||||
node-fetch-native@1.6.7:
|
|
||||||
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
|
|
||||||
|
|
||||||
node-fetch@2.6.12:
|
node-fetch@2.6.12:
|
||||||
resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==}
|
resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==}
|
||||||
engines: {node: 4.x || >=6.0.0}
|
engines: {node: 4.x || >=6.0.0}
|
||||||
|
|
@ -2479,11 +2360,6 @@ packages:
|
||||||
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
|
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
nypm@0.6.1:
|
|
||||||
resolution: {integrity: sha512-hlacBiRiv1k9hZFiphPUkfSQ/ZfQzZDzC+8z0wL3lvDAOUu/2NnChkKuMoMjNur/9OpKuz2QsIeiPVN0xM5Q0w==}
|
|
||||||
engines: {node: ^14.16.0 || >=16.10.0}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
object-assign@4.1.1:
|
object-assign@4.1.1:
|
||||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
@ -2513,9 +2389,6 @@ packages:
|
||||||
obliterator@2.0.4:
|
obliterator@2.0.4:
|
||||||
resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==}
|
resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==}
|
||||||
|
|
||||||
ohash@2.0.11:
|
|
||||||
resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
|
|
||||||
|
|
||||||
on-finished@2.3.0:
|
on-finished@2.3.0:
|
||||||
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
|
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
@ -2594,9 +2467,6 @@ packages:
|
||||||
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
parseley@0.12.1:
|
|
||||||
resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==}
|
|
||||||
|
|
||||||
parseurl@1.3.3:
|
parseurl@1.3.3:
|
||||||
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
@ -2634,12 +2504,6 @@ packages:
|
||||||
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
|
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
|
||||||
engines: {node: '>= 14.16'}
|
engines: {node: '>= 14.16'}
|
||||||
|
|
||||||
peberminta@0.9.0:
|
|
||||||
resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==}
|
|
||||||
|
|
||||||
perfect-debounce@1.0.0:
|
|
||||||
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
|
||||||
|
|
||||||
picocolors@1.1.1:
|
picocolors@1.1.1:
|
||||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||||
|
|
||||||
|
|
@ -2662,14 +2526,6 @@ packages:
|
||||||
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
|
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
pkg-types@2.3.0:
|
|
||||||
resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
|
|
||||||
|
|
||||||
pnpm@10.28.0:
|
|
||||||
resolution: {integrity: sha512-Bd9x0UIfITmeBT/eVnzqNNRG+gLHZXFEG/wceVbpjjYwiJgtlARl/TRIDU2QoGaLwSNi+KqIAApk6D0LDke+SA==}
|
|
||||||
engines: {node: '>=18.12'}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
possible-typed-array-names@1.0.0:
|
possible-typed-array-names@1.0.0:
|
||||||
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
|
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
@ -2697,8 +2553,8 @@ packages:
|
||||||
resolution: {integrity: sha512-VpNpolZ8RXRgfU+j4R+fPZmX8EE95w3vJ2tt7+FwuiQc0leNTfLK5QLf3KbbPDes2rfjh3g20AjDxefQIo5GIA==}
|
resolution: {integrity: sha512-VpNpolZ8RXRgfU+j4R+fPZmX8EE95w3vJ2tt7+FwuiQc0leNTfLK5QLf3KbbPDes2rfjh3g20AjDxefQIo5GIA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
prisma@6.16.2:
|
prisma@6.3.0:
|
||||||
resolution: {integrity: sha512-aRvldGE5UUJTtVmFiH3WfNFNiqFlAtePUxcI0UEGlnXCX7DqhiMT5TRYwncHFeA/Reca5W6ToXXyCMTeFPdSXA==}
|
resolution: {integrity: sha512-y+Zh3Qg+xGCWyyrNUUNaFW/OltaV/yXYuTa0WRgYkz5LGyifmAsgpv94I47+qGRocZrMGcbF2A/78/oO2zgifA==}
|
||||||
engines: {node: '>=18.18'}
|
engines: {node: '>=18.18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -2745,9 +2601,6 @@ packages:
|
||||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
pure-rand@6.1.0:
|
|
||||||
resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==}
|
|
||||||
|
|
||||||
qs@6.13.0:
|
qs@6.13.0:
|
||||||
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
|
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
|
||||||
engines: {node: '>=0.6'}
|
engines: {node: '>=0.6'}
|
||||||
|
|
@ -2770,9 +2623,6 @@ packages:
|
||||||
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
|
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
rc9@2.1.2:
|
|
||||||
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
|
|
||||||
|
|
||||||
rc@1.2.8:
|
rc@1.2.8:
|
||||||
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
|
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
@ -2799,10 +2649,6 @@ packages:
|
||||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||||
engines: {node: '>=8.10.0'}
|
engines: {node: '>=8.10.0'}
|
||||||
|
|
||||||
readdirp@4.1.2:
|
|
||||||
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
|
|
||||||
engines: {node: '>= 14.18.0'}
|
|
||||||
|
|
||||||
reflect-metadata@0.2.2:
|
reflect-metadata@0.2.2:
|
||||||
resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
|
resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
|
||||||
|
|
||||||
|
|
@ -2900,9 +2746,6 @@ packages:
|
||||||
secure-json-parse@2.7.0:
|
secure-json-parse@2.7.0:
|
||||||
resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
|
resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
|
||||||
|
|
||||||
selderee@0.11.0:
|
|
||||||
resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==}
|
|
||||||
|
|
||||||
semver@5.7.2:
|
semver@5.7.2:
|
||||||
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
|
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
@ -3177,9 +3020,6 @@ packages:
|
||||||
tinyexec@0.3.2:
|
tinyexec@0.3.2:
|
||||||
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
||||||
|
|
||||||
tinyexec@1.0.1:
|
|
||||||
resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
|
|
||||||
|
|
||||||
tinyglobby@0.2.13:
|
tinyglobby@0.2.13:
|
||||||
resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
|
resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
@ -3993,20 +3833,11 @@ snapshots:
|
||||||
|
|
||||||
'@polka/url@1.0.0-next.29': {}
|
'@polka/url@1.0.0-next.29': {}
|
||||||
|
|
||||||
'@prisma/client@6.16.2(prisma@6.16.2(typescript@5.7.2))(typescript@5.7.2)':
|
'@prisma/client@6.3.0(prisma@6.3.0(typescript@5.7.2))(typescript@5.7.2)':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
prisma: 6.16.2(typescript@5.7.2)
|
prisma: 6.3.0(typescript@5.7.2)
|
||||||
typescript: 5.7.2
|
typescript: 5.7.2
|
||||||
|
|
||||||
'@prisma/config@6.16.2':
|
|
||||||
dependencies:
|
|
||||||
c12: 3.1.0
|
|
||||||
deepmerge-ts: 7.1.5
|
|
||||||
effect: 3.16.12
|
|
||||||
empathic: 2.0.0
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- magicast
|
|
||||||
|
|
||||||
'@prisma/debug@5.3.1':
|
'@prisma/debug@5.3.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/debug': 4.1.8
|
'@types/debug': 4.1.8
|
||||||
|
|
@ -4015,18 +3846,18 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@prisma/debug@6.16.2': {}
|
'@prisma/debug@6.3.0': {}
|
||||||
|
|
||||||
'@prisma/engines-version@6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43': {}
|
'@prisma/engines-version@6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0': {}
|
||||||
|
|
||||||
'@prisma/engines@5.3.1': {}
|
'@prisma/engines@5.3.1': {}
|
||||||
|
|
||||||
'@prisma/engines@6.16.2':
|
'@prisma/engines@6.3.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@prisma/debug': 6.16.2
|
'@prisma/debug': 6.3.0
|
||||||
'@prisma/engines-version': 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43
|
'@prisma/engines-version': 6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0
|
||||||
'@prisma/fetch-engine': 6.16.2
|
'@prisma/fetch-engine': 6.3.0
|
||||||
'@prisma/get-platform': 6.16.2
|
'@prisma/get-platform': 6.3.0
|
||||||
|
|
||||||
'@prisma/fetch-engine@5.3.1(encoding@0.1.13)':
|
'@prisma/fetch-engine@5.3.1(encoding@0.1.13)':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4051,11 +3882,11 @@ snapshots:
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@prisma/fetch-engine@6.16.2':
|
'@prisma/fetch-engine@6.3.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@prisma/debug': 6.16.2
|
'@prisma/debug': 6.3.0
|
||||||
'@prisma/engines-version': 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43
|
'@prisma/engines-version': 6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0
|
||||||
'@prisma/get-platform': 6.16.2
|
'@prisma/get-platform': 6.3.0
|
||||||
|
|
||||||
'@prisma/generator-helper@5.3.1':
|
'@prisma/generator-helper@5.3.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4081,9 +3912,9 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@prisma/get-platform@6.16.2':
|
'@prisma/get-platform@6.3.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@prisma/debug': 6.16.2
|
'@prisma/debug': 6.3.0
|
||||||
|
|
||||||
'@prisma/internals@5.3.1(encoding@0.1.13)':
|
'@prisma/internals@5.3.1(encoding@0.1.13)':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4206,13 +4037,6 @@ snapshots:
|
||||||
'@scalar/openapi-types': 0.1.7
|
'@scalar/openapi-types': 0.1.7
|
||||||
'@unhead/schema': 1.11.14
|
'@unhead/schema': 1.11.14
|
||||||
|
|
||||||
'@selderee/plugin-htmlparser2@0.11.0':
|
|
||||||
dependencies:
|
|
||||||
domhandler: 5.0.3
|
|
||||||
selderee: 0.11.0
|
|
||||||
|
|
||||||
'@standard-schema/spec@1.0.0': {}
|
|
||||||
|
|
||||||
'@swc/helpers@0.5.15':
|
'@swc/helpers@0.5.15':
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
@ -4312,8 +4136,6 @@ snapshots:
|
||||||
'@types/qs': 6.9.17
|
'@types/qs': 6.9.17
|
||||||
'@types/serve-static': 1.15.7
|
'@types/serve-static': 1.15.7
|
||||||
|
|
||||||
'@types/html-to-text@9.0.4': {}
|
|
||||||
|
|
||||||
'@types/http-assert@1.5.6': {}
|
'@types/http-assert@1.5.6': {}
|
||||||
|
|
||||||
'@types/http-errors@2.0.4': {}
|
'@types/http-errors@2.0.4': {}
|
||||||
|
|
@ -4392,13 +4214,13 @@ snapshots:
|
||||||
chai: 5.2.0
|
chai: 5.2.0
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
'@vitest/mocker@3.1.4(vite@6.3.5(@types/node@20.17.10)(jiti@2.5.1)(yaml@2.6.1))':
|
'@vitest/mocker@3.1.4(vite@6.3.5(@types/node@20.17.10)(yaml@2.6.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/spy': 3.1.4
|
'@vitest/spy': 3.1.4
|
||||||
estree-walker: 3.0.3
|
estree-walker: 3.0.3
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 6.3.5(@types/node@20.17.10)(jiti@2.5.1)(yaml@2.6.1)
|
vite: 6.3.5(@types/node@20.17.10)(yaml@2.6.1)
|
||||||
|
|
||||||
'@vitest/pretty-format@3.1.4':
|
'@vitest/pretty-format@3.1.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4428,7 +4250,7 @@ snapshots:
|
||||||
sirv: 3.0.1
|
sirv: 3.0.1
|
||||||
tinyglobby: 0.2.13
|
tinyglobby: 0.2.13
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vitest: 3.1.4(@types/node@20.17.10)(@vitest/ui@3.1.4)(jiti@2.5.1)(yaml@2.6.1)
|
vitest: 3.1.4(@types/node@20.17.10)(@vitest/ui@3.1.4)(yaml@2.6.1)
|
||||||
|
|
||||||
'@vitest/utils@3.1.4':
|
'@vitest/utils@3.1.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4702,21 +4524,6 @@ snapshots:
|
||||||
|
|
||||||
bytes@3.1.2: {}
|
bytes@3.1.2: {}
|
||||||
|
|
||||||
c12@3.1.0:
|
|
||||||
dependencies:
|
|
||||||
chokidar: 4.0.3
|
|
||||||
confbox: 0.2.2
|
|
||||||
defu: 6.1.4
|
|
||||||
dotenv: 16.6.1
|
|
||||||
exsolve: 1.0.7
|
|
||||||
giget: 2.0.0
|
|
||||||
jiti: 2.5.1
|
|
||||||
ohash: 2.0.11
|
|
||||||
pathe: 2.0.3
|
|
||||||
perfect-debounce: 1.0.0
|
|
||||||
pkg-types: 2.3.0
|
|
||||||
rc9: 2.1.2
|
|
||||||
|
|
||||||
cac@6.7.14: {}
|
cac@6.7.14: {}
|
||||||
|
|
||||||
call-bind-apply-helpers@1.0.1:
|
call-bind-apply-helpers@1.0.1:
|
||||||
|
|
@ -4796,18 +4603,10 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
chokidar@4.0.3:
|
|
||||||
dependencies:
|
|
||||||
readdirp: 4.1.2
|
|
||||||
|
|
||||||
chownr@1.1.4: {}
|
chownr@1.1.4: {}
|
||||||
|
|
||||||
ci-info@3.8.0: {}
|
ci-info@3.8.0: {}
|
||||||
|
|
||||||
citty@0.1.6:
|
|
||||||
dependencies:
|
|
||||||
consola: 3.4.2
|
|
||||||
|
|
||||||
cjs-module-lexer@1.4.1:
|
cjs-module-lexer@1.4.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -4883,10 +4682,6 @@ snapshots:
|
||||||
readable-stream: 2.3.8
|
readable-stream: 2.3.8
|
||||||
typedarray: 0.0.6
|
typedarray: 0.0.6
|
||||||
|
|
||||||
confbox@0.2.2: {}
|
|
||||||
|
|
||||||
consola@3.4.2: {}
|
|
||||||
|
|
||||||
console-log-level@1.4.1:
|
console-log-level@1.4.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -4938,8 +4733,6 @@ snapshots:
|
||||||
|
|
||||||
crypto-random-string@2.0.0: {}
|
crypto-random-string@2.0.0: {}
|
||||||
|
|
||||||
csv-parse@6.1.0: {}
|
|
||||||
|
|
||||||
data-view-buffer@1.0.1:
|
data-view-buffer@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind: 1.0.8
|
call-bind: 1.0.8
|
||||||
|
|
@ -4988,10 +4781,6 @@ snapshots:
|
||||||
|
|
||||||
deep-extend@0.6.0: {}
|
deep-extend@0.6.0: {}
|
||||||
|
|
||||||
deepmerge-ts@7.1.5: {}
|
|
||||||
|
|
||||||
deepmerge@4.3.1: {}
|
|
||||||
|
|
||||||
define-data-property@1.1.4:
|
define-data-property@1.1.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
es-define-property: 1.0.1
|
es-define-property: 1.0.1
|
||||||
|
|
@ -5004,8 +4793,6 @@ snapshots:
|
||||||
has-property-descriptors: 1.0.2
|
has-property-descriptors: 1.0.2
|
||||||
object-keys: 1.1.1
|
object-keys: 1.1.1
|
||||||
|
|
||||||
defu@6.1.4: {}
|
|
||||||
|
|
||||||
del@6.1.1:
|
del@6.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
globby: 11.1.0
|
globby: 11.1.0
|
||||||
|
|
@ -5019,8 +4806,6 @@ snapshots:
|
||||||
|
|
||||||
depd@2.0.0: {}
|
depd@2.0.0: {}
|
||||||
|
|
||||||
destr@2.0.5: {}
|
|
||||||
|
|
||||||
destroy@1.2.0: {}
|
destroy@1.2.0: {}
|
||||||
|
|
||||||
detect-libc@2.0.4: {}
|
detect-libc@2.0.4: {}
|
||||||
|
|
@ -5038,30 +4823,10 @@ snapshots:
|
||||||
jszip: 3.10.1
|
jszip: 3.10.1
|
||||||
sax: 1.3.0
|
sax: 1.3.0
|
||||||
|
|
||||||
dom-serializer@2.0.0:
|
|
||||||
dependencies:
|
|
||||||
domelementtype: 2.3.0
|
|
||||||
domhandler: 5.0.3
|
|
||||||
entities: 4.5.0
|
|
||||||
|
|
||||||
domelementtype@2.3.0: {}
|
|
||||||
|
|
||||||
domhandler@5.0.3:
|
|
||||||
dependencies:
|
|
||||||
domelementtype: 2.3.0
|
|
||||||
|
|
||||||
domutils@3.2.2:
|
|
||||||
dependencies:
|
|
||||||
dom-serializer: 2.0.0
|
|
||||||
domelementtype: 2.3.0
|
|
||||||
domhandler: 5.0.3
|
|
||||||
|
|
||||||
dotenv@16.0.3: {}
|
dotenv@16.0.3: {}
|
||||||
|
|
||||||
dotenv@16.4.7: {}
|
dotenv@16.4.7: {}
|
||||||
|
|
||||||
dotenv@16.6.1: {}
|
|
||||||
|
|
||||||
dunder-proto@1.0.0:
|
dunder-proto@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind-apply-helpers: 1.0.1
|
call-bind-apply-helpers: 1.0.1
|
||||||
|
|
@ -5080,11 +4845,6 @@ snapshots:
|
||||||
|
|
||||||
ee-first@1.1.1: {}
|
ee-first@1.1.1: {}
|
||||||
|
|
||||||
effect@3.16.12:
|
|
||||||
dependencies:
|
|
||||||
'@standard-schema/spec': 1.0.0
|
|
||||||
fast-check: 3.23.2
|
|
||||||
|
|
||||||
elastic-apm-node@3.52.2:
|
elastic-apm-node@3.52.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@elastic/ecs-pino-format': 1.5.0
|
'@elastic/ecs-pino-format': 1.5.0
|
||||||
|
|
@ -5133,8 +4893,6 @@ snapshots:
|
||||||
|
|
||||||
emoji-regex@9.2.2: {}
|
emoji-regex@9.2.2: {}
|
||||||
|
|
||||||
empathic@2.0.0: {}
|
|
||||||
|
|
||||||
enabled@2.0.0: {}
|
enabled@2.0.0: {}
|
||||||
|
|
||||||
encodeurl@1.0.2: {}
|
encodeurl@1.0.2: {}
|
||||||
|
|
@ -5150,8 +4908,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
|
|
||||||
entities@4.5.0: {}
|
|
||||||
|
|
||||||
env-paths@2.2.1: {}
|
env-paths@2.2.1: {}
|
||||||
|
|
||||||
error-callsites@2.0.4:
|
error-callsites@2.0.4:
|
||||||
|
|
@ -5368,12 +5124,6 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
exsolve@1.0.7: {}
|
|
||||||
|
|
||||||
fast-check@3.23.2:
|
|
||||||
dependencies:
|
|
||||||
pure-rand: 6.1.0
|
|
||||||
|
|
||||||
fast-csv@4.3.6:
|
fast-csv@4.3.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@fast-csv/format': 4.3.5
|
'@fast-csv/format': 4.3.5
|
||||||
|
|
@ -5551,15 +5301,6 @@ snapshots:
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
get-intrinsic: 1.2.6
|
get-intrinsic: 1.2.6
|
||||||
|
|
||||||
giget@2.0.0:
|
|
||||||
dependencies:
|
|
||||||
citty: 0.1.6
|
|
||||||
consola: 3.4.2
|
|
||||||
defu: 6.1.4
|
|
||||||
node-fetch-native: 1.6.7
|
|
||||||
nypm: 0.6.1
|
|
||||||
pathe: 2.0.3
|
|
||||||
|
|
||||||
github-from-package@0.0.0: {}
|
github-from-package@0.0.0: {}
|
||||||
|
|
||||||
glob-parent@5.1.2:
|
glob-parent@5.1.2:
|
||||||
|
|
@ -5658,21 +5399,6 @@ snapshots:
|
||||||
|
|
||||||
hpagent@1.2.0: {}
|
hpagent@1.2.0: {}
|
||||||
|
|
||||||
html-to-text@9.0.5:
|
|
||||||
dependencies:
|
|
||||||
'@selderee/plugin-htmlparser2': 0.11.0
|
|
||||||
deepmerge: 4.3.1
|
|
||||||
dom-serializer: 2.0.0
|
|
||||||
htmlparser2: 8.0.2
|
|
||||||
selderee: 0.11.0
|
|
||||||
|
|
||||||
htmlparser2@8.0.2:
|
|
||||||
dependencies:
|
|
||||||
domelementtype: 2.3.0
|
|
||||||
domhandler: 5.0.3
|
|
||||||
domutils: 3.2.2
|
|
||||||
entities: 4.5.0
|
|
||||||
|
|
||||||
http-errors@2.0.0:
|
http-errors@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
depd: 2.0.0
|
depd: 2.0.0
|
||||||
|
|
@ -5925,8 +5651,6 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@pkgjs/parseargs': 0.11.0
|
'@pkgjs/parseargs': 0.11.0
|
||||||
|
|
||||||
jiti@2.5.1: {}
|
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
jsbarcode@3.11.6: {}
|
jsbarcode@3.11.6: {}
|
||||||
|
|
@ -5965,8 +5689,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
readable-stream: 2.3.8
|
readable-stream: 2.3.8
|
||||||
|
|
||||||
leac@0.6.0: {}
|
|
||||||
|
|
||||||
lie@3.3.0:
|
lie@3.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
immediate: 3.0.6
|
immediate: 3.0.6
|
||||||
|
|
@ -6212,8 +5934,6 @@ snapshots:
|
||||||
|
|
||||||
node-addon-api@7.1.1: {}
|
node-addon-api@7.1.1: {}
|
||||||
|
|
||||||
node-fetch-native@1.6.7: {}
|
|
||||||
|
|
||||||
node-fetch@2.6.12(encoding@0.1.13):
|
node-fetch@2.6.12(encoding@0.1.13):
|
||||||
dependencies:
|
dependencies:
|
||||||
whatwg-url: 5.0.0
|
whatwg-url: 5.0.0
|
||||||
|
|
@ -6267,14 +5987,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key: 3.1.1
|
path-key: 3.1.1
|
||||||
|
|
||||||
nypm@0.6.1:
|
|
||||||
dependencies:
|
|
||||||
citty: 0.1.6
|
|
||||||
consola: 3.4.2
|
|
||||||
pathe: 2.0.3
|
|
||||||
pkg-types: 2.3.0
|
|
||||||
tinyexec: 1.0.1
|
|
||||||
|
|
||||||
object-assign@4.1.1: {}
|
object-assign@4.1.1: {}
|
||||||
|
|
||||||
object-filter-sequence@1.0.0:
|
object-filter-sequence@1.0.0:
|
||||||
|
|
@ -6305,8 +6017,6 @@ snapshots:
|
||||||
|
|
||||||
obliterator@2.0.4: {}
|
obliterator@2.0.4: {}
|
||||||
|
|
||||||
ohash@2.0.11: {}
|
|
||||||
|
|
||||||
on-finished@2.3.0:
|
on-finished@2.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
ee-first: 1.1.1
|
ee-first: 1.1.1
|
||||||
|
|
@ -6386,11 +6096,6 @@ snapshots:
|
||||||
json-parse-even-better-errors: 2.3.1
|
json-parse-even-better-errors: 2.3.1
|
||||||
lines-and-columns: 1.2.4
|
lines-and-columns: 1.2.4
|
||||||
|
|
||||||
parseley@0.12.1:
|
|
||||||
dependencies:
|
|
||||||
leac: 0.6.0
|
|
||||||
peberminta: 0.9.0
|
|
||||||
|
|
||||||
parseurl@1.3.3: {}
|
parseurl@1.3.3: {}
|
||||||
|
|
||||||
path-exists@4.0.0: {}
|
path-exists@4.0.0: {}
|
||||||
|
|
@ -6414,10 +6119,6 @@ snapshots:
|
||||||
|
|
||||||
pathval@2.0.0: {}
|
pathval@2.0.0: {}
|
||||||
|
|
||||||
peberminta@0.9.0: {}
|
|
||||||
|
|
||||||
perfect-debounce@1.0.0: {}
|
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
|
|
||||||
picomatch@2.3.1: {}
|
picomatch@2.3.1: {}
|
||||||
|
|
@ -6442,14 +6143,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
find-up: 4.1.0
|
find-up: 4.1.0
|
||||||
|
|
||||||
pkg-types@2.3.0:
|
|
||||||
dependencies:
|
|
||||||
confbox: 0.2.2
|
|
||||||
exsolve: 1.0.7
|
|
||||||
pathe: 2.0.3
|
|
||||||
|
|
||||||
pnpm@10.28.0: {}
|
|
||||||
|
|
||||||
possible-typed-array-names@1.0.0: {}
|
possible-typed-array-names@1.0.0: {}
|
||||||
|
|
||||||
postcss@8.5.3:
|
postcss@8.5.3:
|
||||||
|
|
@ -6475,9 +6168,9 @@ snapshots:
|
||||||
|
|
||||||
prettier@3.4.2: {}
|
prettier@3.4.2: {}
|
||||||
|
|
||||||
prisma-extension-kysely@3.0.0(@prisma/client@6.16.2(prisma@6.16.2(typescript@5.7.2))(typescript@5.7.2)):
|
prisma-extension-kysely@3.0.0(@prisma/client@6.3.0(prisma@6.3.0(typescript@5.7.2))(typescript@5.7.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@prisma/client': 6.16.2(prisma@6.16.2(typescript@5.7.2))(typescript@5.7.2)
|
'@prisma/client': 6.3.0(prisma@6.3.0(typescript@5.7.2))(typescript@5.7.2)
|
||||||
|
|
||||||
prisma-kysely@1.8.0(encoding@0.1.13):
|
prisma-kysely@1.8.0(encoding@0.1.13):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -6490,14 +6183,12 @@ snapshots:
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
prisma@6.16.2(typescript@5.7.2):
|
prisma@6.3.0(typescript@5.7.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@prisma/config': 6.16.2
|
'@prisma/engines': 6.3.0
|
||||||
'@prisma/engines': 6.16.2
|
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
fsevents: 2.3.3
|
||||||
typescript: 5.7.2
|
typescript: 5.7.2
|
||||||
transitivePeerDependencies:
|
|
||||||
- magicast
|
|
||||||
|
|
||||||
process-nextick-args@2.0.1: {}
|
process-nextick-args@2.0.1: {}
|
||||||
|
|
||||||
|
|
@ -6543,8 +6234,6 @@ snapshots:
|
||||||
punycode@2.3.1:
|
punycode@2.3.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
pure-rand@6.1.0: {}
|
|
||||||
|
|
||||||
qs@6.13.0:
|
qs@6.13.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
side-channel: 1.1.0
|
side-channel: 1.1.0
|
||||||
|
|
@ -6570,11 +6259,6 @@ snapshots:
|
||||||
iconv-lite: 0.4.24
|
iconv-lite: 0.4.24
|
||||||
unpipe: 1.0.0
|
unpipe: 1.0.0
|
||||||
|
|
||||||
rc9@2.1.2:
|
|
||||||
dependencies:
|
|
||||||
defu: 6.1.4
|
|
||||||
destr: 2.0.5
|
|
||||||
|
|
||||||
rc@1.2.8:
|
rc@1.2.8:
|
||||||
dependencies:
|
dependencies:
|
||||||
deep-extend: 0.6.0
|
deep-extend: 0.6.0
|
||||||
|
|
@ -6619,8 +6303,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
readdirp@4.1.2: {}
|
|
||||||
|
|
||||||
reflect-metadata@0.2.2: {}
|
reflect-metadata@0.2.2: {}
|
||||||
|
|
||||||
reflect.getprototypeof@1.0.8:
|
reflect.getprototypeof@1.0.8:
|
||||||
|
|
@ -6746,10 +6428,6 @@ snapshots:
|
||||||
|
|
||||||
secure-json-parse@2.7.0: {}
|
secure-json-parse@2.7.0: {}
|
||||||
|
|
||||||
selderee@0.11.0:
|
|
||||||
dependencies:
|
|
||||||
parseley: 0.12.1
|
|
||||||
|
|
||||||
semver@5.7.2: {}
|
semver@5.7.2: {}
|
||||||
|
|
||||||
semver@6.3.1: {}
|
semver@6.3.1: {}
|
||||||
|
|
@ -7066,8 +6744,6 @@ snapshots:
|
||||||
|
|
||||||
tinyexec@0.3.2: {}
|
tinyexec@0.3.2: {}
|
||||||
|
|
||||||
tinyexec@1.0.1: {}
|
|
||||||
|
|
||||||
tinyglobby@0.2.13:
|
tinyglobby@0.2.13:
|
||||||
dependencies:
|
dependencies:
|
||||||
fdir: 6.4.4(picomatch@4.0.2)
|
fdir: 6.4.4(picomatch@4.0.2)
|
||||||
|
|
@ -7273,13 +6949,13 @@ snapshots:
|
||||||
|
|
||||||
vary@1.1.2: {}
|
vary@1.1.2: {}
|
||||||
|
|
||||||
vite-node@3.1.4(@types/node@20.17.10)(jiti@2.5.1)(yaml@2.6.1):
|
vite-node@3.1.4(@types/node@20.17.10)(yaml@2.6.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
cac: 6.7.14
|
cac: 6.7.14
|
||||||
debug: 4.4.0(supports-color@5.5.0)
|
debug: 4.4.0(supports-color@5.5.0)
|
||||||
es-module-lexer: 1.7.0
|
es-module-lexer: 1.7.0
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
vite: 6.3.5(@types/node@20.17.10)(jiti@2.5.1)(yaml@2.6.1)
|
vite: 6.3.5(@types/node@20.17.10)(yaml@2.6.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- jiti
|
- jiti
|
||||||
|
|
@ -7294,7 +6970,7 @@ snapshots:
|
||||||
- tsx
|
- tsx
|
||||||
- yaml
|
- yaml
|
||||||
|
|
||||||
vite@6.3.5(@types/node@20.17.10)(jiti@2.5.1)(yaml@2.6.1):
|
vite@6.3.5(@types/node@20.17.10)(yaml@2.6.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.25.4
|
esbuild: 0.25.4
|
||||||
fdir: 6.4.4(picomatch@4.0.2)
|
fdir: 6.4.4(picomatch@4.0.2)
|
||||||
|
|
@ -7305,13 +6981,12 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 20.17.10
|
'@types/node': 20.17.10
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
jiti: 2.5.1
|
|
||||||
yaml: 2.6.1
|
yaml: 2.6.1
|
||||||
|
|
||||||
vitest@3.1.4(@types/node@20.17.10)(@vitest/ui@3.1.4)(jiti@2.5.1)(yaml@2.6.1):
|
vitest@3.1.4(@types/node@20.17.10)(@vitest/ui@3.1.4)(yaml@2.6.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/expect': 3.1.4
|
'@vitest/expect': 3.1.4
|
||||||
'@vitest/mocker': 3.1.4(vite@6.3.5(@types/node@20.17.10)(jiti@2.5.1)(yaml@2.6.1))
|
'@vitest/mocker': 3.1.4(vite@6.3.5(@types/node@20.17.10)(yaml@2.6.1))
|
||||||
'@vitest/pretty-format': 3.1.4
|
'@vitest/pretty-format': 3.1.4
|
||||||
'@vitest/runner': 3.1.4
|
'@vitest/runner': 3.1.4
|
||||||
'@vitest/snapshot': 3.1.4
|
'@vitest/snapshot': 3.1.4
|
||||||
|
|
@ -7328,8 +7003,8 @@ snapshots:
|
||||||
tinyglobby: 0.2.13
|
tinyglobby: 0.2.13
|
||||||
tinypool: 1.0.2
|
tinypool: 1.0.2
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vite: 6.3.5(@types/node@20.17.10)(jiti@2.5.1)(yaml@2.6.1)
|
vite: 6.3.5(@types/node@20.17.10)(yaml@2.6.1)
|
||||||
vite-node: 3.1.4(@types/node@20.17.10)(jiti@2.5.1)(yaml@2.6.1)
|
vite-node: 3.1.4(@types/node@20.17.10)(yaml@2.6.1)
|
||||||
why-is-node-running: 2.3.0
|
why-is-node-running: 2.3.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 20.17.10
|
'@types/node': 20.17.10
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "User" ADD COLUMN "addressForeign" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
ADD COLUMN "districtText" TEXT,
|
|
||||||
ADD COLUMN "provinceText" TEXT,
|
|
||||||
ADD COLUMN "subDistrictText" TEXT,
|
|
||||||
ADD COLUMN "zipCodeText" TEXT;
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "User" ADD COLUMN "districtTextEN" TEXT,
|
|
||||||
ADD COLUMN "provinceTextEN" TEXT,
|
|
||||||
ADD COLUMN "subDistrictTextEN" TEXT;
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "RequestWorkStepStatus" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "Payment" ADD COLUMN "account" TEXT,
|
|
||||||
ADD COLUMN "channel" TEXT,
|
|
||||||
ADD COLUMN "reference" TEXT;
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "public"."Product" ADD COLUMN "flowAccountProductIdAgentPrice" TEXT,
|
|
||||||
ADD COLUMN "flowAccountProductIdSellPrice" TEXT;
|
|
||||||
|
|
@ -398,25 +398,15 @@ model User {
|
||||||
street String?
|
street String?
|
||||||
streetEN String?
|
streetEN String?
|
||||||
|
|
||||||
addressForeign Boolean @default(false)
|
|
||||||
|
|
||||||
provinceText String?
|
|
||||||
provinceTextEN String?
|
|
||||||
province Province? @relation(fields: [provinceId], references: [id], onDelete: SetNull)
|
province Province? @relation(fields: [provinceId], references: [id], onDelete: SetNull)
|
||||||
provinceId String?
|
provinceId String?
|
||||||
|
|
||||||
districtText String?
|
|
||||||
districtTextEN String?
|
|
||||||
district District? @relation(fields: [districtId], references: [id], onDelete: SetNull)
|
district District? @relation(fields: [districtId], references: [id], onDelete: SetNull)
|
||||||
districtId String?
|
districtId String?
|
||||||
|
|
||||||
subDistrictText String?
|
|
||||||
subDistrictTextEN String?
|
|
||||||
subDistrict SubDistrict? @relation(fields: [subDistrictId], references: [id], onDelete: SetNull)
|
subDistrict SubDistrict? @relation(fields: [subDistrictId], references: [id], onDelete: SetNull)
|
||||||
subDistrictId String?
|
subDistrictId String?
|
||||||
|
|
||||||
zipCodeText String?
|
|
||||||
|
|
||||||
email String
|
email String
|
||||||
telephoneNo String
|
telephoneNo String
|
||||||
|
|
||||||
|
|
@ -1243,9 +1233,6 @@ model Product {
|
||||||
productGroup ProductGroup @relation(fields: [productGroupId], references: [id], onDelete: Cascade)
|
productGroup ProductGroup @relation(fields: [productGroupId], references: [id], onDelete: Cascade)
|
||||||
productGroupId String
|
productGroupId String
|
||||||
|
|
||||||
flowAccountProductIdSellPrice String?
|
|
||||||
flowAccountProductIdAgentPrice String?
|
|
||||||
|
|
||||||
workProduct WorkProduct[]
|
workProduct WorkProduct[]
|
||||||
quotationProductServiceList QuotationProductServiceList[]
|
quotationProductServiceList QuotationProductServiceList[]
|
||||||
taskProduct TaskProduct[]
|
taskProduct TaskProduct[]
|
||||||
|
|
@ -1529,9 +1516,6 @@ model Payment {
|
||||||
|
|
||||||
amount Float
|
amount Float
|
||||||
date DateTime?
|
date DateTime?
|
||||||
channel String?
|
|
||||||
account String?
|
|
||||||
reference String?
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
createdBy User? @relation(name: "PaymentCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull)
|
createdBy User? @relation(name: "PaymentCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull)
|
||||||
|
|
@ -1618,7 +1602,6 @@ model RequestWork {
|
||||||
model RequestWorkStepStatus {
|
model RequestWorkStepStatus {
|
||||||
step Int
|
step Int
|
||||||
workStatus RequestWorkStatus @default(Pending)
|
workStatus RequestWorkStatus @default(Pending)
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
requestWork RequestWork @relation(fields: [requestWorkId], references: [id], onDelete: Cascade)
|
requestWork RequestWork @relation(fields: [requestWorkId], references: [id], onDelete: Cascade)
|
||||||
requestWorkId String
|
requestWorkId String
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,6 @@ const quotationData = (id: string) =>
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
customerBranch: {
|
customerBranch: {
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
include: {
|
include: {
|
||||||
customer: true,
|
customer: true,
|
||||||
businessType: true,
|
businessType: true,
|
||||||
|
|
@ -293,7 +288,6 @@ function replaceEmptyField<T>(data: T): T {
|
||||||
}
|
}
|
||||||
|
|
||||||
type FullAddress = {
|
type FullAddress = {
|
||||||
addressForeign?: boolean;
|
|
||||||
address: string;
|
address: string;
|
||||||
addressEN: string;
|
addressEN: string;
|
||||||
moo?: string;
|
moo?: string;
|
||||||
|
|
@ -302,14 +296,8 @@ type FullAddress = {
|
||||||
soiEN?: string;
|
soiEN?: string;
|
||||||
street?: string;
|
street?: string;
|
||||||
streetEN?: string;
|
streetEN?: string;
|
||||||
provinceText?: string | null;
|
|
||||||
provinceTextEN?: string | null;
|
|
||||||
province?: Province | null;
|
province?: Province | null;
|
||||||
districtText?: string | null;
|
|
||||||
districtTextEN?: string | null;
|
|
||||||
district?: District | null;
|
district?: District | null;
|
||||||
subDistrictText?: string | null;
|
|
||||||
subDistrictTextEN?: string | null;
|
|
||||||
subDistrict?: SubDistrict | null;
|
subDistrict?: SubDistrict | null;
|
||||||
en?: boolean;
|
en?: boolean;
|
||||||
};
|
};
|
||||||
|
|
@ -343,22 +331,13 @@ function addressFull(addr: FullAddress, lang: "th" | "en" = "en") {
|
||||||
if (addr.soi) fragments.push(`ซอย ${addr.soi},`);
|
if (addr.soi) fragments.push(`ซอย ${addr.soi},`);
|
||||||
if (addr.street) fragments.push(`ถนน${addr.street},`);
|
if (addr.street) fragments.push(`ถนน${addr.street},`);
|
||||||
|
|
||||||
if (!addr.addressForeign && addr.subDistrict) {
|
if (addr.subDistrict) {
|
||||||
fragments.push(`${addr.province?.id === "10" ? "แขวง" : "ตำบล"}${addr.subDistrict.name}`);
|
fragments.push(`${addr.province?.id === "10" ? "แขวง" : "ตำบล"}${addr.subDistrict.name},`);
|
||||||
}
|
}
|
||||||
if (addr.addressForeign && addr.subDistrictText) {
|
if (addr.district) {
|
||||||
fragments.push(`ตำบล${addr.subDistrictText}`);
|
fragments.push(`${addr.province?.id === "10" ? "เขต" : "อำเภอ"}${addr.district.name},`);
|
||||||
}
|
}
|
||||||
|
if (addr.province) fragments.push(`จังหวัด${addr.province.name},`);
|
||||||
if (!addr.addressForeign && addr.district) {
|
|
||||||
fragments.push(`${addr.province?.id === "10" ? "เขต" : "อำเภอ"}${addr.district.name}`);
|
|
||||||
}
|
|
||||||
if (addr.addressForeign && addr.districtText) {
|
|
||||||
fragments.push(`อำเภอ${addr.districtText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!addr.addressForeign && addr.province) fragments.push(`จังหวัด${addr.province.name}`);
|
|
||||||
if (addr.addressForeign && addr.provinceText) fragments.push(`จังหวัด${addr.provinceText}`);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -367,26 +346,11 @@ function addressFull(addr: FullAddress, lang: "th" | "en" = "en") {
|
||||||
if (addr.soiEN) fragments.push(`Soi ${addr.soiEN},`);
|
if (addr.soiEN) fragments.push(`Soi ${addr.soiEN},`);
|
||||||
if (addr.streetEN) fragments.push(`${addr.streetEN} Rd.`);
|
if (addr.streetEN) fragments.push(`${addr.streetEN} Rd.`);
|
||||||
|
|
||||||
if (!addr.addressForeign && addr.subDistrict) {
|
if (addr.subDistrict) {
|
||||||
fragments.push(`${addr.subDistrict.nameEN} sub-district,`);
|
fragments.push(`${addr.subDistrict.nameEN} sub-district,`);
|
||||||
}
|
}
|
||||||
if (addr.addressForeign && addr.subDistrictTextEN) {
|
if (addr.district) fragments.push(`${addr.district.nameEN} district,`);
|
||||||
fragments.push(`${addr.subDistrictTextEN} sub-district,`);
|
if (addr.province) fragments.push(`${addr.province.nameEN},`);
|
||||||
}
|
|
||||||
|
|
||||||
if (!addr.addressForeign && addr.district) {
|
|
||||||
fragments.push(`${addr.district.nameEN} district,`);
|
|
||||||
}
|
|
||||||
if (addr.addressForeign && addr.districtTextEN) {
|
|
||||||
fragments.push(`${addr.districtTextEN} district,`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!addr.addressForeign && addr.province) {
|
|
||||||
fragments.push(`${addr.province.nameEN},`);
|
|
||||||
}
|
|
||||||
if (addr.addressForeign && addr.provinceTextEN) {
|
|
||||||
fragments.push(`${addr.provinceTextEN} district,`);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -618,22 +618,9 @@ export class StatsController extends Controller {
|
||||||
startDate = dayjs(startDate).startOf("month").add(1, "month").toDate();
|
startDate = dayjs(startDate).startOf("month").add(1, "month").toDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
const invoices = await tx.invoice.findMany({
|
|
||||||
select: { id: true },
|
|
||||||
where: {
|
|
||||||
quotation: {
|
|
||||||
quotationStatus: { notIn: [QuotationStatus.Canceled] },
|
|
||||||
registeredBranch: { OR: permissionCondCompany(req.user) },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (invoices.length === 0) return [];
|
|
||||||
|
|
||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
months.map(async (v) => {
|
months.map(async (v) => {
|
||||||
const date = dayjs(v);
|
const date = dayjs(v);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
month: date.format("MM"),
|
month: date.format("MM"),
|
||||||
year: date.format("YYYY"),
|
year: date.format("YYYY"),
|
||||||
|
|
@ -642,7 +629,11 @@ export class StatsController extends Controller {
|
||||||
_sum: { amount: true },
|
_sum: { amount: true },
|
||||||
where: {
|
where: {
|
||||||
createdAt: { gte: v, lte: date.endOf("month").toDate() },
|
createdAt: { gte: v, lte: date.endOf("month").toDate() },
|
||||||
invoiceId: { in: invoices.map((v) => v.id) },
|
invoice: {
|
||||||
|
quotation: {
|
||||||
|
registeredBranch: { OR: permissionCondCompany(req.user) },
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
by: "paymentStatus",
|
by: "paymentStatus",
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -387,14 +387,6 @@ export class BranchController extends Controller {
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("{branchId}/bank")
|
|
||||||
@Security("keycloak")
|
|
||||||
async getBranchBankById(@Path() branchId: string) {
|
|
||||||
return await prisma.branchBank.findMany({
|
|
||||||
where: { branchId },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Security("keycloak", MANAGE_ROLES)
|
@Security("keycloak", MANAGE_ROLES)
|
||||||
async createBranch(@Request() req: RequestWithUser, @Body() body: BranchCreate) {
|
async createBranch(@Request() req: RequestWithUser, @Body() body: BranchCreate) {
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,6 @@ type UserCreate = {
|
||||||
responsibleArea?: string[] | null;
|
responsibleArea?: string[] | null;
|
||||||
birthDate?: Date | null;
|
birthDate?: Date | null;
|
||||||
|
|
||||||
addressForeign?: boolean;
|
|
||||||
address: string;
|
address: string;
|
||||||
addressEN: string;
|
addressEN: string;
|
||||||
soi?: string | null;
|
soi?: string | null;
|
||||||
|
|
@ -123,16 +122,9 @@ type UserCreate = {
|
||||||
email: string;
|
email: string;
|
||||||
telephoneNo: string;
|
telephoneNo: string;
|
||||||
|
|
||||||
subDistrictText?: string | null;
|
|
||||||
subDistrictTextEN?: string | null;
|
|
||||||
subDistrictId?: string | null;
|
subDistrictId?: string | null;
|
||||||
districtText?: string | null;
|
|
||||||
districtTextEN?: string | null;
|
|
||||||
districtId?: string | null;
|
districtId?: string | null;
|
||||||
provinceText?: string | null;
|
|
||||||
provinceTextEN?: string | null;
|
|
||||||
provinceId?: string | null;
|
provinceId?: string | null;
|
||||||
zipCodeText?: string | null;
|
|
||||||
|
|
||||||
selectedImage?: string;
|
selectedImage?: string;
|
||||||
|
|
||||||
|
|
@ -181,7 +173,6 @@ type UserUpdate = {
|
||||||
responsibleArea?: string[] | null;
|
responsibleArea?: string[] | null;
|
||||||
birthDate?: Date | null;
|
birthDate?: Date | null;
|
||||||
|
|
||||||
addressForeign?: boolean;
|
|
||||||
address?: string;
|
address?: string;
|
||||||
addressEN?: string;
|
addressEN?: string;
|
||||||
soi?: string | null;
|
soi?: string | null;
|
||||||
|
|
@ -195,16 +186,9 @@ type UserUpdate = {
|
||||||
|
|
||||||
selectedImage?: string;
|
selectedImage?: string;
|
||||||
|
|
||||||
subDistrictText?: string | null;
|
|
||||||
subDistrictTextEN?: string | null;
|
|
||||||
subDistrictId?: string | null;
|
subDistrictId?: string | null;
|
||||||
districtText?: string | null;
|
|
||||||
districtTextEN?: string | null;
|
|
||||||
districtId?: string | null;
|
districtId?: string | null;
|
||||||
provinceText?: string | null;
|
|
||||||
provinceTextEN?: string | null;
|
|
||||||
provinceId?: string | null;
|
provinceId?: string | null;
|
||||||
zipCodeText?: string | null;
|
|
||||||
|
|
||||||
branchId?: string | string[];
|
branchId?: string | string[];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -238,11 +238,6 @@ export class CustomerBranchController extends Controller {
|
||||||
const [result, total] = await prisma.$transaction([
|
const [result, total] = await prisma.$transaction([
|
||||||
prisma.customerBranch.findMany({
|
prisma.customerBranch.findMany({
|
||||||
orderBy: [{ code: "asc" }, { statusOrder: "asc" }, { createdAt: "asc" }],
|
orderBy: [{ code: "asc" }, { statusOrder: "asc" }, { createdAt: "asc" }],
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
include: {
|
include: {
|
||||||
customer: includeCustomer,
|
customer: includeCustomer,
|
||||||
province: true,
|
province: true,
|
||||||
|
|
@ -267,11 +262,6 @@ export class CustomerBranchController extends Controller {
|
||||||
@Security("keycloak")
|
@Security("keycloak")
|
||||||
async getById(@Path() branchId: string) {
|
async getById(@Path() branchId: string) {
|
||||||
const record = await prisma.customerBranch.findFirst({
|
const record = await prisma.customerBranch.findFirst({
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
include: {
|
include: {
|
||||||
customer: true,
|
customer: true,
|
||||||
province: true,
|
province: true,
|
||||||
|
|
@ -362,11 +352,6 @@ export class CustomerBranchController extends Controller {
|
||||||
include: branchRelationPermInclude(req.user),
|
include: branchRelationPermInclude(req.user),
|
||||||
},
|
},
|
||||||
branch: {
|
branch: {
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
take: 1,
|
take: 1,
|
||||||
orderBy: { createdAt: "asc" },
|
orderBy: { createdAt: "asc" },
|
||||||
},
|
},
|
||||||
|
|
@ -638,7 +623,7 @@ export class CustomerBranchFileController extends Controller {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!data) throw notFoundError("Customer Branch");
|
if (!data) throw notFoundError("Customer Branch");
|
||||||
await permissionCheckCompany(user, data.customer.registeredBranch);
|
await permissionCheck(user, data.customer.registeredBranch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("attachment")
|
@Get("attachment")
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ import {
|
||||||
} from "../utils/minio";
|
} from "../utils/minio";
|
||||||
import { isUsedError, notFoundError, relationError } from "../utils/error";
|
import { isUsedError, notFoundError, relationError } from "../utils/error";
|
||||||
import { connectOrNot, queryOrNot, whereDateQuery } from "../utils/relation";
|
import { connectOrNot, queryOrNot, whereDateQuery } from "../utils/relation";
|
||||||
import { json2csv } from "json-2-csv";
|
|
||||||
|
|
||||||
const MANAGE_ROLES = [
|
const MANAGE_ROLES = [
|
||||||
"system",
|
"system",
|
||||||
|
|
@ -170,10 +169,6 @@ export class CustomerController extends Controller {
|
||||||
@Query() activeBranchOnly?: boolean,
|
@Query() activeBranchOnly?: boolean,
|
||||||
@Query() startDate?: Date,
|
@Query() startDate?: Date,
|
||||||
@Query() endDate?: Date,
|
@Query() endDate?: Date,
|
||||||
@Query() businessTypeId?: string,
|
|
||||||
@Query() provinceId?: string,
|
|
||||||
@Query() districtId?: string,
|
|
||||||
@Query() subDistrictId?: string,
|
|
||||||
) {
|
) {
|
||||||
const where = {
|
const where = {
|
||||||
OR: queryOrNot<Prisma.CustomerWhereInput[]>(query, [
|
OR: queryOrNot<Prisma.CustomerWhereInput[]>(query, [
|
||||||
|
|
@ -196,35 +191,6 @@ export class CustomerController extends Controller {
|
||||||
: permissionCond(req.user, { activeOnly: activeBranchOnly }),
|
: permissionCond(req.user, { activeOnly: activeBranchOnly }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
branch: {
|
|
||||||
some: {
|
|
||||||
AND: [
|
|
||||||
businessTypeId
|
|
||||||
? {
|
|
||||||
OR: [{ businessType: { id: businessTypeId } }],
|
|
||||||
}
|
|
||||||
: {},
|
|
||||||
|
|
||||||
provinceId
|
|
||||||
? {
|
|
||||||
OR: [{ province: { id: provinceId } }],
|
|
||||||
}
|
|
||||||
: {},
|
|
||||||
|
|
||||||
districtId
|
|
||||||
? {
|
|
||||||
OR: [{ district: { id: districtId } }],
|
|
||||||
}
|
|
||||||
: {},
|
|
||||||
|
|
||||||
subDistrictId
|
|
||||||
? {
|
|
||||||
OR: [{ subDistrict: { id: subDistrictId } }],
|
|
||||||
}
|
|
||||||
: {},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...whereDateQuery(startDate, endDate),
|
...whereDateQuery(startDate, endDate),
|
||||||
} satisfies Prisma.CustomerWhereInput;
|
} satisfies Prisma.CustomerWhereInput;
|
||||||
|
|
||||||
|
|
@ -240,11 +206,6 @@ export class CustomerController extends Controller {
|
||||||
district: true,
|
district: true,
|
||||||
subDistrict: true,
|
subDistrict: true,
|
||||||
},
|
},
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
orderBy: [{ statusOrder: "asc" }, { createdAt: "asc" }],
|
orderBy: [{ statusOrder: "asc" }, { createdAt: "asc" }],
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
|
|
@ -253,11 +214,6 @@ export class CustomerController extends Controller {
|
||||||
district: true,
|
district: true,
|
||||||
subDistrict: true,
|
subDistrict: true,
|
||||||
},
|
},
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
take: 1,
|
take: 1,
|
||||||
orderBy: { createdAt: "asc" },
|
orderBy: { createdAt: "asc" },
|
||||||
},
|
},
|
||||||
|
|
@ -288,11 +244,6 @@ export class CustomerController extends Controller {
|
||||||
district: true,
|
district: true,
|
||||||
subDistrict: true,
|
subDistrict: true,
|
||||||
},
|
},
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
orderBy: { createdAt: "asc" },
|
orderBy: { createdAt: "asc" },
|
||||||
},
|
},
|
||||||
createdBy: true,
|
createdBy: true,
|
||||||
|
|
@ -364,11 +315,6 @@ export class CustomerController extends Controller {
|
||||||
district: true,
|
district: true,
|
||||||
subDistrict: true,
|
subDistrict: true,
|
||||||
},
|
},
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
createdBy: true,
|
createdBy: true,
|
||||||
updatedBy: true,
|
updatedBy: true,
|
||||||
|
|
@ -468,11 +414,6 @@ export class CustomerController extends Controller {
|
||||||
district: true,
|
district: true,
|
||||||
subDistrict: true,
|
subDistrict: true,
|
||||||
},
|
},
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
createdBy: true,
|
createdBy: true,
|
||||||
updatedBy: true,
|
updatedBy: true,
|
||||||
|
|
@ -511,13 +452,7 @@ export class CustomerController extends Controller {
|
||||||
await deleteFolder(`customer/${customerId}`);
|
await deleteFolder(`customer/${customerId}`);
|
||||||
const data = await tx.customer.delete({
|
const data = await tx.customer.delete({
|
||||||
include: {
|
include: {
|
||||||
branch: {
|
branch: true,
|
||||||
omit: {
|
|
||||||
otpCode: true,
|
|
||||||
otpExpires: true,
|
|
||||||
userId: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
registeredBranch: {
|
registeredBranch: {
|
||||||
include: {
|
include: {
|
||||||
headOffice: true,
|
headOffice: true,
|
||||||
|
|
@ -612,52 +547,3 @@ export class CustomerImageController extends Controller {
|
||||||
await deleteFile(fileLocation.customer.img(customerId, name));
|
await deleteFile(fileLocation.customer.img(customerId, name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Route("api/v1/customer-export")
|
|
||||||
@Tags("Customer")
|
|
||||||
export class CustomerExportController extends CustomerController {
|
|
||||||
@Get()
|
|
||||||
@Security("keycloak")
|
|
||||||
async exportCustomer(
|
|
||||||
@Request() req: RequestWithUser,
|
|
||||||
@Query() customerType?: CustomerType,
|
|
||||||
@Query() query: string = "",
|
|
||||||
@Query() status?: Status,
|
|
||||||
@Query() page: number = 1,
|
|
||||||
@Query() pageSize: number = 30,
|
|
||||||
@Query() includeBranch: boolean = false,
|
|
||||||
@Query() company: boolean = false,
|
|
||||||
@Query() activeBranchOnly?: boolean,
|
|
||||||
@Query() startDate?: Date,
|
|
||||||
@Query() endDate?: Date,
|
|
||||||
@Query() businessTypeId?: string,
|
|
||||||
@Query() provinceId?: string,
|
|
||||||
@Query() districtId?: string,
|
|
||||||
@Query() subDistrictId?: string,
|
|
||||||
) {
|
|
||||||
const ret = await this.list(
|
|
||||||
req,
|
|
||||||
customerType,
|
|
||||||
query,
|
|
||||||
status,
|
|
||||||
page,
|
|
||||||
pageSize,
|
|
||||||
includeBranch,
|
|
||||||
company,
|
|
||||||
activeBranchOnly,
|
|
||||||
startDate,
|
|
||||||
endDate,
|
|
||||||
businessTypeId,
|
|
||||||
provinceId,
|
|
||||||
districtId,
|
|
||||||
subDistrictId,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.setHeader("Content-Type", "text/csv");
|
|
||||||
|
|
||||||
return json2csv(
|
|
||||||
ret.result.map((v) => Object.assign(v, { branch: v.branch.at(0) ?? null })),
|
|
||||||
{ useDateIso8601Format: true, expandNestedObjects: true },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ import {
|
||||||
listFile,
|
listFile,
|
||||||
setFile,
|
setFile,
|
||||||
} from "../utils/minio";
|
} from "../utils/minio";
|
||||||
import { json2csv } from "json-2-csv";
|
|
||||||
|
|
||||||
if (!process.env.MINIO_BUCKET) {
|
if (!process.env.MINIO_BUCKET) {
|
||||||
throw Error("Require MinIO bucket.");
|
throw Error("Require MinIO bucket.");
|
||||||
|
|
@ -66,9 +65,7 @@ function globalAllow(user: RequestWithUser["user"]) {
|
||||||
return user.roles?.some((v) => listAllowed.includes(v)) || false;
|
return user.roles?.some((v) => listAllowed.includes(v)) || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const permissionCondCompany = createPermCondition((_) => true);
|
|
||||||
const permissionCond = createPermCondition(globalAllow);
|
const permissionCond = createPermCondition(globalAllow);
|
||||||
const permissionCheckCompany = createPermCheck((_) => true);
|
|
||||||
const permissionCheck = createPermCheck(globalAllow);
|
const permissionCheck = createPermCheck(globalAllow);
|
||||||
|
|
||||||
type EmployeeCreate = {
|
type EmployeeCreate = {
|
||||||
|
|
@ -250,6 +247,7 @@ export class EmployeeController extends Controller {
|
||||||
endDate,
|
endDate,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("list")
|
@Post("list")
|
||||||
@Security("keycloak")
|
@Security("keycloak")
|
||||||
async listByCriteria(
|
async listByCriteria(
|
||||||
|
|
@ -671,7 +669,7 @@ export class EmployeeFileController extends Controller {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!data) throw notFoundError("Employee");
|
if (!data) throw notFoundError("Employee");
|
||||||
await permissionCheckCompany(user, data.customerBranch.customer.registeredBranch);
|
await permissionCheck(user, data.customerBranch.customer.registeredBranch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("image")
|
@Get("image")
|
||||||
|
|
@ -927,55 +925,3 @@ export class EmployeeFileController extends Controller {
|
||||||
return await deleteFile(fileLocation.employee.inCountryNotice(employeeId, noticeId));
|
return await deleteFile(fileLocation.employee.inCountryNotice(employeeId, noticeId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Route("api/v1/employee-export")
|
|
||||||
@Tags("Employee")
|
|
||||||
export class EmployeeExportController extends EmployeeController {
|
|
||||||
@Get()
|
|
||||||
@Security("keycloak")
|
|
||||||
async exportEmployee(
|
|
||||||
@Request() req: RequestWithUser,
|
|
||||||
@Query() zipCode?: string,
|
|
||||||
@Query() gender?: string,
|
|
||||||
@Query() status?: Status,
|
|
||||||
@Query() visa?: boolean,
|
|
||||||
@Query() passport?: boolean,
|
|
||||||
@Query() customerId?: string,
|
|
||||||
@Query() customerBranchId?: string,
|
|
||||||
@Query() query: string = "",
|
|
||||||
@Query() page: number = 1,
|
|
||||||
@Query() pageSize: number = 30,
|
|
||||||
@Query() activeOnly?: boolean,
|
|
||||||
@Query() startDate?: Date,
|
|
||||||
@Query() endDate?: Date,
|
|
||||||
) {
|
|
||||||
const ret = await this.listByCriteria(
|
|
||||||
req,
|
|
||||||
zipCode,
|
|
||||||
gender,
|
|
||||||
status,
|
|
||||||
visa,
|
|
||||||
passport,
|
|
||||||
customerId,
|
|
||||||
customerBranchId,
|
|
||||||
query,
|
|
||||||
page,
|
|
||||||
pageSize,
|
|
||||||
activeOnly,
|
|
||||||
startDate,
|
|
||||||
endDate,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.setHeader("Content-Type", "text/csv");
|
|
||||||
|
|
||||||
return json2csv(
|
|
||||||
ret.result.map((v) =>
|
|
||||||
Object.assign(v, {
|
|
||||||
employeePassport: v.employeePassport?.at(0) ?? null,
|
|
||||||
employeeVisa: v.employeeVisa?.at(0) ?? null,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
{ useDateIso8601Format: true },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,6 @@ import { deleteFile, deleteFolder, fileLocation, getFile, listFile, setFile } fr
|
||||||
import { isUsedError, notFoundError, relationError } from "../utils/error";
|
import { isUsedError, notFoundError, relationError } from "../utils/error";
|
||||||
import { queryOrNot, whereDateQuery } from "../utils/relation";
|
import { queryOrNot, whereDateQuery } from "../utils/relation";
|
||||||
import spreadsheet from "../utils/spreadsheet";
|
import spreadsheet from "../utils/spreadsheet";
|
||||||
import flowAccount from "../services/flowaccount";
|
|
||||||
import { json2csv } from "json-2-csv";
|
|
||||||
|
|
||||||
const MANAGE_ROLES = [
|
const MANAGE_ROLES = [
|
||||||
"system",
|
"system",
|
||||||
|
|
@ -78,7 +76,6 @@ type ProductCreate = {
|
||||||
|
|
||||||
type ProductUpdate = {
|
type ProductUpdate = {
|
||||||
status?: "ACTIVE" | "INACTIVE";
|
status?: "ACTIVE" | "INACTIVE";
|
||||||
code?: string;
|
|
||||||
name?: string;
|
name?: string;
|
||||||
detail?: string;
|
detail?: string;
|
||||||
process?: number;
|
process?: number;
|
||||||
|
|
@ -302,21 +299,13 @@ export class ProductController extends Controller {
|
||||||
},
|
},
|
||||||
update: { value: { increment: 1 } },
|
update: { value: { increment: 1 } },
|
||||||
});
|
});
|
||||||
|
return await prisma.product.create({
|
||||||
const listId = await flowAccount.createProducts(
|
|
||||||
`${body.code.toLocaleUpperCase()}${last.value.toString().padStart(3, "0")}`,
|
|
||||||
body,
|
|
||||||
);
|
|
||||||
|
|
||||||
return await tx.product.create({
|
|
||||||
include: {
|
include: {
|
||||||
createdBy: true,
|
createdBy: true,
|
||||||
updatedBy: true,
|
updatedBy: true,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
...body,
|
...body,
|
||||||
flowAccountProductIdAgentPrice: `${listId.data.productIdAgentPrice}`,
|
|
||||||
flowAccountProductIdSellPrice: `${listId.data.productIdSellPrice}`,
|
|
||||||
document: body.document
|
document: body.document
|
||||||
? {
|
? {
|
||||||
createMany: { data: body.document.map((v) => ({ name: v })) },
|
createMany: { data: body.document.map((v) => ({ name: v })) },
|
||||||
|
|
@ -390,30 +379,6 @@ export class ProductController extends Controller {
|
||||||
await permissionCheck(req.user, productGroup.registeredBranch);
|
await permissionCheck(req.user, productGroup.registeredBranch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
product.flowAccountProductIdSellPrice !== null &&
|
|
||||||
product.flowAccountProductIdAgentPrice !== null
|
|
||||||
) {
|
|
||||||
const mergedBody = {
|
|
||||||
...body,
|
|
||||||
code: body.code ?? product.code,
|
|
||||||
price: body.price ?? product.price,
|
|
||||||
agentPrice: body.agentPrice ?? product.agentPrice,
|
|
||||||
serviceCharge: body.serviceCharge ?? product.serviceCharge,
|
|
||||||
vatIncluded: body.vatIncluded ?? product.vatIncluded,
|
|
||||||
agentPriceVatIncluded: body.agentPriceVatIncluded ?? product.agentPriceVatIncluded,
|
|
||||||
serviceChargeVatIncluded: body.serviceChargeVatIncluded ?? product.serviceChargeVatIncluded,
|
|
||||||
};
|
|
||||||
|
|
||||||
await flowAccount.editProducts(
|
|
||||||
product.flowAccountProductIdSellPrice,
|
|
||||||
product.flowAccountProductIdAgentPrice,
|
|
||||||
mergedBody,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
throw notFoundError("FlowAccountProductId");
|
|
||||||
}
|
|
||||||
|
|
||||||
const record = await prisma.product.update({
|
const record = await prisma.product.update({
|
||||||
include: {
|
include: {
|
||||||
productGroup: true,
|
productGroup: true,
|
||||||
|
|
@ -476,18 +441,6 @@ export class ProductController extends Controller {
|
||||||
|
|
||||||
if (record.status !== Status.CREATED) throw isUsedError("Product");
|
if (record.status !== Status.CREATED) throw isUsedError("Product");
|
||||||
|
|
||||||
if (
|
|
||||||
record.flowAccountProductIdSellPrice !== null &&
|
|
||||||
record.flowAccountProductIdAgentPrice !== null
|
|
||||||
) {
|
|
||||||
await Promise.all([
|
|
||||||
flowAccount.deleteProduct(record.flowAccountProductIdSellPrice),
|
|
||||||
flowAccount.deleteProduct(record.flowAccountProductIdAgentPrice),
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
throw notFoundError("FlowAccountProductId");
|
|
||||||
}
|
|
||||||
|
|
||||||
await deleteFolder(fileLocation.product.img(productId));
|
await deleteFolder(fileLocation.product.img(productId));
|
||||||
|
|
||||||
return await prisma.product.delete({
|
return await prisma.product.delete({
|
||||||
|
|
@ -689,43 +642,3 @@ export class ProductFileController extends Controller {
|
||||||
return await deleteFile(fileLocation.product.img(productId, name));
|
return await deleteFile(fileLocation.product.img(productId, name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Route("api/v1/product-export")
|
|
||||||
@Tags("Product")
|
|
||||||
export class ProductExportController extends ProductController {
|
|
||||||
@Get()
|
|
||||||
@Security("keycloak")
|
|
||||||
async exportCustomer(
|
|
||||||
@Request() req: RequestWithUser,
|
|
||||||
@Query() status?: Status,
|
|
||||||
@Query() shared?: boolean,
|
|
||||||
@Query() productGroupId?: string,
|
|
||||||
@Query() query: string = "",
|
|
||||||
@Query() page: number = 1,
|
|
||||||
@Query() pageSize: number = 30,
|
|
||||||
@Query() orderField?: keyof Product,
|
|
||||||
@Query() orderBy?: "asc" | "desc",
|
|
||||||
@Query() activeOnly?: boolean,
|
|
||||||
@Query() startDate?: Date,
|
|
||||||
@Query() endDate?: Date,
|
|
||||||
) {
|
|
||||||
const ret = await this.getProduct(
|
|
||||||
req,
|
|
||||||
status,
|
|
||||||
shared,
|
|
||||||
productGroupId,
|
|
||||||
query,
|
|
||||||
page,
|
|
||||||
pageSize,
|
|
||||||
orderField,
|
|
||||||
orderBy,
|
|
||||||
activeOnly,
|
|
||||||
startDate,
|
|
||||||
endDate,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.setHeader("Content-Type", "text/csv");
|
|
||||||
|
|
||||||
return json2csv(ret.result, { useDateIso8601Format: true, expandNestedObjects: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -113,15 +113,7 @@ export class QuotationPayment extends Controller {
|
||||||
@Security("keycloak", MANAGE_ROLES.concat(["head_of_sale", "sale"]))
|
@Security("keycloak", MANAGE_ROLES.concat(["head_of_sale", "sale"]))
|
||||||
async updatePayment(
|
async updatePayment(
|
||||||
@Path() paymentId: string,
|
@Path() paymentId: string,
|
||||||
@Body()
|
@Body() body: { amount?: number; date?: Date; paymentStatus?: PaymentStatus },
|
||||||
body: {
|
|
||||||
amount?: number;
|
|
||||||
date?: Date;
|
|
||||||
paymentStatus?: PaymentStatus;
|
|
||||||
channel?: string | null;
|
|
||||||
account?: string | null;
|
|
||||||
reference?: string | null;
|
|
||||||
},
|
|
||||||
@Request() req: RequestWithUser,
|
@Request() req: RequestWithUser,
|
||||||
) {
|
) {
|
||||||
const record = await prisma.payment.findUnique({
|
const record = await prisma.payment.findUnique({
|
||||||
|
|
@ -152,18 +144,7 @@ export class QuotationPayment extends Controller {
|
||||||
|
|
||||||
if (!record) throw notFoundError("Payment");
|
if (!record) throw notFoundError("Payment");
|
||||||
|
|
||||||
if (record.paymentStatus === "PaymentSuccess") {
|
if (record.paymentStatus === "PaymentSuccess") return record;
|
||||||
const { channel, account, reference } = body;
|
|
||||||
return await prisma.payment.update({
|
|
||||||
where: { id: paymentId, invoice: { quotationId: record.invoice.quotationId } },
|
|
||||||
data: {
|
|
||||||
channel,
|
|
||||||
account,
|
|
||||||
reference,
|
|
||||||
updatedByUserId: req.user.sub,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return await prisma.$transaction(async (tx) => {
|
return await prisma.$transaction(async (tx) => {
|
||||||
const current = new Date();
|
const current = new Date();
|
||||||
|
|
@ -268,7 +249,7 @@ export class QuotationPayment extends Controller {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (quotation.quotationStatus === "PaymentInProcess") {
|
if (quotation.quotationStatus === "PaymentPending") {
|
||||||
await prisma.notification.create({
|
await prisma.notification.create({
|
||||||
data: {
|
data: {
|
||||||
title: "รายการคำขอใหม่ / New Request",
|
title: "รายการคำขอใหม่ / New Request",
|
||||||
|
|
|
||||||
|
|
@ -527,15 +527,16 @@ export class QuotationController extends Controller {
|
||||||
const vatIncluded = body.agentPrice ? p.agentPriceVatIncluded : p.vatIncluded;
|
const vatIncluded = body.agentPrice ? p.agentPriceVatIncluded : p.vatIncluded;
|
||||||
|
|
||||||
const originalPrice = body.agentPrice ? p.agentPrice : p.price;
|
const originalPrice = body.agentPrice ? p.agentPrice : p.price;
|
||||||
const finalPrice = precisionRound(
|
const finalPriceWithVat = precisionRound(
|
||||||
originalPrice + (vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
originalPrice + (vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
||||||
);
|
);
|
||||||
const pricePerUnit = finalPrice / (1 + VAT_DEFAULT);
|
|
||||||
|
const price = finalPriceWithVat;
|
||||||
|
const pricePerUnit = price / (1 + VAT_DEFAULT);
|
||||||
const vat = (body.agentPrice ? p.agentPriceCalcVat : p.calcVat)
|
const vat = (body.agentPrice ? p.agentPriceCalcVat : p.calcVat)
|
||||||
? ((pricePerUnit * (1 + VAT_DEFAULT) * v.amount - (v.discount || 0)) /
|
? (pricePerUnit * v.amount - (v.discount || 0)) * VAT_DEFAULT
|
||||||
(1 + VAT_DEFAULT)) *
|
|
||||||
VAT_DEFAULT
|
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
order: i + 1,
|
order: i + 1,
|
||||||
productId: v.productId,
|
productId: v.productId,
|
||||||
|
|
@ -556,13 +557,13 @@ export class QuotationController extends Controller {
|
||||||
|
|
||||||
const price = list.reduce(
|
const price = list.reduce(
|
||||||
(a, c) => {
|
(a, c) => {
|
||||||
const vat = c.vat ? VAT_DEFAULT : 0;
|
a.totalPrice = precisionRound(a.totalPrice + c.pricePerUnit * c.amount);
|
||||||
const price = c.pricePerUnit * c.amount * (1 + vat) - c.discount;
|
|
||||||
|
|
||||||
a.totalPrice = precisionRound(a.totalPrice + price / (1 + vat) + c.discount);
|
|
||||||
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
|
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
|
||||||
a.vat = precisionRound(a.vat + c.vat);
|
a.vat = precisionRound(a.vat + c.vat);
|
||||||
a.vatExcluded = c.vat === 0 ? precisionRound(a.vatExcluded + price) : a.vatExcluded;
|
a.vatExcluded =
|
||||||
|
c.vat === 0
|
||||||
|
? precisionRound(a.vatExcluded + (c.pricePerUnit * c.amount - (c.discount || 0)))
|
||||||
|
: a.vatExcluded;
|
||||||
a.finalPrice = precisionRound(
|
a.finalPrice = precisionRound(
|
||||||
Math.max(a.totalPrice - a.totalDiscount + a.vat - (body.discount || 0), 0),
|
Math.max(a.totalPrice - a.totalDiscount + a.vat - (body.discount || 0), 0),
|
||||||
);
|
);
|
||||||
|
|
@ -663,14 +664,7 @@ export class QuotationController extends Controller {
|
||||||
title: "ใบเสนอราคาใหม่ / New Quotation",
|
title: "ใบเสนอราคาใหม่ / New Quotation",
|
||||||
detail: "รหัส / code : " + ret.code,
|
detail: "รหัส / code : " + ret.code,
|
||||||
registeredBranchId: ret.registeredBranchId,
|
registeredBranchId: ret.registeredBranchId,
|
||||||
groupReceiver: {
|
groupReceiver: { create: [{ name: "sale" }, { name: "head_of_sale" }] },
|
||||||
create: [
|
|
||||||
{ name: "sale" },
|
|
||||||
{ name: "head_of_sale" },
|
|
||||||
{ name: "accountant" },
|
|
||||||
{ name: "branch_accountant" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -814,14 +808,14 @@ export class QuotationController extends Controller {
|
||||||
const vatIncluded = record.agentPrice ? p.agentPriceVatIncluded : p.vatIncluded;
|
const vatIncluded = record.agentPrice ? p.agentPriceVatIncluded : p.vatIncluded;
|
||||||
|
|
||||||
const originalPrice = record.agentPrice ? p.agentPrice : p.price;
|
const originalPrice = record.agentPrice ? p.agentPrice : p.price;
|
||||||
const finalPrice = precisionRound(
|
const finalPriceWithVat = precisionRound(
|
||||||
originalPrice + (vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
originalPrice + (vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
||||||
);
|
);
|
||||||
const pricePerUnit = finalPrice / (1 + VAT_DEFAULT);
|
|
||||||
|
const price = finalPriceWithVat;
|
||||||
|
const pricePerUnit = price / (1 + VAT_DEFAULT);
|
||||||
const vat = (record.agentPrice ? p.agentPriceCalcVat : p.calcVat)
|
const vat = (record.agentPrice ? p.agentPriceCalcVat : p.calcVat)
|
||||||
? ((pricePerUnit * (1 + VAT_DEFAULT) * v.amount - (v.discount || 0)) /
|
? (pricePerUnit * v.amount - (v.discount || 0)) * VAT_DEFAULT
|
||||||
(1 + VAT_DEFAULT)) *
|
|
||||||
VAT_DEFAULT
|
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -844,13 +838,15 @@ export class QuotationController extends Controller {
|
||||||
|
|
||||||
const price = list?.reduce(
|
const price = list?.reduce(
|
||||||
(a, c) => {
|
(a, c) => {
|
||||||
const vat = c.vat ? VAT_DEFAULT : 0;
|
a.totalPrice = precisionRound(a.totalPrice + c.pricePerUnit * c.amount);
|
||||||
const price = c.pricePerUnit * c.amount * (1 + vat) - c.discount;
|
|
||||||
|
|
||||||
a.totalPrice = precisionRound(a.totalPrice + price / (1 + vat) + c.discount);
|
|
||||||
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
|
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
|
||||||
a.vat = precisionRound(a.vat + c.vat);
|
a.vat = precisionRound(a.vat + c.vat);
|
||||||
a.vatExcluded = c.vat === 0 ? precisionRound(a.vatExcluded + price) : a.vatExcluded;
|
a.vatExcluded =
|
||||||
|
c.vat === 0
|
||||||
|
? precisionRound(
|
||||||
|
a.vatExcluded + (c.pricePerUnit * c.amount - (c.discount || 0)) * VAT_DEFAULT,
|
||||||
|
)
|
||||||
|
: a.vatExcluded;
|
||||||
a.finalPrice = precisionRound(
|
a.finalPrice = precisionRound(
|
||||||
Math.max(a.totalPrice - a.totalDiscount + a.vat - (body.discount || 0), 0),
|
Math.max(a.totalPrice - a.totalDiscount + a.vat - (body.discount || 0), 0),
|
||||||
);
|
);
|
||||||
|
|
@ -866,7 +862,6 @@ export class QuotationController extends Controller {
|
||||||
finalPrice: 0,
|
finalPrice: 0,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const changed = list?.some((lhs) => {
|
const changed = list?.some((lhs) => {
|
||||||
const found = record.productServiceList.find((rhs) => {
|
const found = record.productServiceList.find((rhs) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -900,20 +895,6 @@ export class QuotationController extends Controller {
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (customerBranch) {
|
|
||||||
await tx.customerBranch.update({
|
|
||||||
where: { id: customerBranch.id },
|
|
||||||
data: {
|
|
||||||
customer: {
|
|
||||||
update: {
|
|
||||||
status: Status.ACTIVE,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
status: Status.ACTIVE,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return await tx.quotation.update({
|
return await tx.quotation.update({
|
||||||
include: {
|
include: {
|
||||||
productServiceList: {
|
productServiceList: {
|
||||||
|
|
|
||||||
|
|
@ -293,17 +293,14 @@ export class RequestDataController extends Controller {
|
||||||
async updateRequestData(
|
async updateRequestData(
|
||||||
@Request() req: RequestWithUser,
|
@Request() req: RequestWithUser,
|
||||||
@Body()
|
@Body()
|
||||||
body: {
|
boby: {
|
||||||
defaultMessengerId: string;
|
defaultMessengerId: string;
|
||||||
requestDataId: string[];
|
requestDataId: string[];
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if (body.requestDataId.length === 0) return;
|
const record = await prisma.requestData.updateManyAndReturn({
|
||||||
|
|
||||||
return await prisma.$transaction(async (tx) => {
|
|
||||||
const record = await tx.requestData.updateManyAndReturn({
|
|
||||||
where: {
|
where: {
|
||||||
id: { in: body.requestDataId },
|
id: { in: boby.requestDataId },
|
||||||
quotation: {
|
quotation: {
|
||||||
registeredBranch: {
|
registeredBranch: {
|
||||||
OR: permissionCond(req.user),
|
OR: permissionCond(req.user),
|
||||||
|
|
@ -311,44 +308,19 @@ export class RequestDataController extends Controller {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
defaultMessengerId: body.defaultMessengerId,
|
defaultMessengerId: boby.defaultMessengerId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (record.length <= 0) throw notFoundError("Request Data");
|
if (record.length <= 0) throw notFoundError("Request Data");
|
||||||
|
|
||||||
await tx.requestWorkStepStatus.updateMany({
|
|
||||||
where: {
|
|
||||||
workStatus: {
|
|
||||||
in: [
|
|
||||||
RequestWorkStatus.Pending,
|
|
||||||
RequestWorkStatus.Waiting,
|
|
||||||
RequestWorkStatus.InProgress,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
requestWork: {
|
|
||||||
requestDataId: { in: body.requestDataId },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: { responsibleUserId: body.defaultMessengerId },
|
|
||||||
});
|
|
||||||
|
|
||||||
return record[0];
|
return record[0];
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Route("/api/v1/request-data/{requestDataId}")
|
@Route("/api/v1/request-data/{requestDataId}")
|
||||||
@Tags("Request List")
|
@Tags("Request List")
|
||||||
export class RequestDataActionController extends Controller {
|
export class RequestDataActionController extends Controller {
|
||||||
async #getLineToken() {
|
|
||||||
if (!process.env.LINE_MESSAGING_API_TOKEN) {
|
|
||||||
console.warn("Line Webhook Activated but LINE_MESSAGING_API_TOKEN not set.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.env.LINE_MESSAGING_API_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post("reject-request-cancel")
|
@Post("reject-request-cancel")
|
||||||
@Security("keycloak")
|
@Security("keycloak")
|
||||||
async rejectRequestCancel(
|
async rejectRequestCancel(
|
||||||
|
|
@ -423,17 +395,6 @@ export class RequestDataActionController extends Controller {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
include: {
|
|
||||||
quotation: {
|
|
||||||
include: {
|
|
||||||
customerBranch: {
|
|
||||||
include: {
|
|
||||||
customer: { include: { branch: { where: { userId: { not: null } } } } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result) throw notFoundError("Request Data");
|
if (!result) throw notFoundError("Request Data");
|
||||||
|
|
@ -476,88 +437,23 @@ export class RequestDataActionController extends Controller {
|
||||||
data: { quotationStatus: QuotationStatus.Canceled, urgent: false },
|
data: { quotationStatus: QuotationStatus.Canceled, urgent: false },
|
||||||
})
|
})
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
await Promise.all(
|
await tx.notification.createMany({
|
||||||
res.map((v) =>
|
data: res.map((v) => ({
|
||||||
tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
||||||
detail: "รหัส / code : " + v.code + " Canceled",
|
detail: "รหัส / code : " + v.code + " Canceled",
|
||||||
receiverId: v.createdByUserId,
|
receiverId: v.createdByUserId,
|
||||||
registeredBranchId: v.registeredBranchId,
|
})),
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
});
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
),
|
tx.taskOrder.updateMany({
|
||||||
);
|
|
||||||
}),
|
|
||||||
tx.taskOrder
|
|
||||||
.updateManyAndReturn({
|
|
||||||
where: {
|
where: {
|
||||||
taskList: {
|
taskList: {
|
||||||
every: { taskStatus: TaskStatus.Canceled },
|
every: { taskStatus: TaskStatus.Canceled },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: { taskOrderStatus: TaskStatus.Canceled },
|
data: { taskOrderStatus: TaskStatus.Canceled },
|
||||||
})
|
|
||||||
.then(async (res) => {
|
|
||||||
await Promise.all(
|
|
||||||
res.map((v) =>
|
|
||||||
tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
|
||||||
detail: "รหัส / code : " + v.code + " Canceled",
|
|
||||||
receiverId: v.createdByUserId,
|
|
||||||
registeredBranchId: v.registeredBranchId,
|
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const token = await this.#getLineToken();
|
|
||||||
if (!token) return;
|
|
||||||
|
|
||||||
const textHead = "JWS ALERT:";
|
|
||||||
|
|
||||||
const textAlert = "ขอแจ้งให้ทราบว่าใบเสนอราคา";
|
|
||||||
const textAlert2 = "ได้ดำเนินการยกเลิกเรียบร้อยแล้ว";
|
|
||||||
const textAlert3 = "หากต้องการข้อมูลเพิ่มเติม กรุณาแจ้งให้ฝ่ายที่เกี่ยวข้องทราบ 🙏";
|
|
||||||
let finalTextWork = "";
|
|
||||||
let textData = "";
|
|
||||||
|
|
||||||
let dataCustomerId: string[] = [];
|
|
||||||
let dataUserId: string[] = [];
|
|
||||||
|
|
||||||
result.quotation.customerBranch.customer.branch.forEach((item) => {
|
|
||||||
if (!dataCustomerId?.includes(item.id) && item.userId) {
|
|
||||||
dataCustomerId.push(item.id);
|
|
||||||
dataUserId.push(item.userId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
finalTextWork = `เลขที่ใบเสนอราคา: ${result.code} ${result.quotation.workName}`;
|
|
||||||
|
|
||||||
textData = `${textHead}\n\n${textAlert}\n${finalTextWork}\n${textAlert2}\n\n${textAlert3}`;
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
to: dataUserId,
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: textData,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
await fetch("https://api.line.me/v2/bot/message/multicast", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -689,19 +585,13 @@ export class RequestDataActionController extends Controller {
|
||||||
data: { quotationStatus: QuotationStatus.Canceled, urgent: false },
|
data: { quotationStatus: QuotationStatus.Canceled, urgent: false },
|
||||||
})
|
})
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
await Promise.all(
|
await tx.notification.createMany({
|
||||||
res.map((v) =>
|
data: res.map((v) => ({
|
||||||
tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
||||||
detail: "รหัส / code : " + v.code + " Canceled",
|
detail: "รหัส / code : " + v.code + " Canceled",
|
||||||
receiverId: v.createdByUserId,
|
receiverId: v.createdByUserId,
|
||||||
registeredBranchId: v.registeredBranchId,
|
})),
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
});
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
}),
|
||||||
tx.taskOrder.updateMany({
|
tx.taskOrder.updateMany({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -784,83 +674,14 @@ export class RequestDataActionController extends Controller {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: { quotationStatus: QuotationStatus.ProcessComplete, urgent: false },
|
data: { quotationStatus: QuotationStatus.ProcessComplete, urgent: false },
|
||||||
include: {
|
|
||||||
customerBranch: {
|
|
||||||
include: {
|
|
||||||
customer: {
|
|
||||||
include: {
|
|
||||||
branch: {
|
|
||||||
where: { userId: { not: null } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
await Promise.all(
|
await tx.notification.createMany({
|
||||||
res.map((v) =>
|
data: res.map((v) => ({
|
||||||
tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
||||||
detail: "รหัส / code : " + v.code + " Completed",
|
detail: "รหัส / code : " + v.code + " Completed",
|
||||||
receiverId: v.createdByUserId,
|
receiverId: v.createdByUserId,
|
||||||
registeredBranchId: v.registeredBranchId,
|
})),
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const token = await this.#getLineToken();
|
|
||||||
if (!token) return;
|
|
||||||
|
|
||||||
const textHead = "JWS ALERT:";
|
|
||||||
|
|
||||||
const textAlert = "ขอแจ้งให้ทราบว่าใบเสนอราคา";
|
|
||||||
const textAlert2 = "ได้ดำเนินการเสร็จสิ้นทุกกระบวนการเรียบร้อยแล้ว";
|
|
||||||
const textAlert3 = "หากต้องการข้อมูลเพิ่มเติม กรุณาแจ้งให้ฝ่ายที่เกี่ยวข้องทราบ 🙏";
|
|
||||||
let finalTextWork = "";
|
|
||||||
let textData = "";
|
|
||||||
|
|
||||||
let dataCustomerId: string[] = [];
|
|
||||||
let textWorkList: string[] = [];
|
|
||||||
let dataUserId: string[] = [];
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
res.forEach((data, index) => {
|
|
||||||
data.customerBranch.customer.branch.forEach((item) => {
|
|
||||||
if (!dataCustomerId?.includes(item.id) && item.userId) {
|
|
||||||
dataCustomerId.push(item.id);
|
|
||||||
dataUserId.push(item.userId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
textWorkList.push(`${index + 1}. เลขที่ใบเสนอราคา ${data.code} ${data.workName}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
finalTextWork = textWorkList.join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
textData = `${textHead}\n\n${textAlert}\n${finalTextWork}\n${textAlert2}\n\n${textAlert3}`;
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
to: dataUserId,
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: textData,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
await fetch("https://api.line.me/v2/bot/message/multicast", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// dataRecord.push(record);
|
// dataRecord.push(record);
|
||||||
|
|
@ -1217,19 +1038,13 @@ export class RequestListController extends Controller {
|
||||||
data: { quotationStatus: QuotationStatus.Canceled, urgent: false },
|
data: { quotationStatus: QuotationStatus.Canceled, urgent: false },
|
||||||
})
|
})
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
await Promise.all(
|
await tx.notification.createMany({
|
||||||
res.map((v) =>
|
data: res.map((v) => ({
|
||||||
tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
||||||
detail: "รหัส / code : " + v.code + " Canceled",
|
detail: "รหัส / code : " + v.code + " Canceled",
|
||||||
receiverId: v.createdByUserId,
|
receiverId: v.createdByUserId,
|
||||||
registeredBranchId: v.registeredBranchId,
|
})),
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
});
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
}),
|
||||||
tx.taskOrder.updateMany({
|
tx.taskOrder.updateMany({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -1337,19 +1152,13 @@ export class RequestListController extends Controller {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
await Promise.all(
|
await tx.notification.createMany({
|
||||||
res.map((v) =>
|
data: res.map((v) => ({
|
||||||
tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
||||||
detail: "รหัส / code : " + v.code + " Completed",
|
detail: "รหัส / code : " + v.code + " Completed",
|
||||||
receiverId: v.createdByUserId,
|
receiverId: v.createdByUserId,
|
||||||
registeredBranchId: v.registeredBranchId,
|
})),
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
});
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const token = await this.#getLineToken();
|
const token = await this.#getLineToken();
|
||||||
if (!token) return;
|
if (!token) return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ export class TaskController extends Controller {
|
||||||
by: ["taskOrderStatus"],
|
by: ["taskOrderStatus"],
|
||||||
_count: true,
|
_count: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return task.reduce<Record<TaskOrderStatus, number>>(
|
return task.reduce<Record<TaskOrderStatus, number>>(
|
||||||
(a, c) => Object.assign(a, { [c.taskOrderStatus]: c._count }),
|
(a, c) => Object.assign(a, { [c.taskOrderStatus]: c._count }),
|
||||||
{
|
{
|
||||||
|
|
@ -265,12 +264,6 @@ export class TaskController extends Controller {
|
||||||
taskProduct?: { productId: string; discount?: number }[];
|
taskProduct?: { productId: string; discount?: number }[];
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if (body.taskList.length < 1 || !body.registeredBranchId)
|
|
||||||
throw new HttpError(
|
|
||||||
HttpStatus.BAD_REQUEST,
|
|
||||||
"Your created invalid task order",
|
|
||||||
"taskOrderInvalid",
|
|
||||||
);
|
|
||||||
return await prisma.$transaction(async (tx) => {
|
return await prisma.$transaction(async (tx) => {
|
||||||
const last = await tx.runningNo.upsert({
|
const last = await tx.runningNo.upsert({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -320,8 +313,8 @@ export class TaskController extends Controller {
|
||||||
if (updated.count !== taskList.length) {
|
if (updated.count !== taskList.length) {
|
||||||
throw new HttpError(
|
throw new HttpError(
|
||||||
HttpStatus.PRECONDITION_FAILED,
|
HttpStatus.PRECONDITION_FAILED,
|
||||||
"all request work to issue task order must be in ready state.",
|
"All request work to issue task order must be in ready state.",
|
||||||
"requestworkmustready",
|
"requestWorkMustReady",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await tx.institution.updateMany({
|
await tx.institution.updateMany({
|
||||||
|
|
@ -344,8 +337,7 @@ export class TaskController extends Controller {
|
||||||
where: { OR: taskList },
|
where: { OR: taskList },
|
||||||
});
|
});
|
||||||
|
|
||||||
return await tx.taskOrder
|
return await tx.taskOrder.create({
|
||||||
.create({
|
|
||||||
include: {
|
include: {
|
||||||
taskList: {
|
taskList: {
|
||||||
include: {
|
include: {
|
||||||
|
|
@ -408,17 +400,6 @@ export class TaskController extends Controller {
|
||||||
taskList: { create: taskList },
|
taskList: { create: taskList },
|
||||||
taskProduct: { create: taskProduct },
|
taskProduct: { create: taskProduct },
|
||||||
},
|
},
|
||||||
})
|
|
||||||
.then(async (v) => {
|
|
||||||
await prisma.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "ใบสั่งงานใหม่ / New Task Order",
|
|
||||||
detail: "รหัส / code : " + v.code,
|
|
||||||
registeredBranchId: v.registeredBranchId,
|
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return v;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -562,8 +543,6 @@ export class TaskController extends Controller {
|
||||||
title: "มีการส่งงาน / Task Submitted",
|
title: "มีการส่งงาน / Task Submitted",
|
||||||
detail: "รหัสใบสั่งงาน / Order : " + record.code,
|
detail: "รหัสใบสั่งงาน / Order : " + record.code,
|
||||||
receiverId: record.createdByUserId,
|
receiverId: record.createdByUserId,
|
||||||
registeredBranchId: record.registeredBranchId,
|
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -758,8 +737,6 @@ export class TaskActionController extends Controller {
|
||||||
title: "มีการส่งงาน / Task Submitted",
|
title: "มีการส่งงาน / Task Submitted",
|
||||||
detail: "รหัสใบสั่งงาน / Order : " + record.code,
|
detail: "รหัสใบสั่งงาน / Order : " + record.code,
|
||||||
receiverId: record.createdByUserId,
|
receiverId: record.createdByUserId,
|
||||||
registeredBranchId: record.registeredBranchId,
|
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
@ -792,8 +769,7 @@ export class TaskActionController extends Controller {
|
||||||
const code = `RI${year}${month}${last.value.toString().padStart(6, "0")}`;
|
const code = `RI${year}${month}${last.value.toString().padStart(6, "0")}`;
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
tx.taskOrder
|
tx.taskOrder.update({
|
||||||
.update({
|
|
||||||
where: { id: taskOrderId },
|
where: { id: taskOrderId },
|
||||||
data: {
|
data: {
|
||||||
urgent: false,
|
urgent: false,
|
||||||
|
|
@ -808,17 +784,6 @@ export class TaskActionController extends Controller {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
|
||||||
.then(async (record) => {
|
|
||||||
await tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "ใบงานเสร็จสิ้น / Task Complete",
|
|
||||||
detail: "รหัสใบสั่งงาน / Order : " + record.code,
|
|
||||||
receiverId: record.createdByUserId,
|
|
||||||
registeredBranchId: record.registeredBranchId,
|
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}),
|
}),
|
||||||
tx.requestWorkStepStatus.updateMany({
|
tx.requestWorkStepStatus.updateMany({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -923,33 +888,9 @@ export class TaskActionController extends Controller {
|
||||||
if (completeCheck) completed.push(item.id);
|
if (completeCheck) completed.push(item.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.requestData
|
await tx.requestData.updateMany({
|
||||||
.updateManyAndReturn({
|
|
||||||
where: { id: { in: completed } },
|
where: { id: { in: completed } },
|
||||||
include: {
|
|
||||||
quotation: {
|
|
||||||
select: {
|
|
||||||
registeredBranchId: true,
|
|
||||||
createdByUserId: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: { requestDataStatus: RequestDataStatus.Completed },
|
data: { requestDataStatus: RequestDataStatus.Completed },
|
||||||
})
|
|
||||||
.then(async (res) => {
|
|
||||||
await Promise.all(
|
|
||||||
res.map((v) =>
|
|
||||||
tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
|
||||||
detail: "รหัส / code : " + v.code + " Completed",
|
|
||||||
receiverId: v.quotation.createdByUserId,
|
|
||||||
registeredBranchId: v.quotation.registeredBranchId,
|
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
await tx.quotation
|
await tx.quotation
|
||||||
.updateManyAndReturn({
|
.updateManyAndReturn({
|
||||||
|
|
@ -990,19 +931,13 @@ export class TaskActionController extends Controller {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
await Promise.all(
|
await tx.notification.createMany({
|
||||||
res.map((v) =>
|
data: res.map((v) => ({
|
||||||
tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
title: "สถานะใบเสนอราคาเปลี่ยนแปลง / Quotation Status Updated",
|
||||||
detail: "รหัส / code : " + v.code + " Completed",
|
detail: "รหัส / code : " + v.code + " Completed",
|
||||||
receiverId: v.createdByUserId,
|
receiverId: v.createdByUserId,
|
||||||
registeredBranchId: v.registeredBranchId,
|
})),
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
});
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const token = await this.#getLineToken();
|
const token = await this.#getLineToken();
|
||||||
|
|
||||||
|
|
@ -1241,23 +1176,19 @@ export class UserTaskController extends Controller {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(async (v) => {
|
.then(async (v) => {
|
||||||
await tx.notification.create({
|
await tx.notification.createMany({
|
||||||
data: {
|
data: [
|
||||||
|
{
|
||||||
title: "สถานะใบส่งงานมีการเปลี่ยนแปลง / Order Status Changed",
|
title: "สถานะใบส่งงานมีการเปลี่ยนแปลง / Order Status Changed",
|
||||||
detail: "รหัสใบสั่งงาน / Order : " + v.code + " InProgress",
|
detail: "รหัสใบสั่งงาน / Order : " + v.code + " InProgress",
|
||||||
receiverId: v.createdByUserId,
|
receiverId: v.createdByUserId,
|
||||||
registeredBranchId: v.registeredBranchId,
|
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
},
|
||||||
});
|
{
|
||||||
await tx.notification.create({
|
|
||||||
data: {
|
|
||||||
title: "มีการรับงาน / Task Accepted",
|
title: "มีการรับงาน / Task Accepted",
|
||||||
detail: "รหัสใบสั่งงาน / Order : " + v.code,
|
detail: "รหัสใบสั่งงาน / Order : " + v.code,
|
||||||
receiverId: v.createdByUserId,
|
receiverId: v.createdByUserId,
|
||||||
registeredBranchId: v.registeredBranchId,
|
|
||||||
groupReceiver: { create: { name: "document_checker" } },
|
|
||||||
},
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
tx.task.updateMany({
|
tx.task.updateMany({
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import {
|
||||||
Security,
|
Security,
|
||||||
Tags,
|
Tags,
|
||||||
} from "tsoa";
|
} from "tsoa";
|
||||||
import config from "../config.json";
|
|
||||||
|
|
||||||
import prisma from "../db";
|
import prisma from "../db";
|
||||||
|
|
||||||
|
|
@ -54,7 +53,6 @@ function globalAllow(user: RequestWithUser["user"]) {
|
||||||
const listAllowed = ["system", "head_of_admin", "admin", "executive", "accountant"];
|
const listAllowed = ["system", "head_of_admin", "admin", "executive", "accountant"];
|
||||||
return user.roles?.some((v) => listAllowed.includes(v)) || false;
|
return user.roles?.some((v) => listAllowed.includes(v)) || false;
|
||||||
}
|
}
|
||||||
const VAT_DEFAULT = config.vat;
|
|
||||||
|
|
||||||
const permissionCond = createPermCondition(globalAllow);
|
const permissionCond = createPermCondition(globalAllow);
|
||||||
const permissionCheck = createPermCheck(globalAllow);
|
const permissionCheck = createPermCheck(globalAllow);
|
||||||
|
|
@ -85,14 +83,6 @@ type CreditNoteUpdate = {
|
||||||
@Route("api/v1/credit-note")
|
@Route("api/v1/credit-note")
|
||||||
@Tags("Credit Note")
|
@Tags("Credit Note")
|
||||||
export class CreditNoteController extends Controller {
|
export class CreditNoteController extends Controller {
|
||||||
async #getLineToken() {
|
|
||||||
if (!process.env.LINE_MESSAGING_API_TOKEN) {
|
|
||||||
console.warn("Line Webhook Activated but LINE_MESSAGING_API_TOKEN not set.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.env.LINE_MESSAGING_API_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get("stats")
|
@Get("stats")
|
||||||
@Security("keycloak")
|
@Security("keycloak")
|
||||||
async getCreditNoteStats(@Request() req: RequestWithUser, @Query() quotationId?: string) {
|
async getCreditNoteStats(@Request() req: RequestWithUser, @Query() quotationId?: string) {
|
||||||
|
|
@ -156,6 +146,7 @@ export class CreditNoteController extends Controller {
|
||||||
@Query() creditNoteStatus?: CreditNoteStatus,
|
@Query() creditNoteStatus?: CreditNoteStatus,
|
||||||
@Query() startDate?: Date,
|
@Query() startDate?: Date,
|
||||||
@Query() endDate?: Date,
|
@Query() endDate?: Date,
|
||||||
|
@Body() body?: {},
|
||||||
) {
|
) {
|
||||||
const where = {
|
const where = {
|
||||||
OR: queryOrNot<Prisma.CreditNoteWhereInput[]>(query, [
|
OR: queryOrNot<Prisma.CreditNoteWhereInput[]>(query, [
|
||||||
|
|
@ -217,8 +208,6 @@ export class CreditNoteController extends Controller {
|
||||||
const [result, total] = await prisma.$transaction([
|
const [result, total] = await prisma.$transaction([
|
||||||
prisma.creditNote.findMany({
|
prisma.creditNote.findMany({
|
||||||
where,
|
where,
|
||||||
take: pageSize,
|
|
||||||
skip: (page - 1) * pageSize,
|
|
||||||
include: {
|
include: {
|
||||||
quotation: {
|
quotation: {
|
||||||
include: {
|
include: {
|
||||||
|
|
@ -349,8 +338,9 @@ export class CreditNoteController extends Controller {
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
const price =
|
const price =
|
||||||
c.productService.pricePerUnit * (1 + (c.productService.vat > 0 ? VAT_DEFAULT : 0)) -
|
c.productService.pricePerUnit -
|
||||||
c.productService.discount;
|
c.productService.discount / c.productService.amount +
|
||||||
|
c.productService.vat / c.productService.amount;
|
||||||
|
|
||||||
if (serviceChargeStepCount && successCount) {
|
if (serviceChargeStepCount && successCount) {
|
||||||
return a + price - c.productService.product.serviceCharge * successCount;
|
return a + price - c.productService.product.serviceCharge * successCount;
|
||||||
|
|
@ -376,23 +366,14 @@ export class CreditNoteController extends Controller {
|
||||||
update: { value: { increment: 1 } },
|
update: { value: { increment: 1 } },
|
||||||
});
|
});
|
||||||
|
|
||||||
return await prisma.creditNote
|
return await prisma.creditNote.create({
|
||||||
.create({
|
|
||||||
include: {
|
include: {
|
||||||
requestWork: {
|
requestWork: {
|
||||||
include: {
|
include: {
|
||||||
request: true,
|
request: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
quotation: {
|
quotation: true,
|
||||||
include: {
|
|
||||||
customerBranch: {
|
|
||||||
include: {
|
|
||||||
customer: { include: { branch: { where: { userId: { not: null } } } } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
reason: body.reason,
|
reason: body.reason,
|
||||||
|
|
@ -411,55 +392,6 @@ export class CreditNoteController extends Controller {
|
||||||
},
|
},
|
||||||
quotationId: body.quotationId,
|
quotationId: body.quotationId,
|
||||||
},
|
},
|
||||||
})
|
|
||||||
.then(async (res) => {
|
|
||||||
const token = await this.#getLineToken();
|
|
||||||
if (!token) return;
|
|
||||||
|
|
||||||
const textHead = "JWS ALERT:";
|
|
||||||
|
|
||||||
const textAlert = "ขอแจ้งให้ทราบว่าใบลดหนี้";
|
|
||||||
const textAlert2 = "ได้ถูกสร้างขึ้นเรียบร้อยแล้ว";
|
|
||||||
const textAlert3 =
|
|
||||||
"หากท่านต้องการข้อมูลเพิ่มเติมหรือมีข้อสงสัยประการใด โปรดแจ้งให้ฝ่ายที่เกี่ยวข้องทราบ ทางเรายินดีให้ความช่วยเหลืออย่างเต็มที่ 🙏";
|
|
||||||
let finalTextWork = "";
|
|
||||||
let textData = "";
|
|
||||||
|
|
||||||
let dataCustomerId: string[] = [];
|
|
||||||
let dataUserId: string[] = [];
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
res.quotation.customerBranch.customer.branch.forEach((item) => {
|
|
||||||
if (!dataCustomerId?.includes(item.id) && item.userId) {
|
|
||||||
dataCustomerId.push(item.id);
|
|
||||||
dataUserId.push(item.userId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
finalTextWork = `จำนวนเงิน ${res.value.toFixed(2)} บาท `;
|
|
||||||
}
|
|
||||||
|
|
||||||
textData = `${textHead}\n\n${textAlert}\n${finalTextWork}${textAlert2}\n\n${textAlert3}`;
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
to: dataUserId,
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: textData,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
await fetch("https://api.line.me/v2/bot/message/multicast", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{ isolationLevel: Prisma.TransactionIsolationLevel.Serializable },
|
{ isolationLevel: Prisma.TransactionIsolationLevel.Serializable },
|
||||||
|
|
@ -542,8 +474,9 @@ export class CreditNoteController extends Controller {
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
const price =
|
const price =
|
||||||
c.productService.pricePerUnit * (1 + (c.productService.vat > 0 ? VAT_DEFAULT : 0)) -
|
c.productService.pricePerUnit -
|
||||||
c.productService.discount;
|
c.productService.discount / c.productService.amount +
|
||||||
|
c.productService.vat / c.productService.amount;
|
||||||
|
|
||||||
if (serviceChargeStepCount && successCount) {
|
if (serviceChargeStepCount && successCount) {
|
||||||
return a + price - c.productService.product.serviceCharge * successCount;
|
return a + price - c.productService.product.serviceCharge * successCount;
|
||||||
|
|
@ -640,14 +573,6 @@ export class CreditNoteActionController extends Controller {
|
||||||
return creditNoteData;
|
return creditNoteData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async #getLineToken() {
|
|
||||||
if (!process.env.LINE_MESSAGING_API_TOKEN) {
|
|
||||||
console.warn("Line Webhook Activated but LINE_MESSAGING_API_TOKEN not set.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.env.LINE_MESSAGING_API_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post("accept")
|
@Post("accept")
|
||||||
@Security("keycloak", MANAGE_ROLES)
|
@Security("keycloak", MANAGE_ROLES)
|
||||||
async acceptCreditNote(@Request() req: RequestWithUser, @Path() creditNoteId: string) {
|
async acceptCreditNote(@Request() req: RequestWithUser, @Path() creditNoteId: string) {
|
||||||
|
|
@ -666,8 +591,7 @@ export class CreditNoteActionController extends Controller {
|
||||||
@Body() body: { paybackStatus: PaybackStatus },
|
@Body() body: { paybackStatus: PaybackStatus },
|
||||||
) {
|
) {
|
||||||
await this.#checkPermission(req.user, creditNoteId);
|
await this.#checkPermission(req.user, creditNoteId);
|
||||||
return await prisma.creditNote
|
return await prisma.creditNote.update({
|
||||||
.update({
|
|
||||||
where: { id: creditNoteId },
|
where: { id: creditNoteId },
|
||||||
include: {
|
include: {
|
||||||
requestWork: {
|
requestWork: {
|
||||||
|
|
@ -675,15 +599,7 @@ export class CreditNoteActionController extends Controller {
|
||||||
request: true,
|
request: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
quotation: {
|
quotation: true,
|
||||||
include: {
|
|
||||||
customerBranch: {
|
|
||||||
include: {
|
|
||||||
customer: { include: { branch: { where: { userId: { not: null } } } } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
creditNoteStatus:
|
creditNoteStatus:
|
||||||
|
|
@ -691,55 +607,6 @@ export class CreditNoteActionController extends Controller {
|
||||||
paybackStatus: body.paybackStatus,
|
paybackStatus: body.paybackStatus,
|
||||||
paybackDate: body.paybackStatus === PaybackStatus.Done ? new Date() : undefined,
|
paybackDate: body.paybackStatus === PaybackStatus.Done ? new Date() : undefined,
|
||||||
},
|
},
|
||||||
})
|
|
||||||
.then(async (res) => {
|
|
||||||
const token = await this.#getLineToken();
|
|
||||||
if (!token) return;
|
|
||||||
|
|
||||||
const textHead = "JWS ALERT:";
|
|
||||||
|
|
||||||
const textAlert = "ทางเราขอแจ้งให้ทราบว่าการดำเนินการคืนเงินสำหรับใบลดหนี้";
|
|
||||||
const textAlert2 = "ได้รับการอนุมัติและเสร็จสมบูรณ์เรียบร้อยแล้ว";
|
|
||||||
const textAlert3 =
|
|
||||||
"หากท่านต้องการข้อมูลเพิ่มเติมหรือมีข้อสงสัยประการใด โปรดแจ้งให้ฝ่ายที่เกี่ยวข้องทราบ ทางเรายินดีให้ความช่วยเหลืออย่างเต็มที่ 🙏";
|
|
||||||
let finalTextWork = "";
|
|
||||||
let textData = "";
|
|
||||||
|
|
||||||
let dataCustomerId: string[] = [];
|
|
||||||
let textWorkList: string[] = [];
|
|
||||||
let dataUserId: string[] = [];
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
res.quotation.customerBranch.customer.branch.forEach((item) => {
|
|
||||||
if (!dataCustomerId?.includes(item.id) && item.userId) {
|
|
||||||
dataCustomerId.push(item.id);
|
|
||||||
dataUserId.push(item.userId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
finalTextWork = `จำนวนเงิน ${res.value.toFixed(2)} บาท `;
|
|
||||||
}
|
|
||||||
|
|
||||||
textData = `${textHead}\n\n${textAlert}\n${finalTextWork}${textAlert2}\n\n${textAlert3}`;
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
to: dataUserId,
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: textData,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
body.paybackStatus === PaybackStatus.Done
|
|
||||||
? await fetch("https://api.line.me/v2/bot/message/multicast", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
})
|
|
||||||
: undefined;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -430,18 +430,12 @@ export class DebitNoteController extends Controller {
|
||||||
|
|
||||||
const list = body.productServiceList.map((v, i) => {
|
const list = body.productServiceList.map((v, i) => {
|
||||||
const p = product.find((p) => p.id === v.productId)!;
|
const p = product.find((p) => p.id === v.productId)!;
|
||||||
|
const price = body.agentPrice ? p.agentPrice : p.price;
|
||||||
const vatIncluded = body.agentPrice ? p.agentPriceVatIncluded : p.vatIncluded;
|
const pricePerUnit = p.vatIncluded ? price / (1 + VAT_DEFAULT) : price;
|
||||||
|
const vat = p.calcVat
|
||||||
const originalPrice = body.agentPrice ? p.agentPrice : p.price;
|
? (pricePerUnit * (v.discount ? v.amount : 1) - (v.discount || 0)) *
|
||||||
const finalPrice = precisionRound(
|
VAT_DEFAULT *
|
||||||
originalPrice + (vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
(!v.discount ? v.amount : 1)
|
||||||
);
|
|
||||||
const pricePerUnit = finalPrice / (1 + VAT_DEFAULT);
|
|
||||||
const vat = (body.agentPrice ? p.agentPriceCalcVat : p.calcVat)
|
|
||||||
? ((pricePerUnit * (1 + VAT_DEFAULT) * v.amount - (v.discount || 0)) /
|
|
||||||
(1 + VAT_DEFAULT)) *
|
|
||||||
VAT_DEFAULT
|
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -464,13 +458,15 @@ export class DebitNoteController extends Controller {
|
||||||
|
|
||||||
const price = list.reduce(
|
const price = list.reduce(
|
||||||
(a, c) => {
|
(a, c) => {
|
||||||
const vat = c.vat ? VAT_DEFAULT : 0;
|
a.totalPrice = precisionRound(a.totalPrice + c.pricePerUnit * c.amount);
|
||||||
const price = c.pricePerUnit * c.amount * (1 + vat) - c.discount;
|
|
||||||
|
|
||||||
a.totalPrice = precisionRound(a.totalPrice + price / (1 + vat) + c.discount);
|
|
||||||
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
|
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
|
||||||
a.vat = precisionRound(a.vat + c.vat);
|
a.vat = precisionRound(a.vat + c.vat);
|
||||||
a.vatExcluded = c.vat === 0 ? precisionRound(a.vatExcluded + price) : a.vatExcluded;
|
a.vatExcluded =
|
||||||
|
c.vat === 0
|
||||||
|
? precisionRound(
|
||||||
|
a.vatExcluded + (c.pricePerUnit * c.amount - (c.discount || 0)) * VAT_DEFAULT,
|
||||||
|
)
|
||||||
|
: a.vatExcluded;
|
||||||
a.finalPrice = precisionRound(
|
a.finalPrice = precisionRound(
|
||||||
Math.max(a.totalPrice - a.totalDiscount + a.vat - (body.discount || 0), 0),
|
Math.max(a.totalPrice - a.totalDiscount + a.vat - (body.discount || 0), 0),
|
||||||
);
|
);
|
||||||
|
|
@ -677,18 +673,12 @@ export class DebitNoteController extends Controller {
|
||||||
}
|
}
|
||||||
const list = body.productServiceList.map((v, i) => {
|
const list = body.productServiceList.map((v, i) => {
|
||||||
const p = product.find((p) => p.id === v.productId)!;
|
const p = product.find((p) => p.id === v.productId)!;
|
||||||
|
const price = body.agentPrice ? p.agentPrice : p.price;
|
||||||
const vatIncluded = record.agentPrice ? p.agentPriceVatIncluded : p.vatIncluded;
|
const pricePerUnit = p.vatIncluded ? price / (1 + VAT_DEFAULT) : price;
|
||||||
|
const vat = p.calcVat
|
||||||
const originalPrice = record.agentPrice ? p.agentPrice : p.price;
|
? (pricePerUnit * (v.discount ? v.amount : 1) - (v.discount || 0)) *
|
||||||
const finalPrice = precisionRound(
|
VAT_DEFAULT *
|
||||||
originalPrice + (vatIncluded ? 0 : originalPrice * VAT_DEFAULT),
|
(!v.discount ? v.amount : 1)
|
||||||
);
|
|
||||||
const pricePerUnit = finalPrice / (1 + VAT_DEFAULT);
|
|
||||||
const vat = (record.agentPrice ? p.agentPriceCalcVat : p.calcVat)
|
|
||||||
? ((pricePerUnit * (1 + VAT_DEFAULT) * v.amount - (v.discount || 0)) /
|
|
||||||
(1 + VAT_DEFAULT)) *
|
|
||||||
VAT_DEFAULT
|
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -711,13 +701,15 @@ export class DebitNoteController extends Controller {
|
||||||
|
|
||||||
const price = list.reduce(
|
const price = list.reduce(
|
||||||
(a, c) => {
|
(a, c) => {
|
||||||
const vat = c.vat ? VAT_DEFAULT : 0;
|
a.totalPrice = precisionRound(a.totalPrice + c.pricePerUnit * c.amount);
|
||||||
const price = c.pricePerUnit * c.amount * (1 + vat) - c.discount;
|
|
||||||
|
|
||||||
a.totalPrice = precisionRound(a.totalPrice + price / (1 + vat) + c.discount);
|
|
||||||
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
|
a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
|
||||||
a.vat = precisionRound(a.vat + c.vat);
|
a.vat = precisionRound(a.vat + c.vat);
|
||||||
a.vatExcluded = c.vat === 0 ? precisionRound(a.vatExcluded + price) : a.vatExcluded;
|
a.vatExcluded =
|
||||||
|
c.vat === 0
|
||||||
|
? precisionRound(
|
||||||
|
a.vatExcluded + (c.pricePerUnit * c.amount - (c.discount || 0)) * VAT_DEFAULT,
|
||||||
|
)
|
||||||
|
: a.vatExcluded;
|
||||||
a.finalPrice = precisionRound(
|
a.finalPrice = precisionRound(
|
||||||
Math.max(a.totalPrice - a.totalDiscount + a.vat - (body.discount || 0), 0),
|
Math.max(a.totalPrice - a.totalDiscount + a.vat - (body.discount || 0), 0),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -613,7 +613,10 @@ export class LineController extends Controller {
|
||||||
@Query() endDate?: Date,
|
@Query() endDate?: Date,
|
||||||
) {
|
) {
|
||||||
const where = {
|
const where = {
|
||||||
OR: queryOrNot<Prisma.QuotationWhereInput[]>(query, [
|
OR:
|
||||||
|
query || pendingOnly
|
||||||
|
? [
|
||||||
|
...(queryOrNot<Prisma.QuotationWhereInput[]>(query, [
|
||||||
{ code: { contains: query, mode: "insensitive" } },
|
{ code: { contains: query, mode: "insensitive" } },
|
||||||
{ workName: { contains: query, mode: "insensitive" } },
|
{ workName: { contains: query, mode: "insensitive" } },
|
||||||
{
|
{
|
||||||
|
|
@ -628,7 +631,21 @@ export class LineController extends Controller {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]),
|
]) || []),
|
||||||
|
...(queryOrNot<Prisma.QuotationWhereInput[]>(!!pendingOnly, [
|
||||||
|
{
|
||||||
|
requestData: {
|
||||||
|
some: {
|
||||||
|
requestDataStatus: "Pending",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
requestData: { none: {} },
|
||||||
|
},
|
||||||
|
]) || []),
|
||||||
|
]
|
||||||
|
: undefined,
|
||||||
isDebitNote: false,
|
isDebitNote: false,
|
||||||
code,
|
code,
|
||||||
payCondition,
|
payCondition,
|
||||||
|
|
@ -650,22 +667,6 @@ export class LineController extends Controller {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
AND: pendingOnly
|
|
||||||
? {
|
|
||||||
OR: [
|
|
||||||
{
|
|
||||||
requestData: {
|
|
||||||
some: {
|
|
||||||
requestDataStatus: "Pending",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
requestData: { none: {} },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
...whereDateQuery(startDate, endDate),
|
...whereDateQuery(startDate, endDate),
|
||||||
} satisfies Prisma.QuotationWhereInput;
|
} satisfies Prisma.QuotationWhereInput;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
import prisma from "../db";
|
import prisma from "../db";
|
||||||
import config from "../config.json";
|
import config from "../config.json";
|
||||||
import { CustomerType, PayCondition } from "@prisma/client";
|
import { CustomerType, PayCondition } from "@prisma/client";
|
||||||
import { convertTemplate } from "../utils/string-template";
|
|
||||||
import { htmlToText } from "html-to-text";
|
|
||||||
import { JsonObject } from "@prisma/client/runtime/library";
|
|
||||||
import { precisionRound } from "../utils/arithmetic";
|
|
||||||
|
|
||||||
if (!process.env.FLOW_ACCOUNT_URL) throw new Error("Require FLOW_ACCOUNT_URL");
|
if (!process.env.FLOW_ACCOUNT_URL) throw new Error("Require FLOW_ACCOUNT_URL");
|
||||||
if (!process.env.FLOW_ACCOUNT_CLIENT_ID) throw new Error("Require FLOW_ACCOUNT_CLIENT_ID");
|
if (!process.env.FLOW_ACCOUNT_CLIENT_ID) throw new Error("Require FLOW_ACCOUNT_CLIENT_ID");
|
||||||
|
|
@ -236,29 +232,6 @@ const flowAccount = {
|
||||||
installments: true,
|
installments: true,
|
||||||
quotation: {
|
quotation: {
|
||||||
include: {
|
include: {
|
||||||
paySplit: true,
|
|
||||||
worker: {
|
|
||||||
select: {
|
|
||||||
employee: {
|
|
||||||
select: {
|
|
||||||
employeePassport: {
|
|
||||||
select: {
|
|
||||||
number: true,
|
|
||||||
},
|
|
||||||
orderBy: {
|
|
||||||
expireDate: "desc",
|
|
||||||
},
|
|
||||||
take: 1,
|
|
||||||
},
|
|
||||||
namePrefix: true,
|
|
||||||
firstName: true,
|
|
||||||
lastName: true,
|
|
||||||
firstNameEN: true,
|
|
||||||
lastNameEN: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
registeredBranch: {
|
registeredBranch: {
|
||||||
include: {
|
include: {
|
||||||
province: true,
|
province: true,
|
||||||
|
|
@ -289,58 +262,19 @@ const flowAccount = {
|
||||||
|
|
||||||
const quotation = data.quotation;
|
const quotation = data.quotation;
|
||||||
const customer = quotation.customerBranch;
|
const customer = quotation.customerBranch;
|
||||||
|
const product =
|
||||||
const summary = {
|
|
||||||
subTotal: 0,
|
|
||||||
discountAmount: 0,
|
|
||||||
vatableAmount: 0,
|
|
||||||
exemptAmount: 0,
|
|
||||||
vatAmount: 0,
|
|
||||||
grandTotal: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
const products = (
|
|
||||||
quotation.payCondition === PayCondition.BillFull ||
|
quotation.payCondition === PayCondition.BillFull ||
|
||||||
quotation.payCondition === PayCondition.Full
|
quotation.payCondition === PayCondition.Full
|
||||||
? quotation.productServiceList
|
? quotation.productServiceList
|
||||||
: quotation.productServiceList.filter((lhs) =>
|
: quotation.productServiceList.filter((lhs) =>
|
||||||
data.installments.some((rhs) => rhs.no === lhs.installmentNo),
|
data.installments.some((rhs) => rhs.no === lhs.installmentNo),
|
||||||
)
|
);
|
||||||
).map((v) => {
|
|
||||||
// TODO: Use product's VAT field (not implemented) instead.
|
|
||||||
const VAT_RATE = VAT_DEFAULT;
|
|
||||||
|
|
||||||
summary.subTotal +=
|
|
||||||
precisionRound(v.pricePerUnit * (1 + (v.vat > 0 ? VAT_RATE : 0))) * v.amount;
|
|
||||||
summary.discountAmount += v.discount;
|
|
||||||
|
|
||||||
const total =
|
|
||||||
precisionRound(v.pricePerUnit * (1 + (v.vat > 0 ? VAT_RATE : 0))) * v.amount -
|
|
||||||
(v.discount ?? 0);
|
|
||||||
|
|
||||||
if (v.vat > 0) {
|
|
||||||
summary.vatableAmount += precisionRound(total / (1 + VAT_RATE));
|
|
||||||
summary.vatAmount += v.vat;
|
|
||||||
} else {
|
|
||||||
summary.exemptAmount += total;
|
|
||||||
}
|
|
||||||
|
|
||||||
summary.grandTotal += total;
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: ProductAndServiceType.ProductNonInv,
|
|
||||||
name: v.product.name,
|
|
||||||
pricePerUnit: precisionRound(v.pricePerUnit),
|
|
||||||
quantity: v.amount,
|
|
||||||
discountAmount: v.discount,
|
|
||||||
vatRate: v.vat === 0 ? 0 : Math.round(VAT_RATE * 100),
|
|
||||||
total,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
contactCode: customer.code,
|
contactCode: customer.code,
|
||||||
contactName: customer.contactName || "-",
|
contactName:
|
||||||
|
(customer.customer.customerType === CustomerType.PERS
|
||||||
|
? [customer.firstName, customer.lastName].join(" ").trim()
|
||||||
|
: customer.registerName) || "-",
|
||||||
contactAddress: [
|
contactAddress: [
|
||||||
customer.address,
|
customer.address,
|
||||||
!!customer.moo ? "หมู่ " + customer.moo : null,
|
!!customer.moo ? "หมู่ " + customer.moo : null,
|
||||||
|
|
@ -349,10 +283,11 @@ const flowAccount = {
|
||||||
(customer.province?.id === "10" ? "แขวง" : "อำเภอ") + customer.subDistrict?.name,
|
(customer.province?.id === "10" ? "แขวง" : "อำเภอ") + customer.subDistrict?.name,
|
||||||
(customer.province?.id === "10" ? "เขต" : "ตำบล") + customer.district?.name,
|
(customer.province?.id === "10" ? "เขต" : "ตำบล") + customer.district?.name,
|
||||||
"จังหวัด" + customer.province?.name,
|
"จังหวัด" + customer.province?.name,
|
||||||
|
customer.subDistrict?.zipCode,
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(" "),
|
.join(" "),
|
||||||
contactTaxId: customer.citizenId || customer.legalPersonNo || "-",
|
contactTaxId: customer.citizenId || customer.code,
|
||||||
contactBranch:
|
contactBranch:
|
||||||
(customer.customer.customerType === CustomerType.PERS
|
(customer.customer.customerType === CustomerType.PERS
|
||||||
? [customer.firstName, customer.lastName].join(" ").trim()
|
? [customer.firstName, customer.lastName].join(" ").trim()
|
||||||
|
|
@ -370,35 +305,36 @@ const flowAccount = {
|
||||||
isVat: true,
|
isVat: true,
|
||||||
|
|
||||||
useReceiptDeduction: false,
|
useReceiptDeduction: false,
|
||||||
useInlineVat: true,
|
|
||||||
|
|
||||||
discounPercentage: 0,
|
discounPercentage: 0,
|
||||||
discountAmount: quotation.totalDiscount,
|
discountAmount: quotation.totalDiscount,
|
||||||
|
|
||||||
subTotal: summary.subTotal,
|
subTotal:
|
||||||
totalAfterDiscount: summary.subTotal - summary.discountAmount,
|
quotation.payCondition === "BillSplitCustom" || quotation.payCondition === "SplitCustom"
|
||||||
vatableAmount: summary.vatableAmount,
|
? 0
|
||||||
exemptAmount: summary.exemptAmount,
|
: quotation.totalPrice,
|
||||||
vatAmount: summary.vatAmount,
|
totalAfterDiscount:
|
||||||
grandTotal: summary.grandTotal,
|
quotation.payCondition === "BillSplitCustom" || quotation.payCondition === "SplitCustom"
|
||||||
|
? 0
|
||||||
|
: quotation.finalPrice,
|
||||||
|
vatAmount:
|
||||||
|
quotation.payCondition === "BillSplitCustom" || quotation.payCondition === "SplitCustom"
|
||||||
|
? 0
|
||||||
|
: quotation.vat,
|
||||||
|
grandTotal:
|
||||||
|
quotation.payCondition === "BillSplitCustom" || quotation.payCondition === "SplitCustom"
|
||||||
|
? data.installments.reduce((a, c) => a + c.amount, 0)
|
||||||
|
: quotation.finalPrice,
|
||||||
|
|
||||||
remarks: htmlToText(
|
items: product.map((v) => ({
|
||||||
convertTemplate(quotation.remark ?? "", {
|
type: ProductAndServiceType.ProductNonInv,
|
||||||
"quotation-payment": {
|
name: v.product.name,
|
||||||
paymentType: quotation?.payCondition || "Full",
|
pricePerUnit: v.pricePerUnit,
|
||||||
amount: quotation.finalPrice,
|
quantity: v.amount,
|
||||||
installments: quotation?.paySplit,
|
discountAmount: v.discount,
|
||||||
},
|
total: (v.pricePerUnit - (v.discount || 0)) * v.amount + v.vat,
|
||||||
"quotation-labor": {
|
vatRate: v.vat === 0 ? 0 : Math.round(VAT_DEFAULT * 100),
|
||||||
name: quotation.worker.map(
|
})),
|
||||||
(v, i) =>
|
|
||||||
`${i + 1}. ` +
|
|
||||||
`${v.employee.employeePassport.length !== 0 ? v.employee.employeePassport[0].number + "_" : ""}${v.employee.namePrefix}. ${v.employee.firstNameEN ? `${v.employee.firstNameEN} ${v.employee.lastNameEN}` : `${v.employee.firstName} ${v.employee.lastName}`} `.toUpperCase(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
items: products,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return await flowAccountAPI.createReceipt(payload, false);
|
return await flowAccountAPI.createReceipt(payload, false);
|
||||||
|
|
@ -411,219 +347,6 @@ const flowAccount = {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
// flowAccount GET Product list
|
|
||||||
async getProducts() {
|
|
||||||
const { token } = await flowAccountAPI.auth();
|
|
||||||
|
|
||||||
const res = await fetch(api + "/products", {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
["Content-Type"]: `application/json`,
|
|
||||||
["Authorization"]: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
ok: res.ok,
|
|
||||||
status: res.status,
|
|
||||||
body: await res.json(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
// flowAccount GET Product by id
|
|
||||||
async getProductsById(recordId: string) {
|
|
||||||
const { token } = await flowAccountAPI.auth();
|
|
||||||
|
|
||||||
const res = await fetch(api + `/products/${recordId}`, {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
["Content-Type"]: `application/json`,
|
|
||||||
["Authorization"]: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await res.json();
|
|
||||||
|
|
||||||
return {
|
|
||||||
ok: res.ok,
|
|
||||||
status: res.status,
|
|
||||||
list: data.data.list,
|
|
||||||
total: data.data.total,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
// flowAccount POST create Product
|
|
||||||
async createProducts(code: string, body: JsonObject) {
|
|
||||||
const { token } = await flowAccountAPI.auth();
|
|
||||||
|
|
||||||
const commonBody = {
|
|
||||||
productStructureType: null,
|
|
||||||
type: 3,
|
|
||||||
name: body.name,
|
|
||||||
sellDescription: body.detail,
|
|
||||||
sellVatType: 3,
|
|
||||||
buyPrice: body.serviceCharge,
|
|
||||||
buyVatType: body.serviceChargeVatIncluded ? 1 : 3,
|
|
||||||
buyDescription: body.detail,
|
|
||||||
};
|
|
||||||
|
|
||||||
const createProduct = async (name: string, price: any, vatIncluded: boolean) => {
|
|
||||||
try {
|
|
||||||
const res = await fetch(`${api}/products`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
...commonBody,
|
|
||||||
name,
|
|
||||||
sellPrice: price,
|
|
||||||
sellVatType: vatIncluded ? 1 : 3,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) throw new Error(`HTTP ${res.status}: Failed to create product`);
|
|
||||||
|
|
||||||
const json = await res.json().catch(() => {
|
|
||||||
throw new Error("Invalid JSON response from FlowAccount API");
|
|
||||||
});
|
|
||||||
|
|
||||||
return json?.data?.list?.[0]?.id ?? null;
|
|
||||||
} catch (err) {
|
|
||||||
console.error("createProduct error:", err);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const deleteProduct = async (id: string) => {
|
|
||||||
try {
|
|
||||||
await fetch(`${api}/products/${id}`, {
|
|
||||||
method: "DELETE",
|
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Rollback delete failed:", err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const [sellResult, agentResult] = await Promise.allSettled([
|
|
||||||
createProduct(`${code} ${body.name}`, body.price, /true/.test(`${body.vatIncluded}`)),
|
|
||||||
createProduct(
|
|
||||||
`${code} ${body.name} (ราคาตัวแทน)`,
|
|
||||||
body.agentPrice,
|
|
||||||
/true/.test(`${body.agentPriceVatIncluded}`),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const sellId = sellResult.status === "fulfilled" ? sellResult.value : null;
|
|
||||||
const agentId = agentResult.status === "fulfilled" ? agentResult.value : null;
|
|
||||||
|
|
||||||
// --- validation ---
|
|
||||||
if (!sellId && !agentId) {
|
|
||||||
throw new Error("FlowAccountProductError.BOTH_CREATION_FAILED");
|
|
||||||
}
|
|
||||||
if (!sellId && agentId) {
|
|
||||||
await deleteProduct(agentId);
|
|
||||||
throw new Error("FlowAccountProductError.SELL_PRICE_CREATION_FAILED");
|
|
||||||
}
|
|
||||||
if (sellId && !agentId) {
|
|
||||||
await deleteProduct(sellId);
|
|
||||||
throw new Error("FlowAccountProductError.AGENT_PRICE_CREATION_FAILED");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
status: 200,
|
|
||||||
data: {
|
|
||||||
productIdSellPrice: sellId,
|
|
||||||
productIdAgentPrice: agentId,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
// flowAccount PUT edit Product
|
|
||||||
async editProducts(sellPriceId: String, agentPriceId: String, body: JsonObject) {
|
|
||||||
const { token } = await flowAccountAPI.auth();
|
|
||||||
|
|
||||||
const commonBody = {
|
|
||||||
productStructureType: null,
|
|
||||||
type: 3,
|
|
||||||
name: body.name,
|
|
||||||
sellDescription: body.detail,
|
|
||||||
sellVatType: 3,
|
|
||||||
buyPrice: body.serviceCharge,
|
|
||||||
buyVatType: body.serviceChargeVatIncluded ? 1 : 3,
|
|
||||||
buyDescription: body.detail,
|
|
||||||
};
|
|
||||||
|
|
||||||
const editProduct = async (id: String, name: String, price: any, vatIncluded: boolean) => {
|
|
||||||
try {
|
|
||||||
const res = await fetch(api + `/products/${id}`, {
|
|
||||||
method: "PUT",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
...commonBody,
|
|
||||||
name: name,
|
|
||||||
sellPrice: price,
|
|
||||||
sellVatType: vatIncluded ? 1 : 3,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
throw new Error(`Request failed with status ${res.status} ${res}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let json: any = null;
|
|
||||||
try {
|
|
||||||
json = await res.json();
|
|
||||||
} catch {
|
|
||||||
throw new Error("Response is not valid JSON");
|
|
||||||
}
|
|
||||||
|
|
||||||
return json?.data?.list?.[0]?.id ?? null;
|
|
||||||
} catch (err) {
|
|
||||||
console.error("createProduct error:", err);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
editProduct(
|
|
||||||
sellPriceId,
|
|
||||||
`${body.code} ${body.name}`,
|
|
||||||
body.price,
|
|
||||||
/true/.test(`${body.vatIncluded}`),
|
|
||||||
),
|
|
||||||
editProduct(
|
|
||||||
agentPriceId,
|
|
||||||
`${body.code} ${body.name} (ราคาตัวแทน)`,
|
|
||||||
body.agentPrice,
|
|
||||||
/true/.test(`${body.agentPriceVatIncluded}`),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
|
|
||||||
// flowAccount DELETE Product
|
|
||||||
async deleteProduct(recordId: string) {
|
|
||||||
const { token } = await flowAccountAPI.auth();
|
|
||||||
|
|
||||||
const res = await fetch(api + `/products/${recordId}`, {
|
|
||||||
method: "DELETE",
|
|
||||||
headers: {
|
|
||||||
["Authorization"]: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
ok: res.ok,
|
|
||||||
status: res.status,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default flowAccount;
|
export default flowAccount;
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
export function formatNumberDecimal(num: number, point: number = 2): string {
|
|
||||||
return (num || 0).toLocaleString("eng", {
|
|
||||||
minimumFractionDigits: point,
|
|
||||||
maximumFractionDigits: point,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const templates = {
|
|
||||||
"quotation-labor": {
|
|
||||||
converter: (context?: { name: string[] }) => {
|
|
||||||
return context?.name.join("<br />") || "";
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"quotation-payment": {
|
|
||||||
converter: (context?: {
|
|
||||||
paymentType: "Full" | "Split" | "SplitCustom" | "BillFull" | "BillSplit" | "BillSplitCustom";
|
|
||||||
|
|
||||||
amount?: number;
|
|
||||||
installments?: {
|
|
||||||
no: number;
|
|
||||||
amount: number;
|
|
||||||
}[];
|
|
||||||
}) => {
|
|
||||||
if (context?.paymentType === "Full") {
|
|
||||||
return [
|
|
||||||
"**** เงื่อนไขเพิ่มเติม",
|
|
||||||
"- เงื่อนไขการชำระเงิน แบบเต็มจำนวน",
|
|
||||||
` จำนวน ${formatNumberDecimal(context?.amount || 0, 2)}`,
|
|
||||||
].join("<br/>");
|
|
||||||
} else {
|
|
||||||
return [
|
|
||||||
"**** เงื่อนไขเพิ่มเติม",
|
|
||||||
`- เงื่อนไขการชำระเงิน แบบแบ่งจ่าย${context?.paymentType === "SplitCustom" ? " กำหนดเอง " : " "}${context?.installments?.length} งวด`,
|
|
||||||
...(context?.installments?.map(
|
|
||||||
(v) => ` งวดที่ ${v.no} จำนวน ${formatNumberDecimal(v.amount, 2)}`,
|
|
||||||
) || []),
|
|
||||||
].join("<br />");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
type Template = typeof templates;
|
|
||||||
type TemplateName = keyof Template;
|
|
||||||
type TemplateContext = {
|
|
||||||
[key in TemplateName]?: Parameters<Template[key]["converter"]>[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
export function convertTemplate(
|
|
||||||
text: string,
|
|
||||||
context?: TemplateContext,
|
|
||||||
templateUse?: TemplateName[],
|
|
||||||
) {
|
|
||||||
let ret = text;
|
|
||||||
|
|
||||||
for (const [name, template] of Object.entries(templates)) {
|
|
||||||
if (templateUse && !templateUse.includes(name as TemplateName)) continue;
|
|
||||||
ret = ret.replace(
|
|
||||||
new RegExp("\\#\\[" + name.replaceAll("-", "\\-") + "\\]", "g"),
|
|
||||||
typeof template.converter === "function"
|
|
||||||
? template.converter(context?.[name as TemplateName] as any)
|
|
||||||
: template.converter,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
@ -62,8 +62,7 @@ export async function initThailandAreaDatabase() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.$transaction(
|
await prisma.$transaction(async (tx) => {
|
||||||
async (tx) => {
|
|
||||||
const meta = {
|
const meta = {
|
||||||
createdBy: null,
|
createdBy: null,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
|
|
@ -141,11 +140,7 @@ export async function initThailandAreaDatabase() {
|
||||||
.execute();
|
.execute();
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
},
|
});
|
||||||
{
|
|
||||||
timeout: 15_000,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("[INFO]: Sync thailand province, district and subdistrict, OK.");
|
console.log("[INFO]: Sync thailand province, district and subdistrict, OK.");
|
||||||
}
|
}
|
||||||
|
|
@ -175,8 +170,7 @@ export async function initEmploymentOffice() {
|
||||||
|
|
||||||
const list = await prisma.province.findMany();
|
const list = await prisma.province.findMany();
|
||||||
|
|
||||||
await prisma.$transaction(
|
await prisma.$transaction(async (tx) => {
|
||||||
async (tx) => {
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
list
|
list
|
||||||
.map(async (province) => {
|
.map(async (province) => {
|
||||||
|
|
@ -236,11 +230,7 @@ export async function initEmploymentOffice() {
|
||||||
})
|
})
|
||||||
.flat(),
|
.flat(),
|
||||||
);
|
);
|
||||||
},
|
});
|
||||||
{
|
|
||||||
timeout: 15_000,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("[INFO]: Sync employment office, OK.");
|
console.log("[INFO]: Sync employment office, OK.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue