Compare commits

...

19 Commits

Author SHA1 Message Date
ahasani d526f6ed2c feat: enhance consumer selection to include partner details for individual and legal types 2026-05-19 16:11:59 +03:30
ahasani 62b659246f feat: implement Redis caching for business activities and consumers
- Added Redis caching to BusinessActivitiesService for findAll and findOne methods.
- Integrated Redis caching in BusinessActivityComplexesService for findAll and findOne methods.
- Enhanced ConsumersService with Redis caching for findAll and findOne methods.
- Introduced cache invalidation for partner consumers and business activities.
- Created RedisKeyMaker utility for generating cache keys for consumers, partners, and POS.
- Implemented cache invalidation services for partners and POS.
- Added Redis service methods for JSON handling and key deletion by patterns.
- Updated goods service to include caching and invalidation for goods list.
- Introduced DTO for updating goods.
2026-05-19 15:40:45 +03:30
ahasani c5c522f69c set redis 2026-05-19 09:14:30 +03:30
ahasani 758bb03a26 feat: add update password functionality and DTO for partner service 2026-05-18 13:20:33 +03:30
ahasani 23ae3556de feat: implement consumer info update and password change functionality with DTOs 2026-05-18 10:53:58 +03:30
ahasani 12b11cc238 set vat to sku 2026-05-17 12:04:30 +03:30
ahasani 2d13a8bd9c update 2026-05-16 23:58:59 +03:30
ahasani 2a2c020627 refactor: update Dockerfile cache identifiers and clean up console logs across multiple services 2026-05-16 18:00:08 +03:30
ahasani ba3c544ff8 feat: enhance sale invoices filtering with additional fields and refactor findAll method 2026-05-16 16:12:19 +03:30
ahasani 5baf5bfea6 feat: enhance business activities and sale invoices handling with new query constants and pagination support 2026-05-16 14:49:23 +03:30
ahasani 83e7c26133 update 2026-05-11 20:18:03 +03:30
ahasani 1b26c515c0 update 2026-05-11 20:15:31 +03:30
ahasani 2a4e778c31 feat: enhance authentication flow with device info and optional POS flag in login DTO 2026-05-11 19:09:04 +03:30
ahasani 5e6bd33cdd feat: implement inquiry, send, retry, and revoke actions for sales invoices; enhance query constants and service structure 2026-05-10 19:56:05 +03:30
ahasani 9a76880b1d update dockerfile 2026-05-10 15:15:56 +03:30
ahasani c53eb2dba3 fix: update pnpm install commands to include only-built-dependencies option 2026-05-10 15:07:05 +03:30
ahasani 578e445917 update docker file 2026-05-10 14:56:00 +03:30
ahasani a1e8f40417 feat: enhance sales invoice functionality with inquiry, send, retry, and revoke actions 2026-05-10 14:14:01 +03:30
ahasani afa83895a2 Refactor code structure for improved readability and maintainability 2026-05-10 09:44:49 +03:30
99 changed files with 4166 additions and 2741 deletions
+5
View File
@@ -16,6 +16,11 @@ PORT="5002"
DB_ROOT_PASSWORD="root_password" DB_ROOT_PASSWORD="root_password"
NODE_ENV="production" NODE_ENV="production"
REDIS_HOST="redis"
REDIS_PORT="6379"
REDIS_DB="0"
REDIS_PASSWORD=""
ARVANCLOUD_ENDPOINT=https://s3.ir-thr-at1.arvanstorage.com ARVANCLOUD_ENDPOINT=https://s3.ir-thr-at1.arvanstorage.com
-18
View File
@@ -1,18 +0,0 @@
/*
Warnings:
- Added the required column `raw_request_payload` to the `sale_invoice_tsp_attempts` table without a default value. This is not possible if the table is not empty.
*/
-- DropForeignKey
ALTER TABLE `sale_invoice_tsp_attempts` DROP FOREIGN KEY `sale_invoice_tsp_attempts_invoice_id_fkey`;
-- DropIndex
DROP INDEX `sale_invoice_tsp_attempts_invoice_id_key` ON `sale_invoice_tsp_attempts`;
-- AlterTable
ALTER TABLE `sale_invoice_tsp_attempts` ADD COLUMN `raw_request_payload` JSON NOT NULL,
ADD COLUMN `raw_response_payload` JSON NULL;
-- AddForeignKey
ALTER TABLE `customer_legal` ADD CONSTRAINT `customer_legal_business_activity_id_fkey` FOREIGN KEY (`business_activity_id`) REFERENCES `business_activities`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
+27
View File
@@ -102,3 +102,30 @@ Operational guide for AI/coding agents working in `consumer_api`.
- Duplicate FK error seen in this repo: `sales_invoices_ref_id_fkey` (MySQL 1826). Recheck migration SQL for repeated `ADD CONSTRAINT` statements before rerun. - Duplicate FK error seen in this repo: `sales_invoices_ref_id_fkey` (MySQL 1826). Recheck migration SQL for repeated `ADD CONSTRAINT` statements before rerun.
- Drift that repeatedly showed in this project: missing FK/unique on `sale_invoice_tsp_attempts.invoice_id`. Validate both schema and migration SQL produce the same final state. - Drift that repeatedly showed in this project: missing FK/unique on `sale_invoice_tsp_attempts.invoice_id`. Validate both schema and migration SQL produce the same final state.
- `prisma migrate status` may show up-to-date while `migrate dev` still detects drift (shadow DB/application history issue); treat `migrate dev` output as source of truth for fixing local history. - `prisma migrate status` may show up-to-date while `migrate dev` still detects drift (shadow DB/application history issue); treat `migrate dev` output as source of truth for fixing local history.
## Redis Cache Conventions (May 2026)
- Use `RedisKeyMaker` in `src/common/utils/redis-key-maker.util.ts` for all cache keys and wildcard patterns; do not inline key strings in services.
- Keep invalidation domain-based (for example `src/modules/admin/guilds/cache/*`, `src/modules/admin/partners/cache/*`, `src/modules/pos/cache/*`) and avoid duplicating delete logic across modules.
- For list APIs that are expensive or frequently read, prefer read-through cache with TTL and invalidation on every related write path.
- For entity endpoints, use list + detail split:
- list key(s): invalidated broadly on writes,
- detail key(s): invalidated per entity id.
- Partner domain rules:
- Shared partner cache namespace is `partners:*` (not admin-prefixed) because writes occur in both `admin/partners` and `partners` modules.
- Use shared invalidation service `src/modules/partners/cache/partners-cache-invalidation.service.ts` from both admin and partner write paths.
- Invalidate `partners:list` and `partners:{id}:detail` on partner create/update/delete and license-affecting writes.
- Invalidate partner license caches (activated-licenses list, charge-transactions list/detail) via the shared invalidation service.
- POS goods rules:
- Cache key shape is BA + guild scoped (`pos:ba:{businessActivityId}:guild:{guildId}:goods:list`) because results combine guild-default and BA-owned goods.
- Invalidate POS goods cache by guild when admin guild goods/category/sku changes.
- Invalidate POS goods cache by business activity when consumer BA goods create/update/delete.
- Consumer/Partner hierarchy rules:
- Consumer profile cache key: `consumers:{consumerId}:info`.
- Partner-consumer profile cache key: `partners:{partnerId}:consumers:{consumerId}:info`.
- On partner-consumer single read, write both keys when practical to share warm cache across modules.
- On consumer info update or partner-consumer update, invalidate both consumer and partner-consumer profile keys.
- For business activities, invalidate both list and detail layers; child updates may invalidate parent single cache when parent aggregates depend on child state.
- Wildcard invalidation implementation:
- Use `RedisService.deleteByPattern` / `RedisService.deleteByPatterns` for all pattern deletes.
- Do not implement ad-hoc scan/delete loops inside domain services.
- Pattern deletion uses `SCAN` + pipelined `DEL`; multi-pattern deletes run in parallel.
+10 -5
View File
@@ -1,18 +1,23 @@
FROM node:22-slim AS base FROM node:22-slim AS base
WORKDIR /app WORKDIR /app
ARG NPM_REGISTRY=https://registry.npmjs.org/ ARG NPM_REGISTRY=https://hub.megan.ir/npm/
ENV NPM_CONFIG_REGISTRY=${NPM_REGISTRY} ENV NPM_CONFIG_REGISTRY=${NPM_REGISTRY}
ENV npm_config_registry=${NPM_REGISTRY} ENV npm_config_registry=${NPM_REGISTRY}
ENV PNPM_HOME="/pnpm" ENV PNPM_HOME="/pnpm"
ENV PNPM_STORE_DIR="/pnpm/store"
ENV PATH="${PNPM_HOME}:${PATH}" ENV PATH="${PNPM_HOME}:${PATH}"
ENV COREPACK_NPM_REGISTRY=${NPM_REGISTRY}
ARG PNPM_VERSION=10.17.1
RUN corepack enable && npm config set registry ${NPM_REGISTRY} RUN npm config set registry ${NPM_REGISTRY} \
&& npm install -g pnpm@${PNPM_VERSION}
FROM base AS build FROM base AS build
COPY package.json pnpm-lock.yaml ./ COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile RUN --mount=type=cache,id=pnpm-store-build,sharing=locked,target=/pnpm/store \
pnpm install --frozen-lockfile
COPY . . COPY . .
ENV PRISMA_CLIENT_ENGINE_TYPE=binary ENV PRISMA_CLIENT_ENGINE_TYPE=binary
@@ -21,8 +26,8 @@ RUN pnpm run build
FROM base AS prod-deps FROM base AS prod-deps
COPY package.json pnpm-lock.yaml ./ COPY package.json pnpm-lock.yaml ./
RUN pnpm install --prod --frozen-lockfile \ RUN --mount=type=cache,id=pnpm-store-prod,sharing=locked,target=/pnpm/store \
&& pnpm store prune \ pnpm install --prod --frozen-lockfile \
&& rm -rf /root/.npm /root/.cache && rm -rf /root/.npm /root/.cache
FROM node:22-slim AS runtime FROM node:22-slim AS runtime
+66 -40
View File
@@ -25,6 +25,24 @@ services:
networks: networks:
- psp_consumer_network - psp_consumer_network
redis:
image: redis:7-alpine
platform: ${DOCKER_PLATFORM:-linux/amd64}
container_name: psp_consumer_api_redis
restart: unless-stopped
command: redis-server --appendonly yes
ports:
- "${REDIS_PORT:-6379}:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 15s
timeout: 5s
retries: 5
networks:
- psp_consumer_network
api: api:
platform: ${DOCKER_PLATFORM:-linux/amd64} platform: ${DOCKER_PLATFORM:-linux/amd64}
build: build:
@@ -51,6 +69,8 @@ services:
depends_on: depends_on:
database: database:
condition: service_healthy condition: service_healthy
redis:
condition: service_healthy
environment: environment:
NODE_ENV: ${NODE_ENV:-production} NODE_ENV: ${NODE_ENV:-production}
PORT: ${PORT} PORT: ${PORT}
@@ -65,6 +85,10 @@ services:
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN} JWT_EXPIRES_IN: ${JWT_EXPIRES_IN}
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:5000,http://127.0.0.1:5000} CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:5000,http://127.0.0.1:5000}
OTP_STATIC_CODE: ${OTP_STATIC_CODE} # From .env OTP_STATIC_CODE: ${OTP_STATIC_CODE} # From .env
REDIS_HOST: ${REDIS_HOST:-redis}
REDIS_PORT: ${REDIS_PORT:-6379}
REDIS_DB: ${REDIS_DB:-0}
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
ports: ports:
- "${PORT:-5002}:5002" - "${PORT:-5002}:5002"
read_only: true read_only: true
@@ -91,50 +115,52 @@ services:
# retries: 3 # retries: 3
# start_period: 10s # start_period: 10s
seed: # seed:
platform: ${DOCKER_PLATFORM:-linux/amd64} # platform: ${DOCKER_PLATFORM:-linux/amd64}
build: # build:
context: . # context: .
dockerfile: Dockerfile # dockerfile: Dockerfile
target: build # target: build
args: # args:
NODE_ENV: ${NODE_ENV:-production} # NODE_ENV: ${NODE_ENV:-production}
PORT: ${PORT} # PORT: ${PORT}
DATABASE_NAME: ${DATABASE_NAME} # DATABASE_NAME: ${DATABASE_NAME}
DATABASE_USER: ${DATABASE_USER} # DATABASE_USER: ${DATABASE_USER}
DATABASE_PASSWORD: ${DATABASE_PASSWORD} # DATABASE_PASSWORD: ${DATABASE_PASSWORD}
DATABASE_PORT: ${DATABASE_PORT} # DATABASE_PORT: ${DATABASE_PORT}
DATABASE_HOST: ${DATABASE_HOST} # DATABASE_HOST: ${DATABASE_HOST}
DATABASE_URL: mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME} # DATABASE_URL: mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}
SHADOW_DATABASE_URL: mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}_shadow # SHADOW_DATABASE_URL: mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}_shadow
JWT_SECRET: ${JWT_SECRET} # JWT_SECRET: ${JWT_SECRET}
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN} # JWT_EXPIRES_IN: ${JWT_EXPIRES_IN}
OTP_STATIC_CODE: ${OTP_STATIC_CODE} # OTP_STATIC_CODE: ${OTP_STATIC_CODE}
depends_on: # depends_on:
database: # database:
condition: service_healthy # condition: service_healthy
environment: # environment:
NODE_ENV: ${NODE_ENV:-production} # NODE_ENV: ${NODE_ENV:-production}
PORT: ${PORT} # PORT: ${PORT}
DATABASE_NAME: ${DATABASE_NAME} # DATABASE_NAME: ${DATABASE_NAME}
DATABASE_USER: ${DATABASE_USER} # DATABASE_USER: ${DATABASE_USER}
DATABASE_PASSWORD: ${DATABASE_PASSWORD} # DATABASE_PASSWORD: ${DATABASE_PASSWORD}
DATABASE_PORT: ${DATABASE_PORT} # DATABASE_PORT: ${DATABASE_PORT}
DATABASE_HOST: ${DATABASE_HOST} # DATABASE_HOST: ${DATABASE_HOST}
DATABASE_URL: mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME} # DATABASE_URL: mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}
SHADOW_DATABASE_URL: mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}_shadow # SHADOW_DATABASE_URL: mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}_shadow
JWT_SECRET: ${JWT_SECRET} # JWT_SECRET: ${JWT_SECRET}
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN} # JWT_EXPIRES_IN: ${JWT_EXPIRES_IN}
OTP_STATIC_CODE: ${OTP_STATIC_CODE} # OTP_STATIC_CODE: ${OTP_STATIC_CODE}
networks: # networks:
- psp_consumer_network # - psp_consumer_network
profiles: # profiles:
- tools # - tools
command: ["pnpm", "seed:sku"] # command: ["pnpm", "seed:sku"]
volumes: volumes:
db_data: db_data:
driver: local driver: local
redis_data:
driver: local
networks: networks:
psp_consumer_network: psp_consumer_network:
+1
View File
@@ -24,6 +24,7 @@
"mysql2": "^3.22.2", "mysql2": "^3.22.2",
"prisma": "^7.7.0", "prisma": "^7.7.0",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"ioredis": "^5.8.2",
"rxjs": "^7.8.2", "rxjs": "^7.8.2",
"uuid": "^13.0.0" "uuid": "^13.0.0"
}, },
+130 -61
View File
@@ -59,6 +59,9 @@ importers:
dotenv: dotenv:
specifier: ^17.4.2 specifier: ^17.4.2
version: 17.4.2 version: 17.4.2
ioredis:
specifier: ^5.8.2
version: 5.10.1
jalaliday: jalaliday:
specifier: ^3.1.1 specifier: ^3.1.1
version: 3.1.1(dayjs@1.11.20) version: 3.1.1(dayjs@1.11.20)
@@ -511,7 +514,7 @@ packages:
resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==}
'@colors/colors@1.5.0': '@colors/colors@1.5.0':
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==, tarball: https://hub.megan.ir/repository/npm/@colors/colors/-/colors-1.5.0.tgz}
engines: {node: '>=0.1.90'} engines: {node: '>=0.1.90'}
'@cspotcode/source-map-support@0.8.1': '@cspotcode/source-map-support@0.8.1':
@@ -533,166 +536,166 @@ packages:
resolution: {integrity: sha512-mZ9NzzUSYPOCnxHH1oAHPRzoMFJHY472raDKwXl/+6oPbpdJ7g8LsCN4FSaIIfkiCKHhb3iF/Zqo3NYxaIhU7Q==} resolution: {integrity: sha512-mZ9NzzUSYPOCnxHH1oAHPRzoMFJHY472raDKwXl/+6oPbpdJ7g8LsCN4FSaIIfkiCKHhb3iF/Zqo3NYxaIhU7Q==}
'@emnapi/core@1.10.0': '@emnapi/core@1.10.0':
resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==, tarball: https://hub.megan.ir/repository/npm/@emnapi/core/-/core-1.10.0.tgz}
'@emnapi/runtime@1.10.0': '@emnapi/runtime@1.10.0':
resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==, tarball: https://hub.megan.ir/repository/npm/@emnapi/runtime/-/runtime-1.10.0.tgz}
'@emnapi/wasi-threads@1.2.1': '@emnapi/wasi-threads@1.2.1':
resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==, tarball: https://hub.megan.ir/repository/npm/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz}
'@esbuild/aix-ppc64@0.27.7': '@esbuild/aix-ppc64@0.27.7':
resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==, tarball: https://hub.megan.ir/repository/npm/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [ppc64] cpu: [ppc64]
os: [aix] os: [aix]
'@esbuild/android-arm64@0.27.7': '@esbuild/android-arm64@0.27.7':
resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==, tarball: https://hub.megan.ir/repository/npm/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@esbuild/android-arm@0.27.7': '@esbuild/android-arm@0.27.7':
resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==, tarball: https://hub.megan.ir/repository/npm/@esbuild/android-arm/-/android-arm-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm] cpu: [arm]
os: [android] os: [android]
'@esbuild/android-x64@0.27.7': '@esbuild/android-x64@0.27.7':
resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==, tarball: https://hub.megan.ir/repository/npm/@esbuild/android-x64/-/android-x64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [android] os: [android]
'@esbuild/darwin-arm64@0.27.7': '@esbuild/darwin-arm64@0.27.7':
resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==, tarball: https://hub.megan.ir/repository/npm/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@esbuild/darwin-x64@0.27.7': '@esbuild/darwin-x64@0.27.7':
resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==, tarball: https://hub.megan.ir/repository/npm/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@esbuild/freebsd-arm64@0.27.7': '@esbuild/freebsd-arm64@0.27.7':
resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==, tarball: https://hub.megan.ir/repository/npm/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [freebsd] os: [freebsd]
'@esbuild/freebsd-x64@0.27.7': '@esbuild/freebsd-x64@0.27.7':
resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==, tarball: https://hub.megan.ir/repository/npm/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@esbuild/linux-arm64@0.27.7': '@esbuild/linux-arm64@0.27.7':
resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@esbuild/linux-arm@0.27.7': '@esbuild/linux-arm@0.27.7':
resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@esbuild/linux-ia32@0.27.7': '@esbuild/linux-ia32@0.27.7':
resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [ia32] cpu: [ia32]
os: [linux] os: [linux]
'@esbuild/linux-loong64@0.27.7': '@esbuild/linux-loong64@0.27.7':
resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
'@esbuild/linux-mips64el@0.27.7': '@esbuild/linux-mips64el@0.27.7':
resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [mips64el] cpu: [mips64el]
os: [linux] os: [linux]
'@esbuild/linux-ppc64@0.27.7': '@esbuild/linux-ppc64@0.27.7':
resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
'@esbuild/linux-riscv64@0.27.7': '@esbuild/linux-riscv64@0.27.7':
resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
'@esbuild/linux-s390x@0.27.7': '@esbuild/linux-s390x@0.27.7':
resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
'@esbuild/linux-x64@0.27.7': '@esbuild/linux-x64@0.27.7':
resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==, tarball: https://hub.megan.ir/repository/npm/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@esbuild/netbsd-arm64@0.27.7': '@esbuild/netbsd-arm64@0.27.7':
resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==, tarball: https://hub.megan.ir/repository/npm/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [netbsd] os: [netbsd]
'@esbuild/netbsd-x64@0.27.7': '@esbuild/netbsd-x64@0.27.7':
resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==, tarball: https://hub.megan.ir/repository/npm/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [netbsd] os: [netbsd]
'@esbuild/openbsd-arm64@0.27.7': '@esbuild/openbsd-arm64@0.27.7':
resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==, tarball: https://hub.megan.ir/repository/npm/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [openbsd] os: [openbsd]
'@esbuild/openbsd-x64@0.27.7': '@esbuild/openbsd-x64@0.27.7':
resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==, tarball: https://hub.megan.ir/repository/npm/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [openbsd] os: [openbsd]
'@esbuild/openharmony-arm64@0.27.7': '@esbuild/openharmony-arm64@0.27.7':
resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==, tarball: https://hub.megan.ir/repository/npm/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [openharmony] os: [openharmony]
'@esbuild/sunos-x64@0.27.7': '@esbuild/sunos-x64@0.27.7':
resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==, tarball: https://hub.megan.ir/repository/npm/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [sunos] os: [sunos]
'@esbuild/win32-arm64@0.27.7': '@esbuild/win32-arm64@0.27.7':
resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==, tarball: https://hub.megan.ir/repository/npm/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@esbuild/win32-ia32@0.27.7': '@esbuild/win32-ia32@0.27.7':
resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==, tarball: https://hub.megan.ir/repository/npm/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@esbuild/win32-x64@0.27.7': '@esbuild/win32-x64@0.27.7':
resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==, tarball: https://hub.megan.ir/repository/npm/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@@ -904,6 +907,9 @@ packages:
'@types/node': '@types/node':
optional: true optional: true
'@ioredis/commands@1.5.1':
resolution: {integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==, tarball: https://hub.megan.ir/repository/npm/@ioredis/commands/-/commands-1.5.1.tgz}
'@isaacs/cliui@8.0.2': '@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'} engines: {node: '>=12'}
@@ -1031,7 +1037,7 @@ packages:
resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==}
'@napi-rs/wasm-runtime@0.2.12': '@napi-rs/wasm-runtime@0.2.12':
resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==, tarball: https://hub.megan.ir/repository/npm/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz}
'@nestjs/cli@11.0.21': '@nestjs/cli@11.0.21':
resolution: {integrity: sha512-F8mV0Sj/zVEouzR3NxBuJy08YHTUOmC5Xdcx3qIIaJWzrm8Vw86CHkhkaPBJ5ewRMHPDCShPmhsfwhpCcjts3A==} resolution: {integrity: sha512-F8mV0Sj/zVEouzR3NxBuJy08YHTUOmC5Xdcx3qIIaJWzrm8Vw86CHkhkaPBJ5ewRMHPDCShPmhsfwhpCcjts3A==}
@@ -1159,7 +1165,7 @@ packages:
resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==} resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==}
'@pkgjs/parseargs@0.11.0': '@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==, tarball: https://hub.megan.ir/repository/npm/@pkgjs/parseargs/-/parseargs-0.11.0.tgz}
engines: {node: '>=14'} engines: {node: '>=14'}
'@pkgr/core@0.2.9': '@pkgr/core@0.2.9':
@@ -1553,7 +1559,7 @@ packages:
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
'@tybys/wasm-util@0.10.1': '@tybys/wasm-util@0.10.1':
resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==, tarball: https://hub.megan.ir/repository/npm/@tybys/wasm-util/-/wasm-util-0.10.1.tgz}
'@types/babel__core@7.20.5': '@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
@@ -1645,7 +1651,7 @@ packages:
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
'@types/react@19.2.7': '@types/react@19.2.7':
resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==, tarball: https://hub.megan.ir/repository/npm/@types/react/-/react-19.2.7.tgz}
'@types/send@1.2.1': '@types/send@1.2.1':
resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==}
@@ -1734,97 +1740,105 @@ packages:
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
'@unrs/resolver-binding-android-arm-eabi@1.11.1': '@unrs/resolver-binding-android-arm-eabi@1.11.1':
resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz}
cpu: [arm] cpu: [arm]
os: [android] os: [android]
'@unrs/resolver-binding-android-arm64@1.11.1': '@unrs/resolver-binding-android-arm64@1.11.1':
resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@unrs/resolver-binding-darwin-arm64@1.11.1': '@unrs/resolver-binding-darwin-arm64@1.11.1':
resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@unrs/resolver-binding-darwin-x64@1.11.1': '@unrs/resolver-binding-darwin-x64@1.11.1':
resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@unrs/resolver-binding-freebsd-x64@1.11.1': '@unrs/resolver-binding-freebsd-x64@1.11.1':
resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1':
resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1':
resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@unrs/resolver-binding-linux-arm64-gnu@1.11.1': '@unrs/resolver-binding-linux-arm64-gnu@1.11.1':
resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-arm64-musl@1.11.1': '@unrs/resolver-binding-linux-arm64-musl@1.11.1':
resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1':
resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1':
resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-riscv64-musl@1.11.1': '@unrs/resolver-binding-linux-riscv64-musl@1.11.1':
resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [musl]
'@unrs/resolver-binding-linux-s390x-gnu@1.11.1': '@unrs/resolver-binding-linux-s390x-gnu@1.11.1':
resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-x64-gnu@1.11.1': '@unrs/resolver-binding-linux-x64-gnu@1.11.1':
resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-x64-musl@1.11.1': '@unrs/resolver-binding-linux-x64-musl@1.11.1':
resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@unrs/resolver-binding-wasm32-wasi@1.11.1': '@unrs/resolver-binding-wasm32-wasi@1.11.1':
resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
cpu: [wasm32] cpu: [wasm32]
'@unrs/resolver-binding-win32-arm64-msvc@1.11.1': '@unrs/resolver-binding-win32-arm64-msvc@1.11.1':
resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@unrs/resolver-binding-win32-ia32-msvc@1.11.1': '@unrs/resolver-binding-win32-ia32-msvc@1.11.1':
resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@unrs/resolver-binding-win32-x64-msvc@1.11.1': '@unrs/resolver-binding-win32-x64-msvc@1.11.1':
resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==, tarball: https://hub.megan.ir/repository/npm/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@@ -2193,6 +2207,10 @@ packages:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'} engines: {node: '>=0.8'}
cluster-key-slot@1.1.2:
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==, tarball: https://hub.megan.ir/repository/npm/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz}
engines: {node: '>=0.10.0'}
co@4.6.0: co@4.6.0:
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
@@ -2289,13 +2307,13 @@ packages:
engines: {node: '>= 8'} engines: {node: '>= 8'}
csstype@3.2.3: csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, tarball: https://hub.megan.ir/repository/npm/csstype/-/csstype-3.2.3.tgz}
dayjs@1.11.20: dayjs@1.11.20:
resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==}
debug@4.4.3: debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, tarball: https://hub.megan.ir/repository/npm/debug/-/debug-4.4.3.tgz}
engines: {node: '>=6.0'} engines: {node: '>=6.0'}
peerDependencies: peerDependencies:
supports-color: '*' supports-color: '*'
@@ -2333,7 +2351,7 @@ packages:
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
denque@2.1.0: denque@2.1.0:
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==, tarball: https://hub.megan.ir/repository/npm/denque/-/denque-2.1.0.tgz}
engines: {node: '>=0.10'} engines: {node: '>=0.10'}
depd@2.0.0: depd@2.0.0:
@@ -2673,7 +2691,7 @@ packages:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
fsevents@2.3.3: fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://hub.megan.ir/repository/npm/fsevents/-/fsevents-2.3.3.tgz}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin] os: [darwin]
@@ -2836,6 +2854,10 @@ packages:
inherits@2.0.4: inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
ioredis@5.10.1:
resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==, tarball: https://hub.megan.ir/repository/npm/ioredis/-/ioredis-5.10.1.tgz}
engines: {node: '>=12.22.0'}
ipaddr.js@1.9.1: ipaddr.js@1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
@@ -3137,9 +3159,15 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'} engines: {node: '>=10'}
lodash.defaults@4.2.0:
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==, tarball: https://hub.megan.ir/repository/npm/lodash.defaults/-/lodash.defaults-4.2.0.tgz}
lodash.includes@4.3.0: lodash.includes@4.3.0:
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
lodash.isarguments@3.1.0:
resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==, tarball: https://hub.megan.ir/repository/npm/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz}
lodash.isboolean@3.0.3: lodash.isboolean@3.0.3:
resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
@@ -3556,7 +3584,7 @@ packages:
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
react-dom@19.2.1: react-dom@19.2.1:
resolution: {integrity: sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==} resolution: {integrity: sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==, tarball: https://hub.megan.ir/repository/npm/react-dom/-/react-dom-19.2.1.tgz}
peerDependencies: peerDependencies:
react: ^19.2.1 react: ^19.2.1
@@ -3564,7 +3592,7 @@ packages:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
react@19.2.1: react@19.2.1:
resolution: {integrity: sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==} resolution: {integrity: sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==, tarball: https://hub.megan.ir/repository/npm/react/-/react-19.2.1.tgz}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
readable-stream@3.6.2: readable-stream@3.6.2:
@@ -3575,6 +3603,14 @@ packages:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'} engines: {node: '>= 14.18.0'}
redis-errors@1.2.0:
resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==, tarball: https://hub.megan.ir/repository/npm/redis-errors/-/redis-errors-1.2.0.tgz}
engines: {node: '>=4'}
redis-parser@3.0.0:
resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==, tarball: https://hub.megan.ir/repository/npm/redis-parser/-/redis-parser-3.0.0.tgz}
engines: {node: '>=4'}
reflect-metadata@0.2.2: reflect-metadata@0.2.2:
resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
@@ -3629,7 +3665,7 @@ packages:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
scheduler@0.27.0: scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==, tarball: https://hub.megan.ir/repository/npm/scheduler/-/scheduler-0.27.0.tgz}
schema-utils@3.3.0: schema-utils@3.3.0:
resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
@@ -3730,6 +3766,9 @@ packages:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
standard-as-callback@2.1.0:
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==, tarball: https://hub.megan.ir/repository/npm/standard-as-callback/-/standard-as-callback-2.1.0.tgz}
statuses@2.0.2: statuses@2.0.2:
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
@@ -3976,7 +4015,7 @@ packages:
hasBin: true hasBin: true
uglify-js@3.19.3: uglify-js@3.19.3:
resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==, tarball: https://hub.megan.ir/repository/npm/uglify-js/-/uglify-js-3.19.3.tgz}
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}
hasBin: true hasBin: true
@@ -5121,6 +5160,8 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/node': 22.19.17 '@types/node': 22.19.17
'@ioredis/commands@1.5.1': {}
'@isaacs/cliui@8.0.2': '@isaacs/cliui@8.0.2':
dependencies: dependencies:
string-width: 5.1.2 string-width: 5.1.2
@@ -6720,6 +6761,8 @@ snapshots:
clone@1.0.4: {} clone@1.0.4: {}
cluster-key-slot@1.1.2: {}
co@4.6.0: {} co@4.6.0: {}
collect-v8-coverage@1.0.3: {} collect-v8-coverage@1.0.3: {}
@@ -7390,6 +7433,20 @@ snapshots:
inherits@2.0.4: {} inherits@2.0.4: {}
ioredis@5.10.1:
dependencies:
'@ioredis/commands': 1.5.1
cluster-key-slot: 1.1.2
debug: 4.4.3
denque: 2.1.0
lodash.defaults: 4.2.0
lodash.isarguments: 3.1.0
redis-errors: 1.2.0
redis-parser: 3.0.0
standard-as-callback: 2.1.0
transitivePeerDependencies:
- supports-color
ipaddr.js@1.9.1: {} ipaddr.js@1.9.1: {}
is-arrayish@0.2.1: {} is-arrayish@0.2.1: {}
@@ -7864,8 +7921,12 @@ snapshots:
dependencies: dependencies:
p-locate: 5.0.0 p-locate: 5.0.0
lodash.defaults@4.2.0: {}
lodash.includes@4.3.0: {} lodash.includes@4.3.0: {}
lodash.isarguments@3.1.0: {}
lodash.isboolean@3.0.3: {} lodash.isboolean@3.0.3: {}
lodash.isinteger@4.0.4: {} lodash.isinteger@4.0.4: {}
@@ -8259,6 +8320,12 @@ snapshots:
readdirp@4.1.2: {} readdirp@4.1.2: {}
redis-errors@1.2.0: {}
redis-parser@3.0.0:
dependencies:
redis-errors: 1.2.0
reflect-metadata@0.2.2: {} reflect-metadata@0.2.2: {}
remeda@2.33.4: {} remeda@2.33.4: {}
@@ -8420,6 +8487,8 @@ snapshots:
dependencies: dependencies:
escape-string-regexp: 2.0.0 escape-string-regexp: 2.0.0
standard-as-callback@2.1.0: {}
statuses@2.0.2: {} statuses@2.0.2: {}
std-env@3.10.0: {} std-env@3.10.0: {}
@@ -0,0 +1,32 @@
/*
Warnings:
- You are about to drop the `consumer_devices` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE `consumer_devices` DROP FOREIGN KEY `consumer_devices_consumer_id_fkey`;
-- DropTable
DROP TABLE `consumer_devices`;
-- CreateTable
CREATE TABLE `consumer_account_device` (
`id` VARCHAR(191) NOT NULL,
`device_id` VARCHAR(191) NOT NULL,
`device_name` VARCHAR(191) NULL,
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NOT NULL,
`consumer_account_id` VARCHAR(191) NOT NULL,
UNIQUE INDEX `consumer_account_device_device_id_key`(`device_id`),
UNIQUE INDEX `consumer_account_device_consumer_account_id_key`(`consumer_account_id`),
INDEX `consumer_account_device_consumer_account_id_idx`(`consumer_account_id`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `consumer_account_device` ADD CONSTRAINT `consumer_account_device_consumer_account_id_fkey` FOREIGN KEY (`consumer_account_id`) REFERENCES `consumer_accounts`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `sale_invoice_tsp_attempts` ADD CONSTRAINT `sale_invoice_tsp_attempts_invoice_id_fkey` FOREIGN KEY (`invoice_id`) REFERENCES `sales_invoices`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,14 @@
model ConsumerAccountDevice {
id String @id @default(ulid())
device_id String @unique
device_name String?
created_at DateTime @default(now()) @db.Timestamp(0)
updated_at DateTime @updatedAt @db.Timestamp(0)
consumer_account_id String @unique
consumer_account ConsumerAccount @relation(fields: [consumer_account_id], references: [id])
@@index([consumer_account_id])
@@map("consumer_account_device")
}
@@ -1,23 +1,23 @@
model ConsumerDevices { // model ConsumerDevices {
uuid String @id @unique @db.VarChar(255) // uuid String @id @unique @db.VarChar(255)
app_version String @db.VarChar(20) // app_version String @db.VarChar(20)
build_number String @db.VarChar(20) // build_number String @db.VarChar(20)
platform String @db.VarChar(100) // platform String @db.VarChar(100)
brand String @db.VarChar(100) // brand String @db.VarChar(100)
model String @db.VarChar(100) // model String @db.VarChar(100)
device String @db.VarChar(100) // device String @db.VarChar(100)
publisher ApplicationPublisher // publisher ApplicationPublisher
os_version String @db.VarChar(20) // os_version String @db.VarChar(20)
sdk_version String @db.VarChar(20) // sdk_version String @db.VarChar(20)
release_number String @db.VarChar(20) // release_number String @db.VarChar(20)
user_agent String? @db.VarChar(100) // user_agent String? @db.VarChar(100)
browser_name String? @db.VarChar(100) // browser_name String? @db.VarChar(100)
fcm_token String? @db.VarChar(100) // fcm_token String? @db.VarChar(100)
created_at DateTime @default(now()) @db.Timestamp(0) // created_at DateTime @default(now()) @db.Timestamp(0)
updated_at DateTime @updatedAt @db.Timestamp(0) // updated_at DateTime @updatedAt @db.Timestamp(0)
consumer_id String // consumer_id String
consumer Consumer @relation(fields: [consumer_id], references: [id]) // consumer Consumer @relation(fields: [consumer_id], references: [id])
@@index([consumer_id], map: "consumer_devices_consumer_id_fkey") // @@index([consumer_id], map: "consumer_devices_consumer_id_fkey")
@@map("consumer_devices") // @@map("consumer_devices")
} // }
+2 -1
View File
@@ -15,6 +15,7 @@ model ConsumerAccount {
permission PermissionConsumer? permission PermissionConsumer?
account_allocation LicenseAccountAllocation? account_allocation LicenseAccountAllocation?
sales_invoices SalesInvoice[] sales_invoices SalesInvoice[]
account_device ConsumerAccountDevice?
@@map("consumer_accounts") @@map("consumer_accounts")
} }
@@ -29,7 +30,7 @@ model Consumer {
accounts ConsumerAccount[] accounts ConsumerAccount[]
business_activities BusinessActivity[] business_activities BusinessActivity[]
devices ConsumerDevices[] // devices ConsumerDevices[]
individual ConsumerIndividual? individual ConsumerIndividual?
legal ConsumerLegal? legal ConsumerLegal?
-13
View File
@@ -132,19 +132,6 @@ async function main() {
}) })
upserted++ upserted++
} }
console.log(
JSON.stringify(
{
csvPath: absolutePath,
totalRows: rows.length,
upserted,
skipped,
},
null,
2,
),
)
} }
main() main()
+2
View File
@@ -13,10 +13,12 @@ import { SalesInvoicePaymentsModule } from './modules/pos/sales-invoices/sales-i
import { TriggerLogsModule } from './modules/trigger-logs/trigger-logs.module' import { TriggerLogsModule } from './modules/trigger-logs/trigger-logs.module'
import { UploaderModule } from './modules/uploader/uploader.module' import { UploaderModule } from './modules/uploader/uploader.module'
import { PrismaModule } from './prisma/prisma.module' import { PrismaModule } from './prisma/prisma.module'
import { RedisModule } from './redis/redis.module'
@Module({ @Module({
imports: [ imports: [
PrismaModule, PrismaModule,
RedisModule,
EnumsModule, EnumsModule,
AdminModule, AdminModule,
AuthModule, AuthModule,
+9 -9
View File
@@ -1,7 +1,7 @@
export enum GoldKarat { export enum GoldKarat {
KARAT_18 = '18', KARAT_18 = 'KARAT_18',
KARAT_21 = '21', KARAT_21 = 'KARAT_21',
KARAT_24 = '24', KARAT_24 = 'KARAT_24',
} }
export enum TspProviderRequestType { export enum TspProviderRequestType {
@@ -16,16 +16,16 @@ export enum SKUGuildType {
} }
export const UploadedFileTypes = { export const UploadedFileTypes = {
GOOD: 'good', GOOD: 'GOOD',
SERVICE: 'service', SERVICE: 'SERVICE',
PROFILE_AVATAR: 'profile_avatar', PROFILE_AVATAR: 'PROFILE_AVATAR',
PARTNER_LOGO: 'partner_logo', PARTNER_LOGO: 'PARTNER_LOGO',
} }
export type UploadedFileTypes = (typeof UploadedFileTypes)[keyof typeof UploadedFileTypes] export type UploadedFileTypes = (typeof UploadedFileTypes)[keyof typeof UploadedFileTypes]
export const TspProviderCustomerType = { export const TspProviderCustomerType = {
UNKNOWN: 'Unknown', UNKNOWN: 'UNKNOWN',
KNOWN: 'Known', KNOWN: 'KNOWN',
} }
export type TspProviderCustomerType = export type TspProviderCustomerType =
@@ -0,0 +1,56 @@
import { BusinessActivitySelect } from '@/generated/prisma/models'
export const summarySelect: BusinessActivitySelect = {
id: true,
name: true,
economic_code: true,
created_at: true,
fiscal_id: true,
invoice_number_sequence: true,
partner_token: true,
guild: {
select: {
id: true,
code: true,
name: true,
},
},
license_activation: {
select: {
id: true,
starts_at: true,
expires_at: true,
license: {
select: {
activation: {
select: {
_count: {
select: {
account_allocations: true,
},
},
},
},
},
},
},
},
}
export const select: BusinessActivitySelect = {
...summarySelect,
}
export const mappedData = (businessActivity: any) => {
const { license_activation, ...rest } = businessActivity
const { license, ...license_activation_rest } = license_activation
const { _count } = license.activation
return {
...rest,
license_info: {
...license_activation_rest,
accounts_limit: _count.account_allocations,
},
}
}
+2
View File
@@ -1,3 +1,4 @@
import * as BUSINESS_ACTIVITIES from './businessActivities'
import * as CONSUMER from './consumer' import * as CONSUMER from './consumer'
import * as LICENSE_ACTIVATION from './licenseActivation' import * as LICENSE_ACTIVATION from './licenseActivation'
import * as POS from './pos' import * as POS from './pos'
@@ -8,4 +9,5 @@ export const QUERY_CONSTANTS = {
CONSUMER, CONSUMER,
LICENSE_ACTIVATION, LICENSE_ACTIVATION,
SALE_INVOICE, SALE_INVOICE,
BUSINESS_ACTIVITIES,
} }
+102 -29
View File
@@ -10,16 +10,37 @@ export const summarySelect: SalesInvoiceSelect = {
tax_id: true, tax_id: true,
type: true, type: true,
notes: true, notes: true,
created_at: true,
customer: {
select: {
type: true,
individual: {
select: {
first_name: true,
last_name: true,
mobile_number: true,
national_id: true,
},
},
legal: {
select: {
name: true,
economic_code: true,
registration_number: true,
},
},
},
},
tsp_attempts: { tsp_attempts: {
orderBy: {
created_at: 'desc',
},
take: 1,
select: { select: {
status: true, status: true,
sent_at: true, sent_at: true,
message: true, message: true,
}, },
orderBy: {
attempt_no: 'desc',
},
take: 1,
}, },
reference_invoice: { reference_invoice: {
select: { select: {
@@ -31,42 +52,94 @@ export const summarySelect: SalesInvoiceSelect = {
export const select: SalesInvoiceSelect = { export const select: SalesInvoiceSelect = {
...summarySelect, ...summarySelect,
payments: { updated_at: true,
select: {
amount: true,
paid_at: true,
payment_method: true,
terminal_info: {
select: {
customer_card_no: true,
terminal_id: true,
rrn: true,
stan: true,
transaction_date_time: true,
},
},
},
},
unknown_customer: true, unknown_customer: true,
customer: { pos: {
select: { select: {
type: true, id: true,
legal: true, name: true,
individual: true, complex: {
select: {
id: true,
name: true,
business_activity: {
select: {
id: true,
name: true,
},
},
},
},
},
},
consumer_account: {
select: {
id: true,
role: true,
account: {
select: {
username: true,
},
},
}, },
}, },
items: { items: {
select: { select: {
id: true,
good_id: true,
service_id: true,
quantity: true, quantity: true,
unit_price: true,
discount: true,
total_amount: true,
payload: true,
measure_unit_code: true, measure_unit_code: true,
measure_unit_text: true, measure_unit_text: true,
sku_code: true, sku_code: true,
sku_vat: true, unit_price: true,
discount: true,
total_amount: true,
notes: true,
payload: true,
good_snapshot: true, good_snapshot: true,
good: {
select: {
name: true,
barcode: true,
image_url: true,
category: true,
}, },
}, },
},
},
payments: {
select: {
id: true,
amount: true,
payment_method: true,
paid_at: true,
created_at: true,
terminal_info: {
select: {
terminal_id: true,
stan: true,
rrn: true,
transaction_date_time: true,
customer_card_no: true,
description: true,
},
},
},
},
tsp_attempts: {
orderBy: {
created_at: 'desc',
},
select: {
id: true,
attempt_no: true,
status: true,
message: true,
sent_at: true,
received_at: true,
created_at: true,
},
take: 1,
},
} }
@@ -1,3 +1,4 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants'
import { BusinessActivitySelect } from '@/generated/prisma/models' import { BusinessActivitySelect } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
@@ -7,45 +8,35 @@ export class BusinessActivitiesQueryService {
constructor(private readonly prisma: PrismaService) {} constructor(private readonly prisma: PrismaService) {}
readonly baseSelect: BusinessActivitySelect = { readonly baseSelect: BusinessActivitySelect = {
id: true, ...QUERY_CONSTANTS.BUSINESS_ACTIVITIES.summarySelect,
name: true,
economic_code: true,
created_at: true,
partner_token: true,
fiscal_id: true,
guild: {
select: {
id: true,
code: true,
name: true,
},
},
} }
findAllByConsumer(consumer_id: string, select: BusinessActivitySelect) { async findAllByConsumer(consumer_id: string, select: BusinessActivitySelect) {
return this.prisma.businessActivity.findMany({ const businessActivities = await this.prisma.businessActivity.findMany({
where: { consumer_id }, where: { consumer_id },
select, select: this.baseSelect,
}) })
return businessActivities.map(QUERY_CONSTANTS.BUSINESS_ACTIVITIES.mappedData)
} }
findOneByConsumer( async findOneByConsumer(
consumer_id: string, consumer_id: string,
id: string, id: string,
select: BusinessActivitySelect, select: BusinessActivitySelect,
orThrow = false, orThrow = false,
) { ) {
if (orThrow) { // if (orThrow) {
return this.prisma.businessActivity.findUniqueOrThrow({ // return await this.prisma.businessActivity.findUniqueOrThrow({
where: { consumer_id, id }, // where: { consumer_id, id },
select, // select,
}) // })
} // }
return this.prisma.businessActivity.findUnique({ const businessActivity = await this.prisma.businessActivity.findUnique({
where: { consumer_id, id }, where: { consumer_id, id },
select, select: QUERY_CONSTANTS.BUSINESS_ACTIVITIES.select,
}) })
return QUERY_CONSTANTS.BUSINESS_ACTIVITIES.mappedData(businessActivity)
} }
} }
@@ -0,0 +1,29 @@
import { PrismaService } from '@/prisma/prisma.service'
import { BadRequestException, Injectable } from '@nestjs/common'
import { ConsumerRole } from 'generated/prisma/enums'
@Injectable()
export class SharedSaleInvoiceAccessService {
constructor(private readonly prisma: PrismaService) {}
async getConsumerIdWithPosAccess(
consumerAccountId: string,
posId: string,
): Promise<string> {
const consumer = await this.prisma.consumerAccount.findUnique({
where: {
id: consumerAccountId,
OR: [{ pos: { id: posId } }, { role: ConsumerRole.OWNER }],
},
select: {
consumer_id: true,
},
})
if (!consumer) {
throw new BadRequestException('شما دسترسی لازم برای ارسال فاکتور را ندارید.')
}
return consumer.consumer_id
}
}
@@ -0,0 +1,55 @@
import { SharedSaleInvoiceAccessService } from '@/common/services/saleInvoices/sale-invoice-access.service'
import { Injectable } from '@nestjs/common'
import { SalesInvoiceTspService } from '@/modules/tspProviders/sales-invoice-tsp.service'
@Injectable()
export class SharedSaleInvoiceActionsService {
constructor(
private readonly salesInvoiceTspService: SalesInvoiceTspService,
private readonly saleInvoiceAccessService: SharedSaleInvoiceAccessService,
) {}
async send(consumerAccountId: string, posId: string, invoiceId: string) {
await this.saleInvoiceAccessService.getConsumerIdWithPosAccess(
consumerAccountId,
posId,
)
return this.salesInvoiceTspService.originalSend(posId, invoiceId)
}
async retry(consumerAccountId: string, posId: string, invoiceId: string) {
await this.saleInvoiceAccessService.getConsumerIdWithPosAccess(
consumerAccountId,
posId,
)
return this.salesInvoiceTspService.originalSend(posId, invoiceId)
}
async revoke(
consumerAccountId: string,
posId: string,
complexId: string,
businessId: string,
invoiceId: string,
) {
await this.saleInvoiceAccessService.getConsumerIdWithPosAccess(
consumerAccountId,
posId,
)
return this.salesInvoiceTspService.revoke(
consumerAccountId,
posId,
complexId,
businessId,
invoiceId,
)
}
async inquiry(consumerAccountId: string, posId: string, invoiceId: string) {
const consumerId = await this.saleInvoiceAccessService.getConsumerIdWithPosAccess(
consumerAccountId,
posId,
)
return this.salesInvoiceTspService.get(invoiceId, posId, consumerId)
}
}
@@ -11,13 +11,13 @@ import {
import { SharedCreateSalesInvoiceDto } from './sale-invoice-create.dto' import { SharedCreateSalesInvoiceDto } from './sale-invoice-create.dto'
interface TerminalPaymentInfo { interface TerminalPaymentInfo {
terminalId: string terminal_id: string
stan: string stan: string
rrn: string rrn: string
transactionDateTime: string | Date transaction_date_time: string | Date
customerCardNO?: string customer_card_no: string
description?: string description?: string
amount?: number amount: number
} }
interface NormalizedPayment { interface NormalizedPayment {
@@ -150,8 +150,14 @@ export class SharedSaleInvoiceCreateService {
const rawPayments = (paymentsData || {}) as Record<string, unknown> const rawPayments = (paymentsData || {}) as Record<string, unknown>
const terminalInfo = rawPayments.terminals as TerminalPaymentInfo | undefined const terminalInfo = rawPayments.terminals as TerminalPaymentInfo | undefined
console.log(
'terminalInfo0',
rawPayments.terminals?.[0]?.customer_card_no,
terminalInfo,
)
const payments: NormalizedPayment[] = Object.entries(rawPayments) const payments: NormalizedPayment[] = Object.entries(rawPayments)
.filter(([key]) => key !== 'terminals') .filter(([key, value]) => key !== 'terminals' && value && Number(value) > 0)
.map(([key, value]) => ({ .map(([key, value]) => ({
method: paymentMethodMap[key.toLowerCase()], method: paymentMethodMap[key.toLowerCase()],
amount: typeof value === 'number' ? value : Number(value || 0), amount: typeof value === 'number' ? value : Number(value || 0),
@@ -508,11 +514,11 @@ export class SharedSaleInvoiceCreateService {
await tx.salesInvoicePaymentTerminalInfo.create({ await tx.salesInvoicePaymentTerminalInfo.create({
data: { data: {
payment_id: createdPayment.id, payment_id: createdPayment.id,
terminal_id: terminalInfo.terminalId, terminal_id: terminalInfo.terminal_id,
stan: terminalInfo.stan, stan: terminalInfo.stan,
rrn: terminalInfo.rrn, rrn: terminalInfo.rrn,
transaction_date_time: new Date(terminalInfo.transactionDateTime || ''), transaction_date_time: new Date(terminalInfo.transaction_date_time || ''),
customer_card_no: terminalInfo.customerCardNO || null, customer_card_no: terminalInfo.customer_card_no || null,
description: terminalInfo.description || null, description: terminalInfo.description || null,
}, },
}) })
-2
View File
@@ -29,8 +29,6 @@ export class HttpClientUtil {
continue continue
} }
response = await interceptor.onResponse(context, response) response = await interceptor.onResponse(context, response)
console.log('response')
console.log(response)
} }
return response return response
+3 -2
View File
@@ -1,6 +1,7 @@
export * from './jwt-user.util'
export * from './enum-translator.util' export * from './enum-translator.util'
export * from './http-client.util'
export * from './jwt-user.util'
export * from './mappers/consumer_mappers.util' export * from './mappers/consumer_mappers.util'
export * from './password.util' export * from './password.util'
export * from './redisKeyMaker'
export * from './tracking-code-generator.util' export * from './tracking-code-generator.util'
export * from './http-client.util'
@@ -8,7 +8,7 @@ export default (consumer: any) => {
delete legal?.partner delete legal?.partner
delete individual?.partner delete individual?.partner
return { const returnData = {
...rest, ...rest,
partner, partner,
type: translateEnumValue('ConsumerType', type), type: translateEnumValue('ConsumerType', type),
@@ -18,9 +18,13 @@ export default (consumer: any) => {
? { ...individual, fullname: `${individual?.first_name} ${individual?.last_name}` } ? { ...individual, fullname: `${individual?.first_name} ${individual?.last_name}` }
: null, : null,
name: legal ? legal.name : `${individual?.first_name} ${individual?.last_name}`, name: legal ? legal.name : `${individual?.first_name} ${individual?.last_name}`,
business_counts,
// license_info: prepareLicenseInfo(activation),
} }
if (business_counts !== undefined) {
returnData['business_counts'] = business_counts
}
return returnData
} }
function prepareLicenseInfo(latestLicense: any) { function prepareLicenseInfo(latestLicense: any) {
@@ -0,0 +1,16 @@
export class ConsumerKeyMaker {
static consumerInfo(consumerId: string): string {
return `consumers:${consumerId}:info`
}
static consumerBusinessActivitiesList(consumerId: string): string {
return `consumers:${consumerId}:business-activities:list`
}
static consumerBusinessActivityInfo(
consumerId: string,
businessActivityId: string,
): string {
return `consumers:${consumerId}:business-activities:${businessActivityId}:info`
}
}
+9
View File
@@ -0,0 +1,9 @@
export class EnumKeyMaker {
static enumsAll(buildVersion: string): string {
return `enums:${buildVersion}:all`
}
static enumsValues(buildVersion: string, enumName: string): string {
return `enums:${buildVersion}:values:${enumName}`
}
}
+9
View File
@@ -0,0 +1,9 @@
export class GuildKeyMaker {
static guildStockKeepingUnitsList(guildId: string): string {
return `guilds:${guildId}:stock-keeping-units:list`
}
static guildGoodsList(guildId: string): string {
return `guilds:${guildId}:goods:list`
}
}
+30
View File
@@ -0,0 +1,30 @@
import { ConsumerKeyMaker } from './consumer'
import { EnumKeyMaker } from './enum'
import { GuildKeyMaker } from './guild'
import { PartnerKeyMaker } from './partner'
import { PosKeyMaker } from './pos'
// Keep backward-compatible static methods while separating key builders by domain.
export class RedisKeyMaker extends PartnerKeyMaker {
static consumer = ConsumerKeyMaker
static enums = EnumKeyMaker
static guild = GuildKeyMaker
static partner = PartnerKeyMaker
static pos = PosKeyMaker
static consumerInfo = ConsumerKeyMaker.consumerInfo
static consumerBusinessActivitiesList = ConsumerKeyMaker.consumerBusinessActivitiesList
static consumerBusinessActivityInfo = ConsumerKeyMaker.consumerBusinessActivityInfo
static guildStockKeepingUnitsList = GuildKeyMaker.guildStockKeepingUnitsList
static guildGoodsList = GuildKeyMaker.guildGoodsList
static posInfo = PosKeyMaker.posInfo
static posMe = PosKeyMaker.posMe
static posGoodsList = PosKeyMaker.posGoodsList
static enumsAll = EnumKeyMaker.enumsAll
static enumsValues = EnumKeyMaker.enumsValues
}
export { ConsumerKeyMaker, EnumKeyMaker, GuildKeyMaker, PartnerKeyMaker, PosKeyMaker }
+135
View File
@@ -0,0 +1,135 @@
export class PartnerKeyMaker {
static partnersList(): string {
return 'partners:list'
}
static partnerDetail(partnerId: string): string {
return `partners:${partnerId}:detail`
}
static partnerActivatedLicensesList(
partnerId: string,
page: number,
perPage: number,
): string {
return `partners:${partnerId}:activated-licenses:list:${page}:${perPage}`
}
static partnerActivatedLicensesListPattern(partnerId: string): string {
return `partners:${partnerId}:activated-licenses:list:*`
}
static partnerLicenseChargeTransactionsList(
partnerId: string,
page: number,
perPage: number,
): string {
return `partners:${partnerId}:license-charge-transactions:list:${page}:${perPage}`
}
static partnerLicenseChargeTransactionsListPattern(partnerId: string): string {
return `partners:${partnerId}:license-charge-transactions:list:*`
}
static partnerLicenseChargeTransactionDetail(
partnerId: string,
transactionId: string,
): string {
return `partners:${partnerId}:license-charge-transactions:${transactionId}:detail`
}
static partnerLicenseChargeTransactionDetailPattern(partnerId: string): string {
return `partners:${partnerId}:license-charge-transactions:*:detail`
}
//////////////////// consumers ////////////////////
static partnerConsumersPattern(partnerId: string): string {
return `partners:${partnerId}:consumers:*`
}
static partnerConsumerPattern(partnerId: string): string {
return this.partnerConsumersPattern(partnerId)
}
static partnerConsumersListPattern(partnerId: string): string {
return `partners:${partnerId}:consumers:list:*`
}
static partnerConsumersList(partnerId: string, page: number, perPage: number): string {
return `partners:${partnerId}:consumers:list:${page}:${perPage}`
}
static partnerConsumerInfo(partnerId: string, consumerId: string): string {
return `partners:${partnerId}:consumers:${consumerId}:info`
}
static partnerConsumerBusinessActivitiesList(
partnerId: string,
consumerId: string,
page: number,
perPage: number,
): string {
return `partners:${partnerId}:consumers:${consumerId}:business-activities:list:${page}:${perPage}`
}
static partnerConsumerBusinessActivitiesPattern(
partnerId: string,
consumerId: string,
): string {
return `partners:${partnerId}:consumers:${consumerId}:business-activities:*`
}
static partnerConsumerBusinessActivityInfo(
partnerId: string,
consumerId: string,
businessActivityId: string,
): string {
return `partners:${partnerId}:consumers:${consumerId}:business-activities:${businessActivityId}:info`
}
static partnerConsumerBusinessActivityComplexesList(
partnerId: string,
consumerId: string,
businessActivityId: string,
page: number,
perPage: number,
): string {
return `partners:${partnerId}:consumers:${consumerId}:business-activities:${businessActivityId}:complexes:list:${page}:${perPage}`
}
static partnerConsumerBusinessActivityComplexesPattern(
partnerId: string,
consumerId: string,
businessActivityId: string,
): string {
return `partners:${partnerId}:consumers:${consumerId}:business-activities:${businessActivityId}:complexes:*`
}
static partnerConsumerBusinessActivityComplexInfo(
partnerId: string,
consumerId: string,
businessActivityId: string,
complexId: string,
): string {
return `partners:${partnerId}:consumers:${consumerId}:business-activities:${businessActivityId}:complexes:${complexId}`
}
static partnerConsumerBusinessActivityComplexPosesPattern(
partnerId: string,
consumerId: string,
businessActivityId: string,
complexId: string,
): string {
return `partners:${partnerId}:consumers:${consumerId}:business-activities:${businessActivityId}:complexes:${complexId}:poses:*`
}
static partnerConsumerBusinessActivityComplexPosInfo(
partnerId: string,
consumerId: string,
businessActivityId: string,
complexId: string,
posId: string,
): string {
return `partners:${partnerId}:consumers:${consumerId}:business-activities:${businessActivityId}:complexes:${complexId}:poses:${posId}`
}
}
+13
View File
@@ -0,0 +1,13 @@
export class PosKeyMaker {
static posInfo(posId: string): string {
return `pos:${posId}:info`
}
static posMe(accountId: string, posId: string): string {
return `pos:${posId}:me:${accountId}`
}
static posGoodsList(businessActivityId: string, guildId: string): string {
return `pos:ba:${businessActivityId}:guild:${guildId}:goods:list`
}
}
+2 -2
View File
@@ -123,10 +123,10 @@ export type ProviderAccount = Prisma.ProviderAccountModel
*/ */
export type Provider = Prisma.ProviderModel export type Provider = Prisma.ProviderModel
/** /**
* Model ConsumerDevices * Model ConsumerAccountDevice
* *
*/ */
export type ConsumerDevices = Prisma.ConsumerDevicesModel export type ConsumerAccountDevice = Prisma.ConsumerAccountDeviceModel
/** /**
* Model ApplicationReleasedInfo * Model ApplicationReleasedInfo
* *
+2 -2
View File
@@ -145,10 +145,10 @@ export type ProviderAccount = Prisma.ProviderAccountModel
*/ */
export type Provider = Prisma.ProviderModel export type Provider = Prisma.ProviderModel
/** /**
* Model ConsumerDevices * Model ConsumerAccountDevice
* *
*/ */
export type ConsumerDevices = Prisma.ConsumerDevicesModel export type ConsumerAccountDevice = Prisma.ConsumerAccountDeviceModel
/** /**
* Model ApplicationReleasedInfo * Model ApplicationReleasedInfo
* *
-34
View File
@@ -290,23 +290,6 @@ export type EnumProviderRoleWithAggregatesFilter<$PrismaModel = never> = {
_max?: Prisma.NestedEnumProviderRoleFilter<$PrismaModel> _max?: Prisma.NestedEnumProviderRoleFilter<$PrismaModel>
} }
export type EnumApplicationPublisherFilter<$PrismaModel = never> = {
equals?: $Enums.ApplicationPublisher | Prisma.EnumApplicationPublisherFieldRefInput<$PrismaModel>
in?: $Enums.ApplicationPublisher[]
notIn?: $Enums.ApplicationPublisher[]
not?: Prisma.NestedEnumApplicationPublisherFilter<$PrismaModel> | $Enums.ApplicationPublisher
}
export type EnumApplicationPublisherWithAggregatesFilter<$PrismaModel = never> = {
equals?: $Enums.ApplicationPublisher | Prisma.EnumApplicationPublisherFieldRefInput<$PrismaModel>
in?: $Enums.ApplicationPublisher[]
notIn?: $Enums.ApplicationPublisher[]
not?: Prisma.NestedEnumApplicationPublisherWithAggregatesFilter<$PrismaModel> | $Enums.ApplicationPublisher
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedEnumApplicationPublisherFilter<$PrismaModel>
_max?: Prisma.NestedEnumApplicationPublisherFilter<$PrismaModel>
}
export type BoolFilter<$PrismaModel = never> = { export type BoolFilter<$PrismaModel = never> = {
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
@@ -1028,23 +1011,6 @@ export type NestedEnumProviderRoleWithAggregatesFilter<$PrismaModel = never> = {
_max?: Prisma.NestedEnumProviderRoleFilter<$PrismaModel> _max?: Prisma.NestedEnumProviderRoleFilter<$PrismaModel>
} }
export type NestedEnumApplicationPublisherFilter<$PrismaModel = never> = {
equals?: $Enums.ApplicationPublisher | Prisma.EnumApplicationPublisherFieldRefInput<$PrismaModel>
in?: $Enums.ApplicationPublisher[]
notIn?: $Enums.ApplicationPublisher[]
not?: Prisma.NestedEnumApplicationPublisherFilter<$PrismaModel> | $Enums.ApplicationPublisher
}
export type NestedEnumApplicationPublisherWithAggregatesFilter<$PrismaModel = never> = {
equals?: $Enums.ApplicationPublisher | Prisma.EnumApplicationPublisherFieldRefInput<$PrismaModel>
in?: $Enums.ApplicationPublisher[]
notIn?: $Enums.ApplicationPublisher[]
not?: Prisma.NestedEnumApplicationPublisherWithAggregatesFilter<$PrismaModel> | $Enums.ApplicationPublisher
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedEnumApplicationPublisherFilter<$PrismaModel>
_max?: Prisma.NestedEnumApplicationPublisherFilter<$PrismaModel>
}
export type NestedBoolFilter<$PrismaModel = never> = { export type NestedBoolFilter<$PrismaModel = never> = {
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
File diff suppressed because one or more lines are too long
@@ -405,7 +405,7 @@ export const ModelName = {
PermissionBusiness: 'PermissionBusiness', PermissionBusiness: 'PermissionBusiness',
ProviderAccount: 'ProviderAccount', ProviderAccount: 'ProviderAccount',
Provider: 'Provider', Provider: 'Provider',
ConsumerDevices: 'ConsumerDevices', ConsumerAccountDevice: 'ConsumerAccountDevice',
ApplicationReleasedInfo: 'ApplicationReleasedInfo', ApplicationReleasedInfo: 'ApplicationReleasedInfo',
ConsumerAccount: 'ConsumerAccount', ConsumerAccount: 'ConsumerAccount',
Consumer: 'Consumer', Consumer: 'Consumer',
@@ -445,7 +445,7 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
omit: GlobalOmitOptions omit: GlobalOmitOptions
} }
meta: { meta: {
modelProps: "adminAccount" | "admin" | "account" | "deviceBrand" | "device" | "licenseChargeTransaction" | "license" | "licenseActivation" | "licenseRenewChargeTransaction" | "licenseRenew" | "partnerAccountQuotaChargeTransaction" | "partnerAccountQuotaCredit" | "licenseAccountAllocation" | "partnerAccount" | "partner" | "permissionConsumer" | "permissionPos" | "permissionComplex" | "permissionBusiness" | "providerAccount" | "provider" | "consumerDevices" | "applicationReleasedInfo" | "consumerAccount" | "consumer" | "consumerIndividual" | "consumerLegal" | "businessActivity" | "complex" | "pos" | "good" | "goodCategory" | "guild" | "measureUnits" | "stockKeepingUnits" | "triggerLog" | "customer" | "customerIndividual" | "customerLegal" | "salesInvoice" | "salesInvoiceItem" | "saleInvoiceTspAttempts" | "salesInvoicePayment" | "salesInvoicePaymentTerminalInfo" | "service" | "serviceCategory" modelProps: "adminAccount" | "admin" | "account" | "deviceBrand" | "device" | "licenseChargeTransaction" | "license" | "licenseActivation" | "licenseRenewChargeTransaction" | "licenseRenew" | "partnerAccountQuotaChargeTransaction" | "partnerAccountQuotaCredit" | "licenseAccountAllocation" | "partnerAccount" | "partner" | "permissionConsumer" | "permissionPos" | "permissionComplex" | "permissionBusiness" | "providerAccount" | "provider" | "consumerAccountDevice" | "applicationReleasedInfo" | "consumerAccount" | "consumer" | "consumerIndividual" | "consumerLegal" | "businessActivity" | "complex" | "pos" | "good" | "goodCategory" | "guild" | "measureUnits" | "stockKeepingUnits" | "triggerLog" | "customer" | "customerIndividual" | "customerLegal" | "salesInvoice" | "salesInvoiceItem" | "saleInvoiceTspAttempts" | "salesInvoicePayment" | "salesInvoicePaymentTerminalInfo" | "service" | "serviceCategory"
txIsolationLevel: TransactionIsolationLevel txIsolationLevel: TransactionIsolationLevel
} }
model: { model: {
@@ -1835,69 +1835,69 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
} }
} }
} }
ConsumerDevices: { ConsumerAccountDevice: {
payload: Prisma.$ConsumerDevicesPayload<ExtArgs> payload: Prisma.$ConsumerAccountDevicePayload<ExtArgs>
fields: Prisma.ConsumerDevicesFieldRefs fields: Prisma.ConsumerAccountDeviceFieldRefs
operations: { operations: {
findUnique: { findUnique: {
args: Prisma.ConsumerDevicesFindUniqueArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceFindUniqueArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload> | null result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload> | null
} }
findUniqueOrThrow: { findUniqueOrThrow: {
args: Prisma.ConsumerDevicesFindUniqueOrThrowArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceFindUniqueOrThrowArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload> result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload>
} }
findFirst: { findFirst: {
args: Prisma.ConsumerDevicesFindFirstArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceFindFirstArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload> | null result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload> | null
} }
findFirstOrThrow: { findFirstOrThrow: {
args: Prisma.ConsumerDevicesFindFirstOrThrowArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceFindFirstOrThrowArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload> result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload>
} }
findMany: { findMany: {
args: Prisma.ConsumerDevicesFindManyArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceFindManyArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload>[] result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload>[]
} }
create: { create: {
args: Prisma.ConsumerDevicesCreateArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceCreateArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload> result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload>
} }
createMany: { createMany: {
args: Prisma.ConsumerDevicesCreateManyArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceCreateManyArgs<ExtArgs>
result: BatchPayload result: BatchPayload
} }
delete: { delete: {
args: Prisma.ConsumerDevicesDeleteArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceDeleteArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload> result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload>
} }
update: { update: {
args: Prisma.ConsumerDevicesUpdateArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceUpdateArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload> result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload>
} }
deleteMany: { deleteMany: {
args: Prisma.ConsumerDevicesDeleteManyArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceDeleteManyArgs<ExtArgs>
result: BatchPayload result: BatchPayload
} }
updateMany: { updateMany: {
args: Prisma.ConsumerDevicesUpdateManyArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceUpdateManyArgs<ExtArgs>
result: BatchPayload result: BatchPayload
} }
upsert: { upsert: {
args: Prisma.ConsumerDevicesUpsertArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceUpsertArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerDevicesPayload> result: runtime.Types.Utils.PayloadToResult<Prisma.$ConsumerAccountDevicePayload>
} }
aggregate: { aggregate: {
args: Prisma.ConsumerDevicesAggregateArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceAggregateArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.AggregateConsumerDevices> result: runtime.Types.Utils.Optional<Prisma.AggregateConsumerAccountDevice>
} }
groupBy: { groupBy: {
args: Prisma.ConsumerDevicesGroupByArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceGroupByArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.ConsumerDevicesGroupByOutputType>[] result: runtime.Types.Utils.Optional<Prisma.ConsumerAccountDeviceGroupByOutputType>[]
} }
count: { count: {
args: Prisma.ConsumerDevicesCountArgs<ExtArgs> args: Prisma.ConsumerAccountDeviceCountArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.ConsumerDevicesCountAggregateOutputType> | number result: runtime.Types.Utils.Optional<Prisma.ConsumerAccountDeviceCountAggregateOutputType> | number
} }
} }
} }
@@ -3766,27 +3766,16 @@ export const ProviderScalarFieldEnum = {
export type ProviderScalarFieldEnum = (typeof ProviderScalarFieldEnum)[keyof typeof ProviderScalarFieldEnum] export type ProviderScalarFieldEnum = (typeof ProviderScalarFieldEnum)[keyof typeof ProviderScalarFieldEnum]
export const ConsumerDevicesScalarFieldEnum = { export const ConsumerAccountDeviceScalarFieldEnum = {
uuid: 'uuid', id: 'id',
app_version: 'app_version', device_id: 'device_id',
build_number: 'build_number', device_name: 'device_name',
platform: 'platform',
brand: 'brand',
model: 'model',
device: 'device',
publisher: 'publisher',
os_version: 'os_version',
sdk_version: 'sdk_version',
release_number: 'release_number',
user_agent: 'user_agent',
browser_name: 'browser_name',
fcm_token: 'fcm_token',
created_at: 'created_at', created_at: 'created_at',
updated_at: 'updated_at', updated_at: 'updated_at',
consumer_id: 'consumer_id' consumer_account_id: 'consumer_account_id'
} as const } as const
export type ConsumerDevicesScalarFieldEnum = (typeof ConsumerDevicesScalarFieldEnum)[keyof typeof ConsumerDevicesScalarFieldEnum] export type ConsumerAccountDeviceScalarFieldEnum = (typeof ConsumerAccountDeviceScalarFieldEnum)[keyof typeof ConsumerAccountDeviceScalarFieldEnum]
export const ApplicationReleasedInfoScalarFieldEnum = { export const ApplicationReleasedInfoScalarFieldEnum = {
@@ -4368,24 +4357,14 @@ export const ProviderOrderByRelevanceFieldEnum = {
export type ProviderOrderByRelevanceFieldEnum = (typeof ProviderOrderByRelevanceFieldEnum)[keyof typeof ProviderOrderByRelevanceFieldEnum] export type ProviderOrderByRelevanceFieldEnum = (typeof ProviderOrderByRelevanceFieldEnum)[keyof typeof ProviderOrderByRelevanceFieldEnum]
export const ConsumerDevicesOrderByRelevanceFieldEnum = { export const ConsumerAccountDeviceOrderByRelevanceFieldEnum = {
uuid: 'uuid', id: 'id',
app_version: 'app_version', device_id: 'device_id',
build_number: 'build_number', device_name: 'device_name',
platform: 'platform', consumer_account_id: 'consumer_account_id'
brand: 'brand',
model: 'model',
device: 'device',
os_version: 'os_version',
sdk_version: 'sdk_version',
release_number: 'release_number',
user_agent: 'user_agent',
browser_name: 'browser_name',
fcm_token: 'fcm_token',
consumer_id: 'consumer_id'
} as const } as const
export type ConsumerDevicesOrderByRelevanceFieldEnum = (typeof ConsumerDevicesOrderByRelevanceFieldEnum)[keyof typeof ConsumerDevicesOrderByRelevanceFieldEnum] export type ConsumerAccountDeviceOrderByRelevanceFieldEnum = (typeof ConsumerAccountDeviceOrderByRelevanceFieldEnum)[keyof typeof ConsumerAccountDeviceOrderByRelevanceFieldEnum]
export const JsonNullValueFilter = { export const JsonNullValueFilter = {
@@ -4763,13 +4742,6 @@ export type EnumProviderRoleFieldRefInput<$PrismaModel> = FieldRefInputType<$Pri
/**
* Reference to a field of type 'ApplicationPublisher'
*/
export type EnumApplicationPublisherFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ApplicationPublisher'>
/** /**
* Reference to a field of type 'Boolean' * Reference to a field of type 'Boolean'
*/ */
@@ -5011,7 +4983,7 @@ export type GlobalOmitConfig = {
permissionBusiness?: Prisma.PermissionBusinessOmit permissionBusiness?: Prisma.PermissionBusinessOmit
providerAccount?: Prisma.ProviderAccountOmit providerAccount?: Prisma.ProviderAccountOmit
provider?: Prisma.ProviderOmit provider?: Prisma.ProviderOmit
consumerDevices?: Prisma.ConsumerDevicesOmit consumerAccountDevice?: Prisma.ConsumerAccountDeviceOmit
applicationReleasedInfo?: Prisma.ApplicationReleasedInfoOmit applicationReleasedInfo?: Prisma.ApplicationReleasedInfoOmit
consumerAccount?: Prisma.ConsumerAccountOmit consumerAccount?: Prisma.ConsumerAccountOmit
consumer?: Prisma.ConsumerOmit consumer?: Prisma.ConsumerOmit
@@ -72,7 +72,7 @@ export const ModelName = {
PermissionBusiness: 'PermissionBusiness', PermissionBusiness: 'PermissionBusiness',
ProviderAccount: 'ProviderAccount', ProviderAccount: 'ProviderAccount',
Provider: 'Provider', Provider: 'Provider',
ConsumerDevices: 'ConsumerDevices', ConsumerAccountDevice: 'ConsumerAccountDevice',
ApplicationReleasedInfo: 'ApplicationReleasedInfo', ApplicationReleasedInfo: 'ApplicationReleasedInfo',
ConsumerAccount: 'ConsumerAccount', ConsumerAccount: 'ConsumerAccount',
Consumer: 'Consumer', Consumer: 'Consumer',
@@ -357,27 +357,16 @@ export const ProviderScalarFieldEnum = {
export type ProviderScalarFieldEnum = (typeof ProviderScalarFieldEnum)[keyof typeof ProviderScalarFieldEnum] export type ProviderScalarFieldEnum = (typeof ProviderScalarFieldEnum)[keyof typeof ProviderScalarFieldEnum]
export const ConsumerDevicesScalarFieldEnum = { export const ConsumerAccountDeviceScalarFieldEnum = {
uuid: 'uuid', id: 'id',
app_version: 'app_version', device_id: 'device_id',
build_number: 'build_number', device_name: 'device_name',
platform: 'platform',
brand: 'brand',
model: 'model',
device: 'device',
publisher: 'publisher',
os_version: 'os_version',
sdk_version: 'sdk_version',
release_number: 'release_number',
user_agent: 'user_agent',
browser_name: 'browser_name',
fcm_token: 'fcm_token',
created_at: 'created_at', created_at: 'created_at',
updated_at: 'updated_at', updated_at: 'updated_at',
consumer_id: 'consumer_id' consumer_account_id: 'consumer_account_id'
} as const } as const
export type ConsumerDevicesScalarFieldEnum = (typeof ConsumerDevicesScalarFieldEnum)[keyof typeof ConsumerDevicesScalarFieldEnum] export type ConsumerAccountDeviceScalarFieldEnum = (typeof ConsumerAccountDeviceScalarFieldEnum)[keyof typeof ConsumerAccountDeviceScalarFieldEnum]
export const ApplicationReleasedInfoScalarFieldEnum = { export const ApplicationReleasedInfoScalarFieldEnum = {
@@ -959,24 +948,14 @@ export const ProviderOrderByRelevanceFieldEnum = {
export type ProviderOrderByRelevanceFieldEnum = (typeof ProviderOrderByRelevanceFieldEnum)[keyof typeof ProviderOrderByRelevanceFieldEnum] export type ProviderOrderByRelevanceFieldEnum = (typeof ProviderOrderByRelevanceFieldEnum)[keyof typeof ProviderOrderByRelevanceFieldEnum]
export const ConsumerDevicesOrderByRelevanceFieldEnum = { export const ConsumerAccountDeviceOrderByRelevanceFieldEnum = {
uuid: 'uuid', id: 'id',
app_version: 'app_version', device_id: 'device_id',
build_number: 'build_number', device_name: 'device_name',
platform: 'platform', consumer_account_id: 'consumer_account_id'
brand: 'brand',
model: 'model',
device: 'device',
os_version: 'os_version',
sdk_version: 'sdk_version',
release_number: 'release_number',
user_agent: 'user_agent',
browser_name: 'browser_name',
fcm_token: 'fcm_token',
consumer_id: 'consumer_id'
} as const } as const
export type ConsumerDevicesOrderByRelevanceFieldEnum = (typeof ConsumerDevicesOrderByRelevanceFieldEnum)[keyof typeof ConsumerDevicesOrderByRelevanceFieldEnum] export type ConsumerAccountDeviceOrderByRelevanceFieldEnum = (typeof ConsumerAccountDeviceOrderByRelevanceFieldEnum)[keyof typeof ConsumerAccountDeviceOrderByRelevanceFieldEnum]
export const JsonNullValueFilter = { export const JsonNullValueFilter = {
+1 -1
View File
@@ -29,7 +29,7 @@ export type * from './models/PermissionComplex.js'
export type * from './models/PermissionBusiness.js' export type * from './models/PermissionBusiness.js'
export type * from './models/ProviderAccount.js' export type * from './models/ProviderAccount.js'
export type * from './models/Provider.js' export type * from './models/Provider.js'
export type * from './models/ConsumerDevices.js' export type * from './models/ConsumerAccountDevice.js'
export type * from './models/ApplicationReleasedInfo.js' export type * from './models/ApplicationReleasedInfo.js'
export type * from './models/ConsumerAccount.js' export type * from './models/ConsumerAccount.js'
export type * from './models/Consumer.js' export type * from './models/Consumer.js'
-138
View File
@@ -184,7 +184,6 @@ export type ConsumerWhereInput = {
updated_at?: Prisma.DateTimeFilter<"Consumer"> | Date | string updated_at?: Prisma.DateTimeFilter<"Consumer"> | Date | string
accounts?: Prisma.ConsumerAccountListRelationFilter accounts?: Prisma.ConsumerAccountListRelationFilter
business_activities?: Prisma.BusinessActivityListRelationFilter business_activities?: Prisma.BusinessActivityListRelationFilter
devices?: Prisma.ConsumerDevicesListRelationFilter
individual?: Prisma.XOR<Prisma.ConsumerIndividualNullableScalarRelationFilter, Prisma.ConsumerIndividualWhereInput> | null individual?: Prisma.XOR<Prisma.ConsumerIndividualNullableScalarRelationFilter, Prisma.ConsumerIndividualWhereInput> | null
legal?: Prisma.XOR<Prisma.ConsumerLegalNullableScalarRelationFilter, Prisma.ConsumerLegalWhereInput> | null legal?: Prisma.XOR<Prisma.ConsumerLegalNullableScalarRelationFilter, Prisma.ConsumerLegalWhereInput> | null
} }
@@ -197,7 +196,6 @@ export type ConsumerOrderByWithRelationInput = {
updated_at?: Prisma.SortOrder updated_at?: Prisma.SortOrder
accounts?: Prisma.ConsumerAccountOrderByRelationAggregateInput accounts?: Prisma.ConsumerAccountOrderByRelationAggregateInput
business_activities?: Prisma.BusinessActivityOrderByRelationAggregateInput business_activities?: Prisma.BusinessActivityOrderByRelationAggregateInput
devices?: Prisma.ConsumerDevicesOrderByRelationAggregateInput
individual?: Prisma.ConsumerIndividualOrderByWithRelationInput individual?: Prisma.ConsumerIndividualOrderByWithRelationInput
legal?: Prisma.ConsumerLegalOrderByWithRelationInput legal?: Prisma.ConsumerLegalOrderByWithRelationInput
_relevance?: Prisma.ConsumerOrderByRelevanceInput _relevance?: Prisma.ConsumerOrderByRelevanceInput
@@ -214,7 +212,6 @@ export type ConsumerWhereUniqueInput = Prisma.AtLeast<{
updated_at?: Prisma.DateTimeFilter<"Consumer"> | Date | string updated_at?: Prisma.DateTimeFilter<"Consumer"> | Date | string
accounts?: Prisma.ConsumerAccountListRelationFilter accounts?: Prisma.ConsumerAccountListRelationFilter
business_activities?: Prisma.BusinessActivityListRelationFilter business_activities?: Prisma.BusinessActivityListRelationFilter
devices?: Prisma.ConsumerDevicesListRelationFilter
individual?: Prisma.XOR<Prisma.ConsumerIndividualNullableScalarRelationFilter, Prisma.ConsumerIndividualWhereInput> | null individual?: Prisma.XOR<Prisma.ConsumerIndividualNullableScalarRelationFilter, Prisma.ConsumerIndividualWhereInput> | null
legal?: Prisma.XOR<Prisma.ConsumerLegalNullableScalarRelationFilter, Prisma.ConsumerLegalWhereInput> | null legal?: Prisma.XOR<Prisma.ConsumerLegalNullableScalarRelationFilter, Prisma.ConsumerLegalWhereInput> | null
}, "id"> }, "id">
@@ -249,7 +246,6 @@ export type ConsumerCreateInput = {
updated_at?: Date | string updated_at?: Date | string
accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput
business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput
legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput
} }
@@ -262,7 +258,6 @@ export type ConsumerUncheckedCreateInput = {
updated_at?: Date | string updated_at?: Date | string
accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput
business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesUncheckedCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput
legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput
} }
@@ -275,7 +270,6 @@ export type ConsumerUpdateInput = {
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput
business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput
} }
@@ -288,7 +282,6 @@ export type ConsumerUncheckedUpdateInput = {
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput
business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUncheckedUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput
} }
@@ -352,20 +345,6 @@ export type ConsumerMinOrderByAggregateInput = {
updated_at?: Prisma.SortOrder updated_at?: Prisma.SortOrder
} }
export type ConsumerCreateNestedOneWithoutDevicesInput = {
create?: Prisma.XOR<Prisma.ConsumerCreateWithoutDevicesInput, Prisma.ConsumerUncheckedCreateWithoutDevicesInput>
connectOrCreate?: Prisma.ConsumerCreateOrConnectWithoutDevicesInput
connect?: Prisma.ConsumerWhereUniqueInput
}
export type ConsumerUpdateOneRequiredWithoutDevicesNestedInput = {
create?: Prisma.XOR<Prisma.ConsumerCreateWithoutDevicesInput, Prisma.ConsumerUncheckedCreateWithoutDevicesInput>
connectOrCreate?: Prisma.ConsumerCreateOrConnectWithoutDevicesInput
upsert?: Prisma.ConsumerUpsertWithoutDevicesInput
connect?: Prisma.ConsumerWhereUniqueInput
update?: Prisma.XOR<Prisma.XOR<Prisma.ConsumerUpdateToOneWithWhereWithoutDevicesInput, Prisma.ConsumerUpdateWithoutDevicesInput>, Prisma.ConsumerUncheckedUpdateWithoutDevicesInput>
}
export type ConsumerCreateNestedOneWithoutAccountsInput = { export type ConsumerCreateNestedOneWithoutAccountsInput = {
create?: Prisma.XOR<Prisma.ConsumerCreateWithoutAccountsInput, Prisma.ConsumerUncheckedCreateWithoutAccountsInput> create?: Prisma.XOR<Prisma.ConsumerCreateWithoutAccountsInput, Prisma.ConsumerUncheckedCreateWithoutAccountsInput>
connectOrCreate?: Prisma.ConsumerCreateOrConnectWithoutAccountsInput connectOrCreate?: Prisma.ConsumerCreateOrConnectWithoutAccountsInput
@@ -430,70 +409,6 @@ export type ConsumerUpdateOneRequiredWithoutBusiness_activitiesNestedInput = {
update?: Prisma.XOR<Prisma.XOR<Prisma.ConsumerUpdateToOneWithWhereWithoutBusiness_activitiesInput, Prisma.ConsumerUpdateWithoutBusiness_activitiesInput>, Prisma.ConsumerUncheckedUpdateWithoutBusiness_activitiesInput> update?: Prisma.XOR<Prisma.XOR<Prisma.ConsumerUpdateToOneWithWhereWithoutBusiness_activitiesInput, Prisma.ConsumerUpdateWithoutBusiness_activitiesInput>, Prisma.ConsumerUncheckedUpdateWithoutBusiness_activitiesInput>
} }
export type ConsumerCreateWithoutDevicesInput = {
id?: string
type: $Enums.ConsumerType
status?: $Enums.ConsumerStatus
created_at?: Date | string
updated_at?: Date | string
accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput
business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput
legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput
}
export type ConsumerUncheckedCreateWithoutDevicesInput = {
id?: string
type: $Enums.ConsumerType
status?: $Enums.ConsumerStatus
created_at?: Date | string
updated_at?: Date | string
accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput
business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput
legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput
}
export type ConsumerCreateOrConnectWithoutDevicesInput = {
where: Prisma.ConsumerWhereUniqueInput
create: Prisma.XOR<Prisma.ConsumerCreateWithoutDevicesInput, Prisma.ConsumerUncheckedCreateWithoutDevicesInput>
}
export type ConsumerUpsertWithoutDevicesInput = {
update: Prisma.XOR<Prisma.ConsumerUpdateWithoutDevicesInput, Prisma.ConsumerUncheckedUpdateWithoutDevicesInput>
create: Prisma.XOR<Prisma.ConsumerCreateWithoutDevicesInput, Prisma.ConsumerUncheckedCreateWithoutDevicesInput>
where?: Prisma.ConsumerWhereInput
}
export type ConsumerUpdateToOneWithWhereWithoutDevicesInput = {
where?: Prisma.ConsumerWhereInput
data: Prisma.XOR<Prisma.ConsumerUpdateWithoutDevicesInput, Prisma.ConsumerUncheckedUpdateWithoutDevicesInput>
}
export type ConsumerUpdateWithoutDevicesInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
type?: Prisma.EnumConsumerTypeFieldUpdateOperationsInput | $Enums.ConsumerType
status?: Prisma.EnumConsumerStatusFieldUpdateOperationsInput | $Enums.ConsumerStatus
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput
business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput
}
export type ConsumerUncheckedUpdateWithoutDevicesInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
type?: Prisma.EnumConsumerTypeFieldUpdateOperationsInput | $Enums.ConsumerType
status?: Prisma.EnumConsumerStatusFieldUpdateOperationsInput | $Enums.ConsumerStatus
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput
business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput
}
export type ConsumerCreateWithoutAccountsInput = { export type ConsumerCreateWithoutAccountsInput = {
id?: string id?: string
type: $Enums.ConsumerType type: $Enums.ConsumerType
@@ -501,7 +416,6 @@ export type ConsumerCreateWithoutAccountsInput = {
created_at?: Date | string created_at?: Date | string
updated_at?: Date | string updated_at?: Date | string
business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput
legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput
} }
@@ -513,7 +427,6 @@ export type ConsumerUncheckedCreateWithoutAccountsInput = {
created_at?: Date | string created_at?: Date | string
updated_at?: Date | string updated_at?: Date | string
business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesUncheckedCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput
legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput
} }
@@ -541,7 +454,6 @@ export type ConsumerUpdateWithoutAccountsInput = {
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput
} }
@@ -553,7 +465,6 @@ export type ConsumerUncheckedUpdateWithoutAccountsInput = {
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUncheckedUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput
} }
@@ -566,7 +477,6 @@ export type ConsumerCreateWithoutIndividualInput = {
updated_at?: Date | string updated_at?: Date | string
accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput
business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesCreateNestedManyWithoutConsumerInput
legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput
} }
@@ -578,7 +488,6 @@ export type ConsumerUncheckedCreateWithoutIndividualInput = {
updated_at?: Date | string updated_at?: Date | string
accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput
business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesUncheckedCreateNestedManyWithoutConsumerInput
legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput
} }
@@ -606,7 +515,6 @@ export type ConsumerUpdateWithoutIndividualInput = {
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput
business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUpdateManyWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput
} }
@@ -618,7 +526,6 @@ export type ConsumerUncheckedUpdateWithoutIndividualInput = {
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput
business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUncheckedUpdateManyWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput
} }
@@ -630,7 +537,6 @@ export type ConsumerCreateWithoutLegalInput = {
updated_at?: Date | string updated_at?: Date | string
accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput
business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput business_activities?: Prisma.BusinessActivityCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput
} }
@@ -642,7 +548,6 @@ export type ConsumerUncheckedCreateWithoutLegalInput = {
updated_at?: Date | string updated_at?: Date | string
accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput
business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput business_activities?: Prisma.BusinessActivityUncheckedCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesUncheckedCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput
} }
@@ -670,7 +575,6 @@ export type ConsumerUpdateWithoutLegalInput = {
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput
business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput business_activities?: Prisma.BusinessActivityUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput
} }
@@ -682,7 +586,6 @@ export type ConsumerUncheckedUpdateWithoutLegalInput = {
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput
business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput business_activities?: Prisma.BusinessActivityUncheckedUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUncheckedUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput
} }
@@ -693,7 +596,6 @@ export type ConsumerCreateWithoutBusiness_activitiesInput = {
created_at?: Date | string created_at?: Date | string
updated_at?: Date | string updated_at?: Date | string
accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput accounts?: Prisma.ConsumerAccountCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput individual?: Prisma.ConsumerIndividualCreateNestedOneWithoutConsumerInput
legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput legal?: Prisma.ConsumerLegalCreateNestedOneWithoutConsumerInput
} }
@@ -705,7 +607,6 @@ export type ConsumerUncheckedCreateWithoutBusiness_activitiesInput = {
created_at?: Date | string created_at?: Date | string
updated_at?: Date | string updated_at?: Date | string
accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput accounts?: Prisma.ConsumerAccountUncheckedCreateNestedManyWithoutConsumerInput
devices?: Prisma.ConsumerDevicesUncheckedCreateNestedManyWithoutConsumerInput
individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput individual?: Prisma.ConsumerIndividualUncheckedCreateNestedOneWithoutConsumerInput
legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput legal?: Prisma.ConsumerLegalUncheckedCreateNestedOneWithoutConsumerInput
} }
@@ -733,7 +634,6 @@ export type ConsumerUpdateWithoutBusiness_activitiesInput = {
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput accounts?: Prisma.ConsumerAccountUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput individual?: Prisma.ConsumerIndividualUpdateOneWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput legal?: Prisma.ConsumerLegalUpdateOneWithoutConsumerNestedInput
} }
@@ -745,7 +645,6 @@ export type ConsumerUncheckedUpdateWithoutBusiness_activitiesInput = {
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput accounts?: Prisma.ConsumerAccountUncheckedUpdateManyWithoutConsumerNestedInput
devices?: Prisma.ConsumerDevicesUncheckedUpdateManyWithoutConsumerNestedInput
individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput individual?: Prisma.ConsumerIndividualUncheckedUpdateOneWithoutConsumerNestedInput
legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput legal?: Prisma.ConsumerLegalUncheckedUpdateOneWithoutConsumerNestedInput
} }
@@ -758,13 +657,11 @@ export type ConsumerUncheckedUpdateWithoutBusiness_activitiesInput = {
export type ConsumerCountOutputType = { export type ConsumerCountOutputType = {
accounts: number accounts: number
business_activities: number business_activities: number
devices: number
} }
export type ConsumerCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { export type ConsumerCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
accounts?: boolean | ConsumerCountOutputTypeCountAccountsArgs accounts?: boolean | ConsumerCountOutputTypeCountAccountsArgs
business_activities?: boolean | ConsumerCountOutputTypeCountBusiness_activitiesArgs business_activities?: boolean | ConsumerCountOutputTypeCountBusiness_activitiesArgs
devices?: boolean | ConsumerCountOutputTypeCountDevicesArgs
} }
/** /**
@@ -791,13 +688,6 @@ export type ConsumerCountOutputTypeCountBusiness_activitiesArgs<ExtArgs extends
where?: Prisma.BusinessActivityWhereInput where?: Prisma.BusinessActivityWhereInput
} }
/**
* ConsumerCountOutputType without action
*/
export type ConsumerCountOutputTypeCountDevicesArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
where?: Prisma.ConsumerDevicesWhereInput
}
export type ConsumerSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ export type ConsumerSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
id?: boolean id?: boolean
@@ -807,7 +697,6 @@ export type ConsumerSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs
updated_at?: boolean updated_at?: boolean
accounts?: boolean | Prisma.Consumer$accountsArgs<ExtArgs> accounts?: boolean | Prisma.Consumer$accountsArgs<ExtArgs>
business_activities?: boolean | Prisma.Consumer$business_activitiesArgs<ExtArgs> business_activities?: boolean | Prisma.Consumer$business_activitiesArgs<ExtArgs>
devices?: boolean | Prisma.Consumer$devicesArgs<ExtArgs>
individual?: boolean | Prisma.Consumer$individualArgs<ExtArgs> individual?: boolean | Prisma.Consumer$individualArgs<ExtArgs>
legal?: boolean | Prisma.Consumer$legalArgs<ExtArgs> legal?: boolean | Prisma.Consumer$legalArgs<ExtArgs>
_count?: boolean | Prisma.ConsumerCountOutputTypeDefaultArgs<ExtArgs> _count?: boolean | Prisma.ConsumerCountOutputTypeDefaultArgs<ExtArgs>
@@ -827,7 +716,6 @@ export type ConsumerOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs =
export type ConsumerInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { export type ConsumerInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
accounts?: boolean | Prisma.Consumer$accountsArgs<ExtArgs> accounts?: boolean | Prisma.Consumer$accountsArgs<ExtArgs>
business_activities?: boolean | Prisma.Consumer$business_activitiesArgs<ExtArgs> business_activities?: boolean | Prisma.Consumer$business_activitiesArgs<ExtArgs>
devices?: boolean | Prisma.Consumer$devicesArgs<ExtArgs>
individual?: boolean | Prisma.Consumer$individualArgs<ExtArgs> individual?: boolean | Prisma.Consumer$individualArgs<ExtArgs>
legal?: boolean | Prisma.Consumer$legalArgs<ExtArgs> legal?: boolean | Prisma.Consumer$legalArgs<ExtArgs>
_count?: boolean | Prisma.ConsumerCountOutputTypeDefaultArgs<ExtArgs> _count?: boolean | Prisma.ConsumerCountOutputTypeDefaultArgs<ExtArgs>
@@ -838,7 +726,6 @@ export type $ConsumerPayload<ExtArgs extends runtime.Types.Extensions.InternalAr
objects: { objects: {
accounts: Prisma.$ConsumerAccountPayload<ExtArgs>[] accounts: Prisma.$ConsumerAccountPayload<ExtArgs>[]
business_activities: Prisma.$BusinessActivityPayload<ExtArgs>[] business_activities: Prisma.$BusinessActivityPayload<ExtArgs>[]
devices: Prisma.$ConsumerDevicesPayload<ExtArgs>[]
individual: Prisma.$ConsumerIndividualPayload<ExtArgs> | null individual: Prisma.$ConsumerIndividualPayload<ExtArgs> | null
legal: Prisma.$ConsumerLegalPayload<ExtArgs> | null legal: Prisma.$ConsumerLegalPayload<ExtArgs> | null
} }
@@ -1190,7 +1077,6 @@ export interface Prisma__ConsumerClient<T, Null = never, ExtArgs extends runtime
readonly [Symbol.toStringTag]: "PrismaPromise" readonly [Symbol.toStringTag]: "PrismaPromise"
accounts<T extends Prisma.Consumer$accountsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$accountsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ConsumerAccountPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> accounts<T extends Prisma.Consumer$accountsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$accountsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ConsumerAccountPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
business_activities<T extends Prisma.Consumer$business_activitiesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$business_activitiesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$BusinessActivityPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> business_activities<T extends Prisma.Consumer$business_activitiesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$business_activitiesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$BusinessActivityPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
devices<T extends Prisma.Consumer$devicesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$devicesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ConsumerDevicesPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
individual<T extends Prisma.Consumer$individualArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$individualArgs<ExtArgs>>): Prisma.Prisma__ConsumerIndividualClient<runtime.Types.Result.GetResult<Prisma.$ConsumerIndividualPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> individual<T extends Prisma.Consumer$individualArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$individualArgs<ExtArgs>>): Prisma.Prisma__ConsumerIndividualClient<runtime.Types.Result.GetResult<Prisma.$ConsumerIndividualPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
legal<T extends Prisma.Consumer$legalArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$legalArgs<ExtArgs>>): Prisma.Prisma__ConsumerLegalClient<runtime.Types.Result.GetResult<Prisma.$ConsumerLegalPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> legal<T extends Prisma.Consumer$legalArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Consumer$legalArgs<ExtArgs>>): Prisma.Prisma__ConsumerLegalClient<runtime.Types.Result.GetResult<Prisma.$ConsumerLegalPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
/** /**
@@ -1622,30 +1508,6 @@ export type Consumer$business_activitiesArgs<ExtArgs extends runtime.Types.Exten
distinct?: Prisma.BusinessActivityScalarFieldEnum | Prisma.BusinessActivityScalarFieldEnum[] distinct?: Prisma.BusinessActivityScalarFieldEnum | Prisma.BusinessActivityScalarFieldEnum[]
} }
/**
* Consumer.devices
*/
export type Consumer$devicesArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
/**
* Select specific fields to fetch from the ConsumerDevices
*/
select?: Prisma.ConsumerDevicesSelect<ExtArgs> | null
/**
* Omit specific fields from the ConsumerDevices
*/
omit?: Prisma.ConsumerDevicesOmit<ExtArgs> | null
/**
* Choose, which related nodes to fetch as well
*/
include?: Prisma.ConsumerDevicesInclude<ExtArgs> | null
where?: Prisma.ConsumerDevicesWhereInput
orderBy?: Prisma.ConsumerDevicesOrderByWithRelationInput | Prisma.ConsumerDevicesOrderByWithRelationInput[]
cursor?: Prisma.ConsumerDevicesWhereUniqueInput
take?: number
skip?: number
distinct?: Prisma.ConsumerDevicesScalarFieldEnum | Prisma.ConsumerDevicesScalarFieldEnum[]
}
/** /**
* Consumer.individual * Consumer.individual
*/ */
@@ -196,6 +196,7 @@ export type ConsumerAccountWhereInput = {
permission?: Prisma.XOR<Prisma.PermissionConsumerNullableScalarRelationFilter, Prisma.PermissionConsumerWhereInput> | null permission?: Prisma.XOR<Prisma.PermissionConsumerNullableScalarRelationFilter, Prisma.PermissionConsumerWhereInput> | null
account_allocation?: Prisma.XOR<Prisma.LicenseAccountAllocationNullableScalarRelationFilter, Prisma.LicenseAccountAllocationWhereInput> | null account_allocation?: Prisma.XOR<Prisma.LicenseAccountAllocationNullableScalarRelationFilter, Prisma.LicenseAccountAllocationWhereInput> | null
sales_invoices?: Prisma.SalesInvoiceListRelationFilter sales_invoices?: Prisma.SalesInvoiceListRelationFilter
account_device?: Prisma.XOR<Prisma.ConsumerAccountDeviceNullableScalarRelationFilter, Prisma.ConsumerAccountDeviceWhereInput> | null
} }
export type ConsumerAccountOrderByWithRelationInput = { export type ConsumerAccountOrderByWithRelationInput = {
@@ -211,6 +212,7 @@ export type ConsumerAccountOrderByWithRelationInput = {
permission?: Prisma.PermissionConsumerOrderByWithRelationInput permission?: Prisma.PermissionConsumerOrderByWithRelationInput
account_allocation?: Prisma.LicenseAccountAllocationOrderByWithRelationInput account_allocation?: Prisma.LicenseAccountAllocationOrderByWithRelationInput
sales_invoices?: Prisma.SalesInvoiceOrderByRelationAggregateInput sales_invoices?: Prisma.SalesInvoiceOrderByRelationAggregateInput
account_device?: Prisma.ConsumerAccountDeviceOrderByWithRelationInput
_relevance?: Prisma.ConsumerAccountOrderByRelevanceInput _relevance?: Prisma.ConsumerAccountOrderByRelevanceInput
} }
@@ -230,6 +232,7 @@ export type ConsumerAccountWhereUniqueInput = Prisma.AtLeast<{
permission?: Prisma.XOR<Prisma.PermissionConsumerNullableScalarRelationFilter, Prisma.PermissionConsumerWhereInput> | null permission?: Prisma.XOR<Prisma.PermissionConsumerNullableScalarRelationFilter, Prisma.PermissionConsumerWhereInput> | null
account_allocation?: Prisma.XOR<Prisma.LicenseAccountAllocationNullableScalarRelationFilter, Prisma.LicenseAccountAllocationWhereInput> | null account_allocation?: Prisma.XOR<Prisma.LicenseAccountAllocationNullableScalarRelationFilter, Prisma.LicenseAccountAllocationWhereInput> | null
sales_invoices?: Prisma.SalesInvoiceListRelationFilter sales_invoices?: Prisma.SalesInvoiceListRelationFilter
account_device?: Prisma.XOR<Prisma.ConsumerAccountDeviceNullableScalarRelationFilter, Prisma.ConsumerAccountDeviceWhereInput> | null
}, "id" | "account_id"> }, "id" | "account_id">
export type ConsumerAccountOrderByWithAggregationInput = { export type ConsumerAccountOrderByWithAggregationInput = {
@@ -267,6 +270,7 @@ export type ConsumerAccountCreateInput = {
permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountUncheckedCreateInput = { export type ConsumerAccountUncheckedCreateInput = {
@@ -280,6 +284,7 @@ export type ConsumerAccountUncheckedCreateInput = {
permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountUpdateInput = { export type ConsumerAccountUpdateInput = {
@@ -293,6 +298,7 @@ export type ConsumerAccountUpdateInput = {
permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountUncheckedUpdateInput = { export type ConsumerAccountUncheckedUpdateInput = {
@@ -306,6 +312,7 @@ export type ConsumerAccountUncheckedUpdateInput = {
permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountCreateManyInput = { export type ConsumerAccountCreateManyInput = {
@@ -448,6 +455,20 @@ export type ConsumerAccountUpdateOneRequiredWithoutPermissionNestedInput = {
update?: Prisma.XOR<Prisma.XOR<Prisma.ConsumerAccountUpdateToOneWithWhereWithoutPermissionInput, Prisma.ConsumerAccountUpdateWithoutPermissionInput>, Prisma.ConsumerAccountUncheckedUpdateWithoutPermissionInput> update?: Prisma.XOR<Prisma.XOR<Prisma.ConsumerAccountUpdateToOneWithWhereWithoutPermissionInput, Prisma.ConsumerAccountUpdateWithoutPermissionInput>, Prisma.ConsumerAccountUncheckedUpdateWithoutPermissionInput>
} }
export type ConsumerAccountCreateNestedOneWithoutAccount_deviceInput = {
create?: Prisma.XOR<Prisma.ConsumerAccountCreateWithoutAccount_deviceInput, Prisma.ConsumerAccountUncheckedCreateWithoutAccount_deviceInput>
connectOrCreate?: Prisma.ConsumerAccountCreateOrConnectWithoutAccount_deviceInput
connect?: Prisma.ConsumerAccountWhereUniqueInput
}
export type ConsumerAccountUpdateOneRequiredWithoutAccount_deviceNestedInput = {
create?: Prisma.XOR<Prisma.ConsumerAccountCreateWithoutAccount_deviceInput, Prisma.ConsumerAccountUncheckedCreateWithoutAccount_deviceInput>
connectOrCreate?: Prisma.ConsumerAccountCreateOrConnectWithoutAccount_deviceInput
upsert?: Prisma.ConsumerAccountUpsertWithoutAccount_deviceInput
connect?: Prisma.ConsumerAccountWhereUniqueInput
update?: Prisma.XOR<Prisma.XOR<Prisma.ConsumerAccountUpdateToOneWithWhereWithoutAccount_deviceInput, Prisma.ConsumerAccountUpdateWithoutAccount_deviceInput>, Prisma.ConsumerAccountUncheckedUpdateWithoutAccount_deviceInput>
}
export type EnumConsumerRoleFieldUpdateOperationsInput = { export type EnumConsumerRoleFieldUpdateOperationsInput = {
set?: $Enums.ConsumerRole set?: $Enums.ConsumerRole
} }
@@ -532,6 +553,7 @@ export type ConsumerAccountCreateWithoutAccountInput = {
permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountUncheckedCreateWithoutAccountInput = { export type ConsumerAccountUncheckedCreateWithoutAccountInput = {
@@ -544,6 +566,7 @@ export type ConsumerAccountUncheckedCreateWithoutAccountInput = {
permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountCreateOrConnectWithoutAccountInput = { export type ConsumerAccountCreateOrConnectWithoutAccountInput = {
@@ -572,6 +595,7 @@ export type ConsumerAccountUpdateWithoutAccountInput = {
permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountUncheckedUpdateWithoutAccountInput = { export type ConsumerAccountUncheckedUpdateWithoutAccountInput = {
@@ -584,6 +608,7 @@ export type ConsumerAccountUncheckedUpdateWithoutAccountInput = {
permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountCreateWithoutAccount_allocationInput = { export type ConsumerAccountCreateWithoutAccount_allocationInput = {
@@ -596,6 +621,7 @@ export type ConsumerAccountCreateWithoutAccount_allocationInput = {
pos?: Prisma.PosCreateNestedOneWithoutAccountInput pos?: Prisma.PosCreateNestedOneWithoutAccountInput
permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput
sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountUncheckedCreateWithoutAccount_allocationInput = { export type ConsumerAccountUncheckedCreateWithoutAccount_allocationInput = {
@@ -608,6 +634,7 @@ export type ConsumerAccountUncheckedCreateWithoutAccount_allocationInput = {
pos?: Prisma.PosUncheckedCreateNestedOneWithoutAccountInput pos?: Prisma.PosUncheckedCreateNestedOneWithoutAccountInput
permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput
sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountCreateOrConnectWithoutAccount_allocationInput = { export type ConsumerAccountCreateOrConnectWithoutAccount_allocationInput = {
@@ -636,6 +663,7 @@ export type ConsumerAccountUpdateWithoutAccount_allocationInput = {
pos?: Prisma.PosUpdateOneWithoutAccountNestedInput pos?: Prisma.PosUpdateOneWithoutAccountNestedInput
permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput
sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountUncheckedUpdateWithoutAccount_allocationInput = { export type ConsumerAccountUncheckedUpdateWithoutAccount_allocationInput = {
@@ -648,6 +676,7 @@ export type ConsumerAccountUncheckedUpdateWithoutAccount_allocationInput = {
pos?: Prisma.PosUncheckedUpdateOneWithoutAccountNestedInput pos?: Prisma.PosUncheckedUpdateOneWithoutAccountNestedInput
permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput
sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountCreateWithoutPermissionInput = { export type ConsumerAccountCreateWithoutPermissionInput = {
@@ -660,6 +689,7 @@ export type ConsumerAccountCreateWithoutPermissionInput = {
pos?: Prisma.PosCreateNestedOneWithoutAccountInput pos?: Prisma.PosCreateNestedOneWithoutAccountInput
account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountUncheckedCreateWithoutPermissionInput = { export type ConsumerAccountUncheckedCreateWithoutPermissionInput = {
@@ -672,6 +702,7 @@ export type ConsumerAccountUncheckedCreateWithoutPermissionInput = {
pos?: Prisma.PosUncheckedCreateNestedOneWithoutAccountInput pos?: Prisma.PosUncheckedCreateNestedOneWithoutAccountInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountCreateOrConnectWithoutPermissionInput = { export type ConsumerAccountCreateOrConnectWithoutPermissionInput = {
@@ -700,6 +731,7 @@ export type ConsumerAccountUpdateWithoutPermissionInput = {
pos?: Prisma.PosUpdateOneWithoutAccountNestedInput pos?: Prisma.PosUpdateOneWithoutAccountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountUncheckedUpdateWithoutPermissionInput = { export type ConsumerAccountUncheckedUpdateWithoutPermissionInput = {
@@ -712,6 +744,75 @@ export type ConsumerAccountUncheckedUpdateWithoutPermissionInput = {
pos?: Prisma.PosUncheckedUpdateOneWithoutAccountNestedInput pos?: Prisma.PosUncheckedUpdateOneWithoutAccountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedUpdateOneWithoutConsumer_accountNestedInput
}
export type ConsumerAccountCreateWithoutAccount_deviceInput = {
id?: string
role: $Enums.ConsumerRole
created_at?: Date | string
updated_at?: Date | string
consumer: Prisma.ConsumerCreateNestedOneWithoutAccountsInput
account: Prisma.AccountCreateNestedOneWithoutConsumer_accountInput
pos?: Prisma.PosCreateNestedOneWithoutAccountInput
permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput
}
export type ConsumerAccountUncheckedCreateWithoutAccount_deviceInput = {
id?: string
role: $Enums.ConsumerRole
created_at?: Date | string
updated_at?: Date | string
consumer_id: string
account_id: string
pos?: Prisma.PosUncheckedCreateNestedOneWithoutAccountInput
permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput
}
export type ConsumerAccountCreateOrConnectWithoutAccount_deviceInput = {
where: Prisma.ConsumerAccountWhereUniqueInput
create: Prisma.XOR<Prisma.ConsumerAccountCreateWithoutAccount_deviceInput, Prisma.ConsumerAccountUncheckedCreateWithoutAccount_deviceInput>
}
export type ConsumerAccountUpsertWithoutAccount_deviceInput = {
update: Prisma.XOR<Prisma.ConsumerAccountUpdateWithoutAccount_deviceInput, Prisma.ConsumerAccountUncheckedUpdateWithoutAccount_deviceInput>
create: Prisma.XOR<Prisma.ConsumerAccountCreateWithoutAccount_deviceInput, Prisma.ConsumerAccountUncheckedCreateWithoutAccount_deviceInput>
where?: Prisma.ConsumerAccountWhereInput
}
export type ConsumerAccountUpdateToOneWithWhereWithoutAccount_deviceInput = {
where?: Prisma.ConsumerAccountWhereInput
data: Prisma.XOR<Prisma.ConsumerAccountUpdateWithoutAccount_deviceInput, Prisma.ConsumerAccountUncheckedUpdateWithoutAccount_deviceInput>
}
export type ConsumerAccountUpdateWithoutAccount_deviceInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
role?: Prisma.EnumConsumerRoleFieldUpdateOperationsInput | $Enums.ConsumerRole
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
consumer?: Prisma.ConsumerUpdateOneRequiredWithoutAccountsNestedInput
account?: Prisma.AccountUpdateOneRequiredWithoutConsumer_accountNestedInput
pos?: Prisma.PosUpdateOneWithoutAccountNestedInput
permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput
}
export type ConsumerAccountUncheckedUpdateWithoutAccount_deviceInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
role?: Prisma.EnumConsumerRoleFieldUpdateOperationsInput | $Enums.ConsumerRole
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updated_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
consumer_id?: Prisma.StringFieldUpdateOperationsInput | string
account_id?: Prisma.StringFieldUpdateOperationsInput | string
pos?: Prisma.PosUncheckedUpdateOneWithoutAccountNestedInput
permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountCreateWithoutConsumerInput = { export type ConsumerAccountCreateWithoutConsumerInput = {
@@ -724,6 +825,7 @@ export type ConsumerAccountCreateWithoutConsumerInput = {
permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountUncheckedCreateWithoutConsumerInput = { export type ConsumerAccountUncheckedCreateWithoutConsumerInput = {
@@ -736,6 +838,7 @@ export type ConsumerAccountUncheckedCreateWithoutConsumerInput = {
permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountCreateOrConnectWithoutConsumerInput = { export type ConsumerAccountCreateOrConnectWithoutConsumerInput = {
@@ -786,6 +889,7 @@ export type ConsumerAccountCreateWithoutPosInput = {
permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountUncheckedCreateWithoutPosInput = { export type ConsumerAccountUncheckedCreateWithoutPosInput = {
@@ -798,6 +902,7 @@ export type ConsumerAccountUncheckedCreateWithoutPosInput = {
permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput
sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput sales_invoices?: Prisma.SalesInvoiceUncheckedCreateNestedManyWithoutConsumer_accountInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountCreateOrConnectWithoutPosInput = { export type ConsumerAccountCreateOrConnectWithoutPosInput = {
@@ -826,6 +931,7 @@ export type ConsumerAccountUpdateWithoutPosInput = {
permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountUncheckedUpdateWithoutPosInput = { export type ConsumerAccountUncheckedUpdateWithoutPosInput = {
@@ -838,6 +944,7 @@ export type ConsumerAccountUncheckedUpdateWithoutPosInput = {
permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountCreateWithoutSales_invoicesInput = { export type ConsumerAccountCreateWithoutSales_invoicesInput = {
@@ -850,6 +957,7 @@ export type ConsumerAccountCreateWithoutSales_invoicesInput = {
pos?: Prisma.PosCreateNestedOneWithoutAccountInput pos?: Prisma.PosCreateNestedOneWithoutAccountInput
permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationCreateNestedOneWithoutAccountInput
account_device?: Prisma.ConsumerAccountDeviceCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountUncheckedCreateWithoutSales_invoicesInput = { export type ConsumerAccountUncheckedCreateWithoutSales_invoicesInput = {
@@ -862,6 +970,7 @@ export type ConsumerAccountUncheckedCreateWithoutSales_invoicesInput = {
pos?: Prisma.PosUncheckedCreateNestedOneWithoutAccountInput pos?: Prisma.PosUncheckedCreateNestedOneWithoutAccountInput
permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput permission?: Prisma.PermissionConsumerUncheckedCreateNestedOneWithoutConsumer_accountInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedCreateNestedOneWithoutAccountInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedCreateNestedOneWithoutConsumer_accountInput
} }
export type ConsumerAccountCreateOrConnectWithoutSales_invoicesInput = { export type ConsumerAccountCreateOrConnectWithoutSales_invoicesInput = {
@@ -890,6 +999,7 @@ export type ConsumerAccountUpdateWithoutSales_invoicesInput = {
pos?: Prisma.PosUpdateOneWithoutAccountNestedInput pos?: Prisma.PosUpdateOneWithoutAccountNestedInput
permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountUncheckedUpdateWithoutSales_invoicesInput = { export type ConsumerAccountUncheckedUpdateWithoutSales_invoicesInput = {
@@ -902,6 +1012,7 @@ export type ConsumerAccountUncheckedUpdateWithoutSales_invoicesInput = {
pos?: Prisma.PosUncheckedUpdateOneWithoutAccountNestedInput pos?: Prisma.PosUncheckedUpdateOneWithoutAccountNestedInput
permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountCreateManyConsumerInput = { export type ConsumerAccountCreateManyConsumerInput = {
@@ -922,6 +1033,7 @@ export type ConsumerAccountUpdateWithoutConsumerInput = {
permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountUncheckedUpdateWithoutConsumerInput = { export type ConsumerAccountUncheckedUpdateWithoutConsumerInput = {
@@ -934,6 +1046,7 @@ export type ConsumerAccountUncheckedUpdateWithoutConsumerInput = {
permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput permission?: Prisma.PermissionConsumerUncheckedUpdateOneWithoutConsumer_accountNestedInput
account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput account_allocation?: Prisma.LicenseAccountAllocationUncheckedUpdateOneWithoutAccountNestedInput
sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput sales_invoices?: Prisma.SalesInvoiceUncheckedUpdateManyWithoutConsumer_accountNestedInput
account_device?: Prisma.ConsumerAccountDeviceUncheckedUpdateOneWithoutConsumer_accountNestedInput
} }
export type ConsumerAccountUncheckedUpdateManyWithoutConsumerInput = { export type ConsumerAccountUncheckedUpdateManyWithoutConsumerInput = {
@@ -988,6 +1101,7 @@ export type ConsumerAccountSelect<ExtArgs extends runtime.Types.Extensions.Inter
permission?: boolean | Prisma.ConsumerAccount$permissionArgs<ExtArgs> permission?: boolean | Prisma.ConsumerAccount$permissionArgs<ExtArgs>
account_allocation?: boolean | Prisma.ConsumerAccount$account_allocationArgs<ExtArgs> account_allocation?: boolean | Prisma.ConsumerAccount$account_allocationArgs<ExtArgs>
sales_invoices?: boolean | Prisma.ConsumerAccount$sales_invoicesArgs<ExtArgs> sales_invoices?: boolean | Prisma.ConsumerAccount$sales_invoicesArgs<ExtArgs>
account_device?: boolean | Prisma.ConsumerAccount$account_deviceArgs<ExtArgs>
_count?: boolean | Prisma.ConsumerAccountCountOutputTypeDefaultArgs<ExtArgs> _count?: boolean | Prisma.ConsumerAccountCountOutputTypeDefaultArgs<ExtArgs>
}, ExtArgs["result"]["consumerAccount"]> }, ExtArgs["result"]["consumerAccount"]>
@@ -1010,6 +1124,7 @@ export type ConsumerAccountInclude<ExtArgs extends runtime.Types.Extensions.Inte
permission?: boolean | Prisma.ConsumerAccount$permissionArgs<ExtArgs> permission?: boolean | Prisma.ConsumerAccount$permissionArgs<ExtArgs>
account_allocation?: boolean | Prisma.ConsumerAccount$account_allocationArgs<ExtArgs> account_allocation?: boolean | Prisma.ConsumerAccount$account_allocationArgs<ExtArgs>
sales_invoices?: boolean | Prisma.ConsumerAccount$sales_invoicesArgs<ExtArgs> sales_invoices?: boolean | Prisma.ConsumerAccount$sales_invoicesArgs<ExtArgs>
account_device?: boolean | Prisma.ConsumerAccount$account_deviceArgs<ExtArgs>
_count?: boolean | Prisma.ConsumerAccountCountOutputTypeDefaultArgs<ExtArgs> _count?: boolean | Prisma.ConsumerAccountCountOutputTypeDefaultArgs<ExtArgs>
} }
@@ -1022,6 +1137,7 @@ export type $ConsumerAccountPayload<ExtArgs extends runtime.Types.Extensions.Int
permission: Prisma.$PermissionConsumerPayload<ExtArgs> | null permission: Prisma.$PermissionConsumerPayload<ExtArgs> | null
account_allocation: Prisma.$LicenseAccountAllocationPayload<ExtArgs> | null account_allocation: Prisma.$LicenseAccountAllocationPayload<ExtArgs> | null
sales_invoices: Prisma.$SalesInvoicePayload<ExtArgs>[] sales_invoices: Prisma.$SalesInvoicePayload<ExtArgs>[]
account_device: Prisma.$ConsumerAccountDevicePayload<ExtArgs> | null
} }
scalars: runtime.Types.Extensions.GetPayloadResult<{ scalars: runtime.Types.Extensions.GetPayloadResult<{
id: string id: string
@@ -1376,6 +1492,7 @@ export interface Prisma__ConsumerAccountClient<T, Null = never, ExtArgs extends
permission<T extends Prisma.ConsumerAccount$permissionArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.ConsumerAccount$permissionArgs<ExtArgs>>): Prisma.Prisma__PermissionConsumerClient<runtime.Types.Result.GetResult<Prisma.$PermissionConsumerPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> permission<T extends Prisma.ConsumerAccount$permissionArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.ConsumerAccount$permissionArgs<ExtArgs>>): Prisma.Prisma__PermissionConsumerClient<runtime.Types.Result.GetResult<Prisma.$PermissionConsumerPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
account_allocation<T extends Prisma.ConsumerAccount$account_allocationArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.ConsumerAccount$account_allocationArgs<ExtArgs>>): Prisma.Prisma__LicenseAccountAllocationClient<runtime.Types.Result.GetResult<Prisma.$LicenseAccountAllocationPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> account_allocation<T extends Prisma.ConsumerAccount$account_allocationArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.ConsumerAccount$account_allocationArgs<ExtArgs>>): Prisma.Prisma__LicenseAccountAllocationClient<runtime.Types.Result.GetResult<Prisma.$LicenseAccountAllocationPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
sales_invoices<T extends Prisma.ConsumerAccount$sales_invoicesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.ConsumerAccount$sales_invoicesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$SalesInvoicePayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> sales_invoices<T extends Prisma.ConsumerAccount$sales_invoicesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.ConsumerAccount$sales_invoicesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$SalesInvoicePayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
account_device<T extends Prisma.ConsumerAccount$account_deviceArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.ConsumerAccount$account_deviceArgs<ExtArgs>>): Prisma.Prisma__ConsumerAccountDeviceClient<runtime.Types.Result.GetResult<Prisma.$ConsumerAccountDevicePayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
/** /**
* Attaches callbacks for the resolution and/or rejection of the Promise. * Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved. * @param onfulfilled The callback to execute when the Promise is resolved.
@@ -1839,6 +1956,25 @@ export type ConsumerAccount$sales_invoicesArgs<ExtArgs extends runtime.Types.Ext
distinct?: Prisma.SalesInvoiceScalarFieldEnum | Prisma.SalesInvoiceScalarFieldEnum[] distinct?: Prisma.SalesInvoiceScalarFieldEnum | Prisma.SalesInvoiceScalarFieldEnum[]
} }
/**
* ConsumerAccount.account_device
*/
export type ConsumerAccount$account_deviceArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
/**
* Select specific fields to fetch from the ConsumerAccountDevice
*/
select?: Prisma.ConsumerAccountDeviceSelect<ExtArgs> | null
/**
* Omit specific fields from the ConsumerAccountDevice
*/
omit?: Prisma.ConsumerAccountDeviceOmit<ExtArgs> | null
/**
* Choose, which related nodes to fetch as well
*/
include?: Prisma.ConsumerAccountDeviceInclude<ExtArgs> | null
where?: Prisma.ConsumerAccountDeviceWhereInput
}
/** /**
* ConsumerAccount without action * ConsumerAccount without action
*/ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+34 -5
View File
@@ -57,17 +57,46 @@ async function bootstrap() {
// Enable CORS. You can set `CORS_ORIGINS` to a comma-separated list of allowed origins. // Enable CORS. You can set `CORS_ORIGINS` to a comma-separated list of allowed origins.
// Defaults include common localhost origins used by front-end dev servers. // Defaults include common localhost origins used by front-end dev servers.
const defaultOrigins = [] const defaultOrigins: string[] = []
const envOrigins = process.env.CORS_ORIGINS const envOrigins = process.env.CORS_ORIGINS
? process.env.CORS_ORIGINS.split(',') ? process.env.CORS_ORIGINS.split(',')
.map(s => s.trim()) .map(s => s.trim())
.filter(Boolean) .filter(Boolean)
: [] : []
const allowedOrigins = (envOrigins.length ? envOrigins : defaultOrigins).filter(
origin => origin !== '*', const allowedOrigins = (envOrigins.length ? envOrigins : defaultOrigins).filter(Boolean)
)
const isOriginAllowed = (origin: string) => {
try {
const hostname = new URL(origin).hostname
return allowedOrigins.some(pattern => {
if (pattern === '*') return true
if (pattern.startsWith('*.')) {
const rootDomain = pattern.slice(2)
return hostname === rootDomain || hostname.endsWith(`.${rootDomain}`)
}
return hostname === pattern || origin === pattern
})
} catch {
return allowedOrigins.includes(origin)
}
}
app.enableCors({ app.enableCors({
origin: allowedOrigins, origin: (origin, callback) => {
if (!origin) {
callback(null, true)
return
}
if (isOriginAllowed(origin)) {
callback(null, true)
return
}
callback(new Error('Not allowed by CORS'), false)
},
credentials: true, credentials: true,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS', methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
allowedHeaders: allowedHeaders:
@@ -14,6 +14,26 @@ export class AdminConsumersService {
type: true, type: true,
...QUERY_CONSTANTS.CONSUMER.infoSelect, ...QUERY_CONSTANTS.CONSUMER.infoSelect,
...QUERY_CONSTANTS.CONSUMER.activeBusinessCount, ...QUERY_CONSTANTS.CONSUMER.activeBusinessCount,
individual: {
select: {
partner: {
select: {
id: true,
name: true,
},
},
},
},
legal: {
select: {
partner: {
select: {
id: true,
name: true,
},
},
},
},
status: true, status: true,
created_at: true, created_at: true,
} }
@@ -0,0 +1,17 @@
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { PosCacheInvalidationService } from '@/modules/pos/cache/pos-cache-invalidation.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common'
@Injectable()
export class AdminGuildCacheInvalidationService {
constructor(
private readonly redisService: RedisService,
private readonly posCacheInvalidationService: PosCacheInvalidationService,
) {}
async invalidateGoodsList(guildId: string): Promise<void> {
await this.redisService.delete(RedisKeyMaker.guildGoodsList(guildId))
await this.posCacheInvalidationService.invalidateGoodsListByGuild(guildId)
}
}
@@ -1,5 +1,6 @@
import { GoodCategoryOmit } from '@/generated/prisma/models' import { GoodCategoryOmit } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { AdminGuildCacheInvalidationService } from '@/modules/admin/guilds/cache/admin-guild-cache-invalidation.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { import {
@@ -9,7 +10,10 @@ import {
@Injectable() @Injectable()
export class GoodCategoriesService { export class GoodCategoriesService {
constructor(private prisma: PrismaService) {} constructor(
private prisma: PrismaService,
private readonly cacheInvalidationService: AdminGuildCacheInvalidationService,
) {}
private readonly goodCategoriesOmit = { private readonly goodCategoriesOmit = {
complex_id: true, complex_id: true,
@@ -67,8 +71,8 @@ export class GoodCategoriesService {
}) })
} }
create(guild_id: string, data: CreateGoodCategoryDto) { async create(guild_id: string, data: CreateGoodCategoryDto) {
const category = this.prisma.goodCategory.create({ const category = await this.prisma.goodCategory.create({
data: { data: {
guild: { guild: {
connect: { connect: {
@@ -83,6 +87,8 @@ export class GoodCategoriesService {
omit: this.goodCategoriesOmit, omit: this.goodCategoriesOmit,
}) })
await this.cacheInvalidationService.invalidateGoodsList(guild_id)
return ResponseMapper.create({ ...category, goods_count: 0 }) return ResponseMapper.create({ ...category, goods_count: 0 })
} }
@@ -113,6 +119,8 @@ export class GoodCategoriesService {
omit: this.goodCategoriesOmit, omit: this.goodCategoriesOmit,
}) })
await this.cacheInvalidationService.invalidateGoodsList(guild_id)
return ResponseMapper.update({ return ResponseMapper.update({
...category, ...category,
goods_count: Number(category?._count.goods), goods_count: Number(category?._count.goods),
@@ -1,7 +1,10 @@
import { UploadedFileTypes } from '@/common/enums/enums' import { UploadedFileTypes } from '@/common/enums/enums'
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { GoodSelect, GoodWhereInput } from '@/generated/prisma/models' import { GoodSelect, GoodWhereInput } from '@/generated/prisma/models'
import { AdminGuildCacheInvalidationService } from '@/modules/admin/guilds/cache/admin-guild-cache-invalidation.service'
import { UploaderService } from '@/modules/uploader/uploader.service' import { UploaderService } from '@/modules/uploader/uploader.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { CreateGuildGoodDto, UpdateGuildGoodDto } from './dto/create-good.dto' import { CreateGuildGoodDto, UpdateGuildGoodDto } from './dto/create-good.dto'
@@ -11,8 +14,12 @@ export class GoodsService {
constructor( constructor(
private prisma: PrismaService, private prisma: PrismaService,
private readonly uploaderService: UploaderService, private readonly uploaderService: UploaderService,
private readonly redisService: RedisService,
private readonly cacheInvalidationService: AdminGuildCacheInvalidationService,
) {} ) {}
private readonly listCacheTtlSeconds = 300
private readonly defaultSelect: GoodSelect = { private readonly defaultSelect: GoodSelect = {
id: true, id: true,
name: true, name: true,
@@ -23,12 +30,14 @@ export class GoodsService {
select: { select: {
id: true, id: true,
name: true, name: true,
code: true,
}, },
}, },
measure_unit: { measure_unit: {
select: { select: {
id: true, id: true,
name: true, name: true,
code: true,
}, },
}, },
category: { category: {
@@ -47,6 +56,14 @@ export class GoodsService {
}) })
async findAll(guildId: string) { async findAll(guildId: string) {
const cacheKey = RedisKeyMaker.guildGoodsList(guildId)
const cached = await this.redisService.getJson<{ goods: unknown[]; total: number }>(
cacheKey,
)
if (cached) {
return ResponseMapper.paginate(cached.goods, { total: cached.total })
}
const [goods, total] = await this.prisma.$transaction([ const [goods, total] = await this.prisma.$transaction([
this.prisma.good.findMany({ this.prisma.good.findMany({
where: this.defaultWhere(guildId), where: this.defaultWhere(guildId),
@@ -54,6 +71,9 @@ export class GoodsService {
}), }),
this.prisma.good.count(), this.prisma.good.count(),
]) ])
await this.redisService.setJson(cacheKey, { goods, total }, this.listCacheTtlSeconds)
return ResponseMapper.paginate(goods, { return ResponseMapper.paginate(goods, {
total, total,
}) })
@@ -73,6 +93,10 @@ export class GoodsService {
async create(data: CreateGuildGoodDto, file: Express.Multer.File) { async create(data: CreateGuildGoodDto, file: Express.Multer.File) {
const { category_id, measure_unit_id, sku_id, ...rest } = data const { category_id, measure_unit_id, sku_id, ...rest } = data
const category = await this.prisma.goodCategory.findUnique({
where: { id: category_id },
select: { guild_id: true },
})
const good = await this.prisma.$transaction(async tx => { const good = await this.prisma.$transaction(async tx => {
let image_url = '' let image_url = ''
@@ -109,11 +133,25 @@ export class GoodsService {
}) })
}) })
if (category?.guild_id) {
await this.cacheInvalidationService.invalidateGoodsList(category.guild_id)
}
return ResponseMapper.create(good) return ResponseMapper.create(good)
} }
async update(id: string, data: UpdateGuildGoodDto, file: Express.Multer.File) { async update(id: string, data: UpdateGuildGoodDto, file: Express.Multer.File) {
const { category_id, measure_unit_id, sku_id, ...rest } = data const { category_id, measure_unit_id, sku_id, ...rest } = data
const prevGood = await this.prisma.good.findUnique({
where: { id },
select: { category: { select: { guild_id: true } } },
})
const nextCategory = category_id
? await this.prisma.goodCategory.findUnique({
where: { id: category_id },
select: { guild_id: true },
})
: null
const good = await this.prisma.$transaction(async tx => { const good = await this.prisma.$transaction(async tx => {
let image_url = '' let image_url = ''
@@ -160,6 +198,18 @@ export class GoodsService {
}) })
}) })
const cacheGuildIds = new Set<string>()
if (prevGood?.category?.guild_id) {
cacheGuildIds.add(prevGood.category.guild_id)
}
if (nextCategory?.guild_id) {
cacheGuildIds.add(nextCategory.guild_id)
}
for (const guildId of cacheGuildIds) {
await this.cacheInvalidationService.invalidateGoodsList(guildId)
}
return ResponseMapper.create(good) return ResponseMapper.create(good)
} }
} }
@@ -1,4 +1,7 @@
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { AdminGuildCacheInvalidationService } from '@/modules/admin/guilds/cache/admin-guild-cache-invalidation.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { CreateStockKeepingUnitDto } from './dto/create-stock-keeping-unit.dto' import { CreateStockKeepingUnitDto } from './dto/create-stock-keeping-unit.dto'
@@ -6,7 +9,17 @@ import { UpdateStockKeepingUnitDto } from './dto/update-stock-keeping-unit.dto'
@Injectable() @Injectable()
export class StockKeepingUnitsService { export class StockKeepingUnitsService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
private readonly cacheInvalidationService: AdminGuildCacheInvalidationService,
) {}
private readonly listCacheTtlSeconds = 300
private getListCacheKey(guild_id: string): string {
return RedisKeyMaker.guildStockKeepingUnitsList(guild_id)
}
private mapData(data: any) { private mapData(data: any) {
const { name, is_foreign, is_domestic, ...rest } = data const { name, is_foreign, is_domestic, ...rest } = data
@@ -17,12 +30,19 @@ export class StockKeepingUnitsService {
} }
async findAll(guild_id: string) { async findAll(guild_id: string) {
const cacheKey = this.getListCacheKey(guild_id)
const cached = await this.redisService.getJson<unknown[]>(cacheKey)
if (cached) {
return ResponseMapper.list(cached)
}
const items = await this.prisma.stockKeepingUnits.findMany({ const items = await this.prisma.stockKeepingUnits.findMany({
where: { guild_id }, where: { guild_id },
orderBy: { created_at: 'desc' }, orderBy: { created_at: 'desc' },
}) })
const mappedData = items.map(this.mapData) const mappedData = items.map(this.mapData)
await this.redisService.setJson(cacheKey, mappedData, this.listCacheTtlSeconds)
return ResponseMapper.list(mappedData) return ResponseMapper.list(mappedData)
} }
@@ -39,6 +59,9 @@ export class StockKeepingUnitsService {
}, },
}) })
await this.redisService.delete(this.getListCacheKey(guild_id))
await this.cacheInvalidationService.invalidateGoodsList(guild_id)
const mappedData = this.mapData(item) const mappedData = this.mapData(item)
return ResponseMapper.create(mappedData) return ResponseMapper.create(mappedData)
} }
@@ -48,6 +71,10 @@ export class StockKeepingUnitsService {
where: { guild_id, id }, where: { guild_id, id },
data, data,
}) })
await this.redisService.delete(this.getListCacheKey(guild_id))
await this.cacheInvalidationService.invalidateGoodsList(guild_id)
return ResponseMapper.update(item) return ResponseMapper.update(item)
} }
} }
@@ -1,15 +1,30 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants' import { QUERY_CONSTANTS } from '@/common/queryConstants'
import consumer_mappersUtil from '@/common/utils/mappers/consumer_mappers.util' import consumer_mappersUtil from '@/common/utils/mappers/consumer_mappers.util'
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { LicenseActivationWhereInput } from '@/generated/prisma/models' import { LicenseActivationWhereInput } from '@/generated/prisma/models'
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
@Injectable() @Injectable()
export class PartnerActivatedLicensesService { export class PartnerActivatedLicensesService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
private readonly cacheInvalidationService: PartnersCacheInvalidationService,
) {}
async findAll(partner_id: string, page = 1, perPage = 10) { async findAll(partner_id: string, page = 1, perPage = 10) {
const cacheKey = RedisKeyMaker.partnerActivatedLicensesList(partner_id, page, perPage)
const cached = await this.redisService.getJson<{ data: unknown[]; total: number }>(
cacheKey,
)
if (cached) {
return ResponseMapper.paginate(cached.data, { page, perPage, total: cached.total })
}
const defaultWhere: LicenseActivationWhereInput = { const defaultWhere: LicenseActivationWhereInput = {
license: { license: {
charge_transaction: { charge_transaction: {
@@ -73,6 +88,8 @@ export class PartnerActivatedLicensesService {
} }
}) })
await this.redisService.setJson(cacheKey, { data: mappedLicenses, total }, 300)
return ResponseMapper.paginate(mappedLicenses, { return ResponseMapper.paginate(mappedLicenses, {
page, page,
perPage, perPage,
@@ -90,6 +107,7 @@ export class PartnerActivatedLicensesService {
async delete(partnerId: string, id: string) { async delete(partnerId: string, id: string) {
await this.prisma.license.delete({ where: { id } }) await this.prisma.license.delete({ where: { id } })
await this.cacheInvalidationService.invalidatePartnerLicenses(partnerId)
return ResponseMapper.delete() return ResponseMapper.delete()
} }
} }
@@ -1,3 +1,4 @@
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { import {
generateTrackingCode, generateTrackingCode,
isTrackingCodeUniqueViolation, isTrackingCodeUniqueViolation,
@@ -6,14 +7,20 @@ import {
LicenseChargeTransactionSelect, LicenseChargeTransactionSelect,
LicenseChargeTransactionWhereInput, LicenseChargeTransactionWhereInput,
} from '@/generated/prisma/models' } from '@/generated/prisma/models'
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { BadRequestException, Injectable } from '@nestjs/common' import { BadRequestException, Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { ChargeLicenseDto } from './dto/chargedLicenseTransactions.dto' import { ChargeLicenseDto } from './dto/chargedLicenseTransactions.dto'
@Injectable() @Injectable()
export class PartnerLicenseChargeTransactionService { export class PartnerLicenseChargeTransactionService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
private readonly cacheInvalidationService: PartnersCacheInvalidationService,
) {}
private readonly TRACKING_CODE_LENGTH = 8 private readonly TRACKING_CODE_LENGTH = 8
private readonly TRACKING_CODE_MAX_ATTEMPTS = 5 private readonly TRACKING_CODE_MAX_ATTEMPTS = 5
@@ -53,6 +60,18 @@ export class PartnerLicenseChargeTransactionService {
} }
async findAll(partner_id: string, page = 1, perPage = 10) { async findAll(partner_id: string, page = 1, perPage = 10) {
const cacheKey = RedisKeyMaker.partnerLicenseChargeTransactionsList(
partner_id,
page,
perPage,
)
const cached = await this.redisService.getJson<{ data: unknown[]; total: number }>(
cacheKey,
)
if (cached) {
return ResponseMapper.paginate(cached.data, { page, perPage, total: cached.total })
}
const defaultWhere: LicenseChargeTransactionWhereInput = { const defaultWhere: LicenseChargeTransactionWhereInput = {
partner_id, partner_id,
} }
@@ -70,6 +89,7 @@ export class PartnerLicenseChargeTransactionService {
]) ])
const mappedTransactions = transactions.map(this.mappedTransaction) const mappedTransactions = transactions.map(this.mappedTransaction)
await this.redisService.setJson(cacheKey, { data: mappedTransactions, total }, 300)
return ResponseMapper.paginate(mappedTransactions, { return ResponseMapper.paginate(mappedTransactions, {
page, page,
@@ -79,6 +99,12 @@ export class PartnerLicenseChargeTransactionService {
} }
async findOne(partner_id: string, id: string) { async findOne(partner_id: string, id: string) {
const cacheKey = RedisKeyMaker.partnerLicenseChargeTransactionDetail(partner_id, id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const transaction = await this.prisma.licenseChargeTransaction.findUniqueOrThrow({ const transaction = await this.prisma.licenseChargeTransaction.findUniqueOrThrow({
where: { where: {
id, id,
@@ -86,7 +112,9 @@ export class PartnerLicenseChargeTransactionService {
}, },
select: this.defaultSelect, select: this.defaultSelect,
}) })
return ResponseMapper.single(this.mappedTransaction(transaction)) const mappedTransaction = this.mappedTransaction(transaction)
await this.redisService.setJson(cacheKey, mappedTransaction, 300)
return ResponseMapper.single(mappedTransaction)
} }
async create(partner_id: string, data: ChargeLicenseDto) { async create(partner_id: string, data: ChargeLicenseDto) {
@@ -134,6 +162,8 @@ export class PartnerLicenseChargeTransactionService {
}) })
this.scheduleLicenseProvisioning(transaction.id, transaction.purchased_count) this.scheduleLicenseProvisioning(transaction.id, transaction.purchased_count)
await this.cacheInvalidationService.invalidatePartnersList()
await this.cacheInvalidationService.invalidatePartnerLicenses(partner_id)
return ResponseMapper.create({ return ResponseMapper.create({
transaction_id: transaction.id, transaction_id: transaction.id,
charged_license_count: transaction.purchased_count, charged_license_count: transaction.purchased_count,
+32 -1
View File
@@ -1,6 +1,7 @@
import { UploadedFileTypes } from '@/common/enums/enums' import { UploadedFileTypes } from '@/common/enums/enums'
import { translateEnumValue } from '@/common/utils' import { translateEnumValue } from '@/common/utils'
import { PasswordUtil } from '@/common/utils/password.util' import { PasswordUtil } from '@/common/utils/password.util'
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { import {
AccountStatus, AccountStatus,
AccountType, AccountType,
@@ -8,8 +9,10 @@ import {
PartnerStatus, PartnerStatus,
} from '@/generated/prisma/enums' } from '@/generated/prisma/enums'
import { PartnerSelect } from '@/generated/prisma/models' import { PartnerSelect } from '@/generated/prisma/models'
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
import { UploaderService } from '@/modules/uploader/uploader.service' import { UploaderService } from '@/modules/uploader/uploader.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { CreatePartnerDto, UpdatePartnerDto } from './dto/partner.dto' import { CreatePartnerDto, UpdatePartnerDto } from './dto/partner.dto'
@@ -20,6 +23,8 @@ export class PartnersService {
constructor( constructor(
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private readonly uploaderService: UploaderService, private readonly uploaderService: UploaderService,
private readonly redisService: RedisService,
private readonly cacheInvalidationService: PartnersCacheInvalidationService,
) {} ) {}
private readonly defaultSelect: PartnerSelect = { private readonly defaultSelect: PartnerSelect = {
@@ -137,22 +142,40 @@ export class PartnersService {
} }
async findAll() { async findAll() {
const cacheKey = RedisKeyMaker.partnersList()
const cached = await this.redisService.getJson<unknown[]>(cacheKey)
if (cached) {
console.log('cached', cached)
return ResponseMapper.list(cached)
}
const partners = await this.prisma.partner.findMany({ const partners = await this.prisma.partner.findMany({
select: this.defaultSelect, select: this.defaultSelect,
}) })
const mappedPartners = partners.map(this.mapPartner) const mappedPartners = partners.map(this.mapPartner)
await this.redisService.setJson(cacheKey, mappedPartners, 300)
return ResponseMapper.list(mappedPartners) return ResponseMapper.list(mappedPartners)
} }
async findOne(id: string) { async findOne(id: string) {
const cacheKey = RedisKeyMaker.partnerDetail(id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const partner = await this.prisma.partner.findUniqueOrThrow({ const partner = await this.prisma.partner.findUniqueOrThrow({
where: { id }, where: { id },
select: this.defaultSelect, select: this.defaultSelect,
}) })
return ResponseMapper.single(this.mapPartner(partner)) const mappedPartner = this.mapPartner(partner)
await this.redisService.setJson(cacheKey, mappedPartner, 300)
return ResponseMapper.single(mappedPartner)
} }
async create(data: CreatePartnerDto, logo?: any) { async create(data: CreatePartnerDto, logo?: any) {
@@ -184,6 +207,8 @@ export class PartnersService {
}, },
select: this.defaultSelect, select: this.defaultSelect,
}) })
await this.cacheInvalidationService.invalidatePartnersList()
await this.cacheInvalidationService.invalidatePartnerDetail(partner.id)
return ResponseMapper.create(partner) return ResponseMapper.create(partner)
} }
@@ -220,11 +245,17 @@ export class PartnersService {
}) })
}) })
await this.cacheInvalidationService.invalidatePartnersList()
await this.cacheInvalidationService.invalidatePartnerDetail(id)
return ResponseMapper.update(partner) return ResponseMapper.update(partner)
} }
async delete(id: string) { async delete(id: string) {
await this.prisma.partner.delete({ where: { id } }) await this.prisma.partner.delete({ where: { id } })
await this.cacheInvalidationService.invalidatePartnersList()
await this.cacheInvalidationService.invalidatePartnerDetail(id)
await this.cacheInvalidationService.invalidatePartnerLicenses(id)
return ResponseMapper.delete() return ResponseMapper.delete()
} }
} }
@@ -3,11 +3,10 @@ import { JwtService } from '@nestjs/jwt'
import { AppController } from './application.controller' import { AppController } from './application.controller'
import { AppService } from './application.service' import { AppService } from './application.service'
import { ApplicationAuthModule } from './auth/auth.module' import { ApplicationAuthModule } from './auth/auth.module'
import { ApplicationConfigModule } from './config/config.module'
@Module({ @Module({
controllers: [AppController], controllers: [AppController],
providers: [AppService, JwtService], providers: [AppService, JwtService],
imports: [ApplicationConfigModule, ApplicationAuthModule], imports: [ApplicationAuthModule],
}) })
export class ApplicationModule {} export class ApplicationModule {}
+4 -1
View File
@@ -7,7 +7,10 @@ export class ApplicationAuthService {
constructor(private readonly authService: AuthService) {} constructor(private readonly authService: AuthService) {}
async login(data: applicationLoginDto) { async login(data: applicationLoginDto) {
const loginResponse = await this.authService.login(data, true) const loginResponse = await this.authService.login(data, true, {
id: data.device_id,
name: data.device_name,
})
return loginResponse return loginResponse
} }
+4 -1
View File
@@ -1,3 +1,6 @@
import { LoginDto } from '@/modules/auth/dto/login.dto' import { LoginDto } from '@/modules/auth/dto/login.dto'
export class applicationLoginDto extends LoginDto {} export class applicationLoginDto extends LoginDto {
device_name: string
device_id: string
}
@@ -1,21 +0,0 @@
import { Public } from '@/common/decorators/public.decorator'
import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
import { Body, Controller, Get, Param, Post } from '@nestjs/common'
import { ConfigService } from './config.service'
import { CreateConfigDto } from './dto/create-config.dto'
@Controller('app/config')
export class ConfigController {
constructor(private readonly configService: ConfigService) {}
@Get(':id')
findOne(@Param('id') uuid: string) {
return this.configService.findOne(uuid)
}
@Post()
@Public()
create(@TokenAccount('userId') consumerId: string, @Body() data: CreateConfigDto) {
return this.configService.create(consumerId, data)
}
}
@@ -1,9 +0,0 @@
import { Module } from '@nestjs/common'
import { ConfigController } from './config.controller'
import { ConfigService } from './config.service'
@Module({
controllers: [ConfigController],
providers: [ConfigService],
})
export class ApplicationConfigModule {}
@@ -1,83 +0,0 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants'
import { ConsumerDevicesSelect } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service'
import { BadRequestException, Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper'
import { CreateConfigDto } from './dto/create-config.dto'
@Injectable()
export class ConfigService {
constructor(private prisma: PrismaService) {}
private readonly defaultSelect: ConsumerDevicesSelect = {
uuid: true,
app_version: true,
brand: true,
browser_name: true,
build_number: true,
device: true,
os_version: true,
fcm_token: true,
model: true,
platform: true,
release_number: true,
sdk_version: true,
consumer: {
select: {
id: true,
...QUERY_CONSTANTS.CONSUMER.infoSelect,
},
},
}
async findOne(uuid: string) {
const config = await this.prisma.consumerDevices.findUnique({
where: {
uuid,
},
select: this.defaultSelect,
})
return ResponseMapper.single(config)
}
async create(consumer_id: string, data: CreateConfigDto) {
const prevConfig = await this.prisma.consumerDevices.findUnique({
where: {
uuid: data.uuid,
},
select: {
consumer_id: true,
},
})
if (prevConfig && consumer_id !== prevConfig.consumer_id) {
throw new BadRequestException('این دستگاه با کاربری دیگری ثبت شده است.')
}
const config = await this.prisma.consumerDevices.upsert({
where: {
uuid: data.uuid,
},
update: {
...data,
consumer: {
connect: {
id: consumer_id,
},
},
},
create: {
...data,
consumer: {
connect: {
id: consumer_id,
},
},
},
select: this.defaultSelect,
})
return ResponseMapper.create(config)
}
}
@@ -1,4 +0,0 @@
import type { ConfigService } from '../config.service'
export type ConfigServiceCreateResponseDto = Awaited<ReturnType<ConfigService['create']>>
export type ConfigServiceFindOneResponseDto = Awaited<ReturnType<ConfigService['findOne']>>
@@ -1,66 +0,0 @@
import { ApplicationPlatform, ApplicationPublisher } from '@/generated/prisma/enums'
import { ApiProperty, PartialType } from '@nestjs/swagger'
import { IsEnum, IsOptional, IsString } from 'class-validator'
export class CreateConfigDto {
@ApiProperty({ required: true })
@IsString()
uuid: string
@ApiProperty({ required: true })
@IsEnum(ApplicationPublisher)
publisher: ApplicationPublisher
@ApiProperty({ required: true })
@IsString()
app_version: string
@ApiProperty({ required: true })
@IsString()
build_number: string
@ApiProperty({ required: true })
@IsEnum(ApplicationPlatform)
platform: ApplicationPlatform
@ApiProperty({ required: true })
@IsString()
brand: string
@ApiProperty({ required: true })
@IsString()
model: string
@ApiProperty({ required: true })
@IsString()
device: string
@ApiProperty({ required: true })
@IsString()
os_version: string
@ApiProperty({ required: true })
@IsString()
sdk_version: string
@ApiProperty({ required: true })
@IsString()
release_number: string
@ApiProperty({ required: false })
@IsString()
@IsOptional()
browser_name: string
@ApiProperty({ required: false })
@IsString()
@IsOptional()
user_agent: string
@ApiProperty({ required: false })
@IsString()
@IsOptional()
fcm_token?: string
}
export class UpdateConfigDto extends PartialType(CreateConfigDto) {}
+79 -13
View File
@@ -1,3 +1,5 @@
import { ConsumerRole } from '@/generated/prisma/enums'
import { AccountInclude, AccountWhereUniqueInput } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { Injectable, NotFoundException } from '@nestjs/common' import { Injectable, NotFoundException } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
@@ -5,6 +7,10 @@ import 'dotenv/config'
import { AuthUtils } from './auth.utils' import { AuthUtils } from './auth.utils'
import { LoginDto } from './dto/login.dto' import { LoginDto } from './dto/login.dto'
interface DeviceInfoForLogin {
id: string
name: string
}
@Injectable() @Injectable()
export class AuthService { export class AuthService {
constructor( constructor(
@@ -12,31 +18,91 @@ export class AuthService {
private authUtils: AuthUtils, private authUtils: AuthUtils,
) {} ) {}
async login(dto: LoginDto, isPos = false) { async login(dto: LoginDto, is_pos = false, device_info?: DeviceInfoForLogin) {
const { username, password } = dto const { username, password, isPos } = dto
let accountWhere: AccountWhereUniqueInput = {
username,
}
let accountInclude: AccountInclude = {}
console.error('isPos', isPos)
if (isPos) {
// if (!device_info?.id) {
// throw new NotFoundException('اطلاعات ورودی شما اشتباه است')
// }
accountWhere = {
...accountWhere,
consumer_account: {
pos: {
isNot: null,
},
},
}
accountInclude = {
...accountInclude,
consumer_account: {
select: {
id: true,
account_device: true,
role: true,
},
},
}
}
const account = await this.prisma.account.findUnique({ const account = await this.prisma.account.findUnique({
where: { where: accountWhere,
username, include: accountInclude,
},
}) })
if (!account) { if (!account) {
throw new NotFoundException('اطلاعات ورودی شما اشتباه است') throw new NotFoundException('اطلاعات ورودی شما اشتباه است')
} }
await this.authUtils.checkAuthPassword(password, account.password)
if (isPos) { if (isPos) {
const posAccount = await this.prisma.consumerAccount.findUnique({ if (
where: { !account.consumer_account ||
account_id: account.id, account.consumer_account.role !== ConsumerRole.OPERATOR
}, ) {
})
if (!posAccount) {
throw new NotFoundException('اطلاعات ورودی شما اشتباه است') throw new NotFoundException('اطلاعات ورودی شما اشتباه است')
} }
} // const { account_device, id } = account.consumer_account as any
await this.authUtils.checkAuthPassword(password, account.password) // if (account_device?.device_id !== device_info!.id) {
// throw new ForbiddenException(
// 'کاربر شما با دستگاه دیگری اجازه ورود دارد. لطفا با پشتیبانی تماس بگیرید',
// )
// }
// const device = await this.prisma.consumerAccountDevice.findUnique({
// where: {
// device_id: device_info!.id!,
// },
// })
// if (device) {
// throw new ForbiddenException(
// 'این دستگاه برای کاربر دیگری رجیستر شده است. لطفا با پشتیبانی تماس بگیرید.',
// )
// }
// await this.prisma.consumerAccountDevice.create({
// data: {
// device_id: device_info!.id!,
// device_name: device_info!.name,
// consumer_account: {
// connect: {
// id,
// },
// },
// },
// })
}
const preparedData = await this.authUtils.generateLoginResponse(account) const preparedData = await this.authUtils.generateLoginResponse(account)
return ResponseMapper.create(preparedData) return ResponseMapper.create(preparedData)
+6 -1
View File
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger' import { ApiProperty } from '@nestjs/swagger'
import { IsString } from 'class-validator' import { IsBoolean, IsOptional, IsString } from 'class-validator'
export class LoginDto { export class LoginDto {
@ApiProperty({ description: 'Mobile number used as username', example: '09120258156' }) @ApiProperty({ description: 'Mobile number used as username', example: '09120258156' })
@@ -9,4 +9,9 @@ export class LoginDto {
@ApiProperty({ description: 'OTP password (one-time password)', example: '11111' }) @ApiProperty({ description: 'OTP password (one-time password)', example: '11111' })
@IsString() @IsString()
password: string password: string
@ApiProperty({ default: false })
@IsBoolean()
@IsOptional()
isPos: boolean = false
} }
@@ -1,6 +1,8 @@
import { BusinessActivitiesQueryService } from '@/common/services/businessActivities/business-activities-query.service' import { BusinessActivitiesQueryService } from '@/common/services/businessActivities/business-activities-query.service'
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { BusinessActivitySelect } from '@/generated/prisma/models' import { BusinessActivitySelect } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
@@ -10,6 +12,7 @@ export class BusinessActivitiesService {
constructor( constructor(
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private readonly businessActivitiesQueryService: BusinessActivitiesQueryService, private readonly businessActivitiesQueryService: BusinessActivitiesQueryService,
private readonly redisService: RedisService,
) { ) {
this.defaultSelect = { this.defaultSelect = {
...this.businessActivitiesQueryService.baseSelect, ...this.businessActivitiesQueryService.baseSelect,
@@ -37,6 +40,7 @@ export class BusinessActivitiesService {
}, },
} }
} }
private readonly cacheTtlSeconds = 300
private readonly prepareBusinessActivityResponse = (businessActivity: any) => { private readonly prepareBusinessActivityResponse = (businessActivity: any) => {
const { license_activation, complexes, ...rest } = businessActivity const { license_activation, complexes, ...rest } = businessActivity
@@ -56,24 +60,35 @@ export class BusinessActivitiesService {
} }
async findAll(consumer_id: string) { async findAll(consumer_id: string) {
const cacheKey = RedisKeyMaker.consumerBusinessActivitiesList(consumer_id)
const cached = await this.redisService.getJson<unknown[]>(cacheKey)
if (cached) {
return ResponseMapper.list(cached)
}
const businessActivities = const businessActivities =
await this.businessActivitiesQueryService.findAllByConsumer( await this.businessActivitiesQueryService.findAllByConsumer(
consumer_id, consumer_id,
this.defaultSelect, this.defaultSelect,
) )
return ResponseMapper.list( await this.redisService.setJson(cacheKey, businessActivities, this.cacheTtlSeconds)
businessActivities.map(this.prepareBusinessActivityResponse), return ResponseMapper.list(businessActivities)
)
} }
async findOne(consumer_id: string, id: string) { async findOne(consumer_id: string, id: string) {
const cacheKey = RedisKeyMaker.consumerBusinessActivityInfo(consumer_id, id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const businessActivity = await this.businessActivitiesQueryService.findOneByConsumer( const businessActivity = await this.businessActivitiesQueryService.findOneByConsumer(
consumer_id, consumer_id,
id, id,
this.defaultSelect, this.defaultSelect,
true,
) )
return ResponseMapper.single(this.prepareBusinessActivityResponse(businessActivity)) await this.redisService.setJson(cacheKey, businessActivity, this.cacheTtlSeconds)
return ResponseMapper.single(businessActivity)
} }
async update(consumer_id: string, id: string, data: any) { async update(consumer_id: string, id: string, data: any) {
@@ -82,6 +97,13 @@ export class BusinessActivitiesService {
data, data,
select: this.defaultSelect, select: this.defaultSelect,
}) })
await this.redisService.delete(
RedisKeyMaker.consumerBusinessActivityInfo(consumer_id, id),
)
await this.redisService.delete(
RedisKeyMaker.consumerBusinessActivitiesList(consumer_id),
)
return ResponseMapper.update(this.prepareBusinessActivityResponse(businessActivity)) return ResponseMapper.update(this.prepareBusinessActivityResponse(businessActivity))
} }
} }
@@ -1,4 +1,4 @@
import { Controller, Get, Param } from '@nestjs/common' import { Controller, Get, Param, Post } from '@nestjs/common'
import { TokenAccount } from '@/common/decorators/tokenInfo.decorator' import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
import { ApiTags } from '@nestjs/swagger' import { ApiTags } from '@nestjs/swagger'
@@ -26,4 +26,43 @@ export class SalesInvoicesController {
) { ) {
return this.salesInvoicesService.findOne(complexId, posId, id) return this.salesInvoicesService.findOne(complexId, posId, id)
} }
@Get(':id/inquiry')
inquiry(
@TokenAccount('userId') userId: string,
@Param('posId') posId: string,
@Param('id') id: string,
) {
return this.salesInvoicesService.inquiry(userId, posId, id)
}
@Post(':id/send')
send(
@TokenAccount('userId') userId: string,
@Param('complexId') complexId: string,
@Param('posId') posId: string,
@Param('id') id: string,
) {
return this.salesInvoicesService.send(userId, complexId, posId, id)
}
@Post(':id/retry')
retry(
@TokenAccount('userId') userId: string,
@Param('complexId') complexId: string,
@Param('posId') posId: string,
@Param('id') id: string,
) {
return this.salesInvoicesService.retry(userId, complexId, posId, id)
}
@Post(':id/revoke')
revoke(
@TokenAccount('userId') userId: string,
@Param('complexId') complexId: string,
@Param('posId') posId: string,
@Param('id') id: string,
) {
return this.salesInvoicesService.revoke(userId, complexId, posId, id)
}
} }
@@ -1,9 +1,17 @@
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
import { SharedSaleInvoiceAccessService } from '@/common/services/saleInvoices/sale-invoice-access.service'
import { SaleInvoiceTspModule } from '@/modules/tspProviders/sales-invoice-tsp.module'
import { Module } from '@nestjs/common' import { Module } from '@nestjs/common'
import { SalesInvoicesController } from './sales-invoices.controller' import { SalesInvoicesController } from './sales-invoices.controller'
import { SalesInvoicesService } from './sales-invoices.service' import { SalesInvoicesService } from './sales-invoices.service'
@Module({ @Module({
imports: [SaleInvoiceTspModule],
controllers: [SalesInvoicesController], controllers: [SalesInvoicesController],
providers: [SalesInvoicesService], providers: [
SalesInvoicesService,
SharedSaleInvoiceActionsService,
SharedSaleInvoiceAccessService,
],
}) })
export class ConsumerPosSalesInvoicesModule {} export class ConsumerPosSalesInvoicesModule {}
@@ -1,11 +1,15 @@
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
import { ResponseMapper } from '@/common/response/response-mapper' import { ResponseMapper } from '@/common/response/response-mapper'
import { SalesInvoiceWhereInput } from '@/generated/prisma/models' import { SalesInvoiceWhereInput } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { Injectable } from '@nestjs/common' import { Injectable, NotFoundException } from '@nestjs/common'
@Injectable() @Injectable()
export class SalesInvoicesService { export class SalesInvoicesService {
constructor(private prisma: PrismaService) {} constructor(
private prisma: PrismaService,
private readonly sharedSaleInvoiceActionsService: SharedSaleInvoiceActionsService,
) {}
async findAll(consumer_id: string, complex_id: string, pos_id: string) { async findAll(consumer_id: string, complex_id: string, pos_id: string) {
const defaultWhere: SalesInvoiceWhereInput = { const defaultWhere: SalesInvoiceWhereInput = {
@@ -117,4 +121,75 @@ export class SalesInvoicesService {
// TODO: Implement fetching a single sales invoice // TODO: Implement fetching a single sales invoice
return {} return {}
} }
async send(
consumerAccountId: string,
complexId: string,
posId: string,
invoiceId: string,
) {
const invoice = await this.sharedSaleInvoiceActionsService.send(
consumerAccountId,
posId,
invoiceId,
)
return ResponseMapper.single(invoice)
}
async retry(
consumerAccountId: string,
complexId: string,
posId: string,
invoiceId: string,
) {
const invoice = await this.sharedSaleInvoiceActionsService.retry(
consumerAccountId,
posId,
invoiceId,
)
return ResponseMapper.single(invoice)
}
async revoke(
consumerAccountId: string,
complexId: string,
posId: string,
invoiceId: string,
) {
const pos = await this.prisma.pos.findUnique({
where: {
id: posId,
complex: {
id: complexId,
},
},
select: {
complex: {
select: {
business_activity_id: true,
},
},
},
})
if (!pos) throw new NotFoundException('پایانه فروش مورد نظر یافت نشد.')
const invoice = await this.sharedSaleInvoiceActionsService.revoke(
consumerAccountId,
posId,
complexId,
pos.complex.business_activity_id,
invoiceId,
)
return ResponseMapper.single(invoice)
}
async inquiry(consumerAccountId: string, posId: string, invoiceId: string) {
const invoice = await this.sharedSaleInvoiceActionsService.inquiry(
consumerAccountId,
posId,
invoiceId,
)
return ResponseMapper.single(invoice)
}
} }
@@ -1,5 +1,6 @@
import { UploadedFileTypes } from '@/common/enums/enums' import { UploadedFileTypes } from '@/common/enums/enums'
import { GoodSelect } from '@/generated/prisma/models' import { GoodSelect } from '@/generated/prisma/models'
import { PosCacheInvalidationService } from '@/modules/pos/cache/pos-cache-invalidation.service'
import { UploaderService } from '@/modules/uploader/uploader.service' import { UploaderService } from '@/modules/uploader/uploader.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
@@ -11,6 +12,7 @@ export class ConsumerBusinessActivityGoodsService {
constructor( constructor(
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private readonly uploaderService: UploaderService, private readonly uploaderService: UploaderService,
private readonly posCacheInvalidationService: PosCacheInvalidationService,
) {} ) {}
defaultSelect: GoodSelect = { defaultSelect: GoodSelect = {
@@ -110,6 +112,9 @@ export class ConsumerBusinessActivityGoodsService {
}, },
}, },
}) })
await this.posCacheInvalidationService.invalidateGoodsListByBusinessActivity(
business_activity_id,
)
return ResponseMapper.create(good) return ResponseMapper.create(good)
} }
@@ -174,6 +179,9 @@ export class ConsumerBusinessActivityGoodsService {
}, },
}) })
}) })
await this.posCacheInvalidationService.invalidateGoodsListByBusinessActivity(
business_activity_id,
)
return ResponseMapper.update(good) return ResponseMapper.update(good)
} }
+27 -3
View File
@@ -1,8 +1,13 @@
import { ConsumerInfo } from '@/common/decorators/consumerInfo.decorator' import { ConsumerInfo } from '@/common/decorators/consumerInfo.decorator'
import { Controller, Get } from '@nestjs/common' import { Body, Controller, Get, Patch, Put } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger' import { ApiTags } from '@nestjs/swagger'
import { ConsumerService } from './consumer.service' import { ConsumerService } from './consumer.service'
import type { ConsumerServiceGetInfoResponseDto } from './dto/consumer-response.dto' import type {
ConsumerServiceGetInfoResponseDto,
ConsumerServiceUpdateInfoResponseDto,
} from './dto/consumer-response.dto'
import { UpdateConsumerInfoDto } from './dto/update-info-request.dto'
import { UpdateConsumerPasswordDto } from './dto/update-password-request.dto'
@ApiTags('Consumer') @ApiTags('Consumer')
@Controller('consumer') @Controller('consumer')
@@ -10,7 +15,26 @@ export class ConsumerController {
constructor(private service: ConsumerService) {} constructor(private service: ConsumerService) {}
@Get('') @Get('')
async findOne(@ConsumerInfo('id') consumerId: string): Promise<ConsumerServiceGetInfoResponseDto> { async findOne(
@ConsumerInfo('id') consumerId: string,
): Promise<ConsumerServiceGetInfoResponseDto> {
return this.service.getInfo(consumerId) return this.service.getInfo(consumerId)
} }
@Patch('')
async updateInfo(
@ConsumerInfo('id') consumerId: string,
@Body() data: UpdateConsumerInfoDto,
): Promise<ConsumerServiceUpdateInfoResponseDto> {
return this.service.updateInfo(consumerId, data)
}
@Put('update-password')
async updatePassword(
@ConsumerInfo('id') consumerId: string,
@ConsumerInfo('account_id') accountId: string,
@Body() data: UpdateConsumerPasswordDto,
) {
return this.service.updatePassword(consumerId, accountId, data)
}
} }
+104 -2
View File
@@ -1,14 +1,31 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants' import { QUERY_CONSTANTS } from '@/common/queryConstants'
import { ResponseMapper } from '@/common/response/response-mapper' import { ResponseMapper } from '@/common/response/response-mapper'
import { PasswordUtil } from '@/common/utils'
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { ConsumerUpdateInput } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import consumer_mappersUtil from '../../common/utils/mappers/consumer_mappers.util' import consumer_mappersUtil from '../../common/utils/mappers/consumer_mappers.util'
import { UpdateConsumerInfoDto } from './dto/update-info-request.dto'
import { UpdateConsumerPasswordDto } from './dto/update-password-request.dto'
@Injectable() @Injectable()
export class ConsumerService { export class ConsumerService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
) {}
private readonly infoCacheTtlSeconds = 300
async getInfo(consumer_id: string) { async getInfo(consumer_id: string) {
const cacheKey = RedisKeyMaker.consumerInfo(consumer_id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const consumer = await this.prisma.consumer.findUniqueOrThrow({ const consumer = await this.prisma.consumer.findUniqueOrThrow({
where: { where: {
id: consumer_id, id: consumer_id,
@@ -20,6 +37,91 @@ export class ConsumerService {
}, },
}) })
return ResponseMapper.single(consumer_mappersUtil(consumer)) const mappedConsumer = consumer_mappersUtil(consumer)
await this.redisService.setJson(cacheKey, mappedConsumer, this.infoCacheTtlSeconds)
return ResponseMapper.single(mappedConsumer)
}
async updateInfo(consumer_id: string, data: UpdateConsumerInfoDto) {
const consumerExists = await this.prisma.consumer.findUnique({
where: {
id: consumer_id,
},
select: {
type: true,
},
})
let dataForUpdate: ConsumerUpdateInput = {}
if (consumerExists?.type === 'LEGAL') {
dataForUpdate = {
legal: {
update: {
name: data.company_name,
registration_code: data.registration_code,
},
},
}
} else if (consumerExists?.type === 'INDIVIDUAL') {
dataForUpdate = {
individual: {
update: {
first_name: data.first_name,
last_name: data.last_name,
mobile_number: data.mobile_number,
national_code: data.national_code,
},
},
}
}
const consumer = await this.prisma.consumer.update({
where: {
id: consumer_id,
},
data: {
...dataForUpdate,
},
})
await this.redisService.delete(RedisKeyMaker.consumerInfo(consumer_id))
const partnerOwner = await this.prisma.consumer.findUnique({
where: { id: consumer_id },
select: {
legal: { select: { partner_id: true } },
individual: { select: { partner_id: true } },
},
})
const partnerId =
partnerOwner?.legal?.partner_id || partnerOwner?.individual?.partner_id || null
if (partnerId) {
await this.redisService.delete(
RedisKeyMaker.partnerConsumerInfo(partnerId, consumer_id),
)
}
return ResponseMapper.update(consumer)
}
async updatePassword(
consumer_id: string,
accountId: string,
data: UpdateConsumerPasswordDto,
) {
const consumer = await this.prisma.consumerAccount.update({
where: {
id: accountId,
consumer_id,
},
data: {
account: {
update: {
password: await PasswordUtil.hash(data.password),
},
},
},
})
return ResponseMapper.update(consumer)
} }
} }
@@ -1,3 +1,8 @@
import type { ConsumerService } from '../consumer.service' import type { ConsumerService } from '../consumer.service'
export type ConsumerServiceGetInfoResponseDto = Awaited<ReturnType<ConsumerService['getInfo']>> export type ConsumerServiceGetInfoResponseDto = Awaited<
ReturnType<ConsumerService['getInfo']>
>
export type ConsumerServiceUpdateInfoResponseDto = Awaited<
ReturnType<ConsumerService['updateInfo']>
>
@@ -0,0 +1,28 @@
import { ApiProperty } from '@nestjs/swagger'
import { IsString } from 'class-validator'
export class UpdateConsumerInfoDto {
@IsString()
@ApiProperty()
first_name: string
@IsString()
@ApiProperty()
last_name: string
@IsString()
@ApiProperty()
mobile_number: string
@IsString()
@ApiProperty()
national_code: string
@IsString()
@ApiProperty()
company_name: string
@IsString()
@ApiProperty()
registration_code: string
}
@@ -0,0 +1,8 @@
import { ApiProperty } from '@nestjs/swagger'
import { IsString } from 'class-validator'
export class UpdateConsumerPasswordDto {
@IsString()
@ApiProperty({ required: true })
password: string
}
@@ -0,0 +1,95 @@
import { ApiPropertyOptional } from '@nestjs/swagger'
import { Type } from 'class-transformer'
import {
IsDateString,
IsEnum,
IsNumber,
IsOptional,
IsString,
Max,
Min,
} from 'class-validator'
import { TspProviderResponseStatus } from 'generated/prisma/enums'
export class ConsumerSaleInvoicesFilterDto {
@ApiPropertyOptional({ type: Number, example: 1 })
@Type(() => Number)
@Min(1)
@IsOptional()
page?: number
@ApiPropertyOptional({ type: Number, example: 10, description: 'Max value is 50.' })
@Type(() => Number)
@Min(1)
@Max(50)
@IsOptional()
perPage?: number
@ApiPropertyOptional()
@IsOptional()
@IsDateString()
invoice_date_from?: string
@ApiPropertyOptional()
@IsOptional()
@IsDateString()
invoice_date_to?: string
@ApiPropertyOptional()
@IsOptional()
@IsDateString()
created_at_from?: string
@ApiPropertyOptional()
@IsOptional()
@IsDateString()
created_at_to?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
code?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
customer_name?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
customer_mobile?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
customer_national_id?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
customer_economic_code?: string
@ApiPropertyOptional({ enum: TspProviderResponseStatus })
@IsOptional()
@IsEnum(TspProviderResponseStatus)
status?: TspProviderResponseStatus
@ApiPropertyOptional()
@IsOptional()
@Type(() => Number)
@IsNumber()
total_amount?: number
@ApiPropertyOptional()
@IsOptional()
@Type(() => Number)
@IsNumber()
total_amount_from?: number
@ApiPropertyOptional()
@IsOptional()
@Type(() => Number)
@IsNumber()
total_amount_to?: number
}
@@ -1,6 +1,9 @@
import { PosInfo } from '@/common/decorators/posInfo.decorator'
import { TokenAccount } from '@/common/decorators/tokenInfo.decorator' import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
import { Body, Controller, Get, Param, Post } from '@nestjs/common' import type { IPosPayload } from '@/common/models'
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger' import { ApiTags } from '@nestjs/swagger'
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
import type { import type {
SaleInvoicesServiceFindAllResponseDto, SaleInvoicesServiceFindAllResponseDto,
SaleInvoicesServiceFindOneResponseDto, SaleInvoicesServiceFindOneResponseDto,
@@ -16,8 +19,9 @@ export class StatisticsController {
@Get('') @Get('')
async findAll( async findAll(
@TokenAccount('userId') consumerId: string, @TokenAccount('userId') consumerId: string,
@Query() query: ConsumerSaleInvoicesFilterDto,
): Promise<SaleInvoicesServiceFindAllResponseDto> { ): Promise<SaleInvoicesServiceFindAllResponseDto> {
return this.service.findAll(consumerId) return this.service.findAll(consumerId, query)
} }
@Get(':id') @Get(':id')
@@ -28,11 +32,6 @@ export class StatisticsController {
return this.service.findOne(consumerId, id) return this.service.findOne(consumerId, id)
} }
@Post(':id/send_tax')
async send(@TokenAccount('userId') consumerId: string, @Param('id') id: string) {
return this.service.send(consumerId, id)
}
@Post('send_tax_bulk') @Post('send_tax_bulk')
async sendBulk( async sendBulk(
@TokenAccount('userId') consumerId: string, @TokenAccount('userId') consumerId: string,
@@ -40,4 +39,24 @@ export class StatisticsController {
) { ) {
return this.service.sendBulk(consumerId, data.invoice_ids) return this.service.sendBulk(consumerId, data.invoice_ids)
} }
@Get(':id/inquiry')
inquiry(@PosInfo() posInfo: IPosPayload, @Param('id') id: string) {
return this.service.inquiry(posInfo.consumer_account_id, posInfo.pos_id, id)
}
@Post(':id/send')
send(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
return this.service.send(id, posInfo)
}
@Post(':id/retry')
retry(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
return this.service.retry(id, posInfo)
}
@Post(':id/revoke')
revoke(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
return this.service.revoke(id, posInfo)
}
} }
@@ -1,3 +1,5 @@
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
import { SharedSaleInvoiceAccessService } from '@/common/services/saleInvoices/sale-invoice-access.service'
import { SaleInvoiceTspModule } from '@/modules/tspProviders/sales-invoice-tsp.module' import { SaleInvoiceTspModule } from '@/modules/tspProviders/sales-invoice-tsp.module'
import { PrismaModule } from '@/prisma/prisma.module' import { PrismaModule } from '@/prisma/prisma.module'
import { Module } from '@nestjs/common' import { Module } from '@nestjs/common'
@@ -7,7 +9,7 @@ import { SaleInvoicesService } from './saleInvoices.service'
@Module({ @Module({
imports: [PrismaModule, SaleInvoiceTspModule], imports: [PrismaModule, SaleInvoiceTspModule],
controllers: [StatisticsController], controllers: [StatisticsController],
providers: [SaleInvoicesService], providers: [SaleInvoicesService, SharedSaleInvoiceActionsService, SharedSaleInvoiceAccessService],
exports: [SaleInvoicesService], exports: [SaleInvoicesService],
}) })
export class ConsumerSaleInvoicesModule {} export class ConsumerSaleInvoicesModule {}
@@ -1,3 +1,6 @@
import { IPosPayload } from '@/common/models'
import { QUERY_CONSTANTS } from '@/common/queryConstants'
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
import { translateEnumValue } from '@/common/utils' import { translateEnumValue } from '@/common/utils'
import { TspProviderResponseStatus } from '@/generated/prisma/enums' import { TspProviderResponseStatus } from '@/generated/prisma/enums'
import { import {
@@ -9,30 +12,20 @@ import { PrismaService } from '@/prisma/prisma.service'
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common' import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { SalesInvoiceTspService } from '../../tspProviders/sales-invoice-tsp.service' import { SalesInvoiceTspService } from '../../tspProviders/sales-invoice-tsp.service'
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
@Injectable() @Injectable()
export class SaleInvoicesService { export class SaleInvoicesService {
constructor( constructor(
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private salesInvoiceTaxService: SalesInvoiceTspService, private salesInvoiceTaxService: SalesInvoiceTspService,
private sharedSaleInvoiceActionsService: SharedSaleInvoiceActionsService,
) {} ) {}
private readonly defaultPerPage = 10
private readonly maxPerPage = 50
private readonly defaultSelect: SalesInvoiceSelect = { private readonly defaultSelect: SalesInvoiceSelect = {
id: true,
code: true,
total_amount: true,
invoice_date: true,
created_at: true,
consumer_account: {
select: {
role: true,
account: {
select: {
username: true,
},
},
},
},
pos: { pos: {
select: { select: {
id: true, id: true,
@@ -51,17 +44,6 @@ export class SaleInvoicesService {
}, },
}, },
}, },
tsp_attempts: {
orderBy: {
created_at: 'asc',
},
take: 1,
select: {
id: true,
status: true,
},
},
} }
private readonly invoiceMapper = (invoice: any) => { private readonly invoiceMapper = (invoice: any) => {
@@ -76,24 +58,181 @@ export class SaleInvoicesService {
} }
} }
async findAll(consumer_id: string, page = 1, perPage = 10) { async findAll(consumer_id: string, filter: ConsumerSaleInvoicesFilterDto) {
const invoicesWhere: SalesInvoiceWhereInput = { const invoicesWhere = this.buildFindAllWhere(consumer_id, filter)
consumer_account: { const normalizedPageValue = Number(filter.page ?? 1)
consumer_id, const normalizedPage = Number.isFinite(normalizedPageValue)
}, ? Math.max(1, Math.floor(normalizedPageValue))
} : 1
const requestedPerPageValue = Number(filter.perPage ?? this.defaultPerPage)
const requestedPerPage = Number.isFinite(requestedPerPageValue)
? Math.max(1, Math.floor(requestedPerPageValue))
: this.defaultPerPage
const normalizedPerPage = Math.min(requestedPerPage, this.maxPerPage)
const [invoices, total] = await this.prisma.$transaction(async tx => [ const [invoices, total] = await this.prisma.$transaction(async tx => [
await tx.salesInvoice.findMany({ await tx.salesInvoice.findMany({
where: invoicesWhere, where: invoicesWhere,
select: this.defaultSelect, orderBy: {
skip: (page - 1) * perPage, created_at: 'desc',
take: perPage, },
skip: (normalizedPage - 1) * normalizedPerPage,
take: normalizedPerPage,
select: {
...QUERY_CONSTANTS.SALE_INVOICE.summarySelect,
...this.defaultSelect,
},
}), }),
await tx.salesInvoice.count({ where: invoicesWhere }), await tx.salesInvoice.count({ where: invoicesWhere }),
]) ])
const mappedInvoices = invoices.map(this.invoiceMapper) const mappedInvoices = invoices.map(this.invoiceMapper)
return ResponseMapper.paginate(mappedInvoices, { page, perPage, total }) return ResponseMapper.paginate(mappedInvoices, {
page: normalizedPage,
perPage: normalizedPerPage,
total,
})
}
private buildFindAllWhere(
consumer_id: string,
filter: ConsumerSaleInvoicesFilterDto,
): SalesInvoiceWhereInput {
const where: SalesInvoiceWhereInput = {
consumer_account: {
consumer_id,
},
}
if (filter.code?.trim()) {
where.code = {
contains: filter.code.trim(),
}
}
if (filter.invoice_date_from || filter.invoice_date_to) {
where.invoice_date = {
...(filter.invoice_date_from ? { gte: new Date(filter.invoice_date_from) } : {}),
...(filter.invoice_date_to ? { lte: new Date(filter.invoice_date_to) } : {}),
}
}
if (filter.created_at_from || filter.created_at_to) {
where.created_at = {
...(filter.created_at_from ? { gte: new Date(filter.created_at_from) } : {}),
...(filter.created_at_to ? { lte: new Date(filter.created_at_to) } : {}),
}
}
if (
filter.total_amount !== undefined ||
filter.total_amount_from !== undefined ||
filter.total_amount_to !== undefined
) {
where.total_amount = {
...(filter.total_amount !== undefined ? { equals: filter.total_amount } : {}),
...(filter.total_amount_from !== undefined
? { gte: filter.total_amount_from }
: {}),
...(filter.total_amount_to !== undefined ? { lte: filter.total_amount_to } : {}),
}
}
if (
filter.customer_name?.trim() ||
filter.customer_mobile?.trim() ||
filter.customer_national_id?.trim() ||
filter.customer_economic_code?.trim()
) {
where.customer = {
is: {
OR: [
...(filter.customer_name?.trim()
? [
{
individual: {
is: {
OR: [
{ first_name: { contains: filter.customer_name.trim() } },
{ last_name: { contains: filter.customer_name.trim() } },
],
},
},
},
{
legal: {
is: {
name: {
contains: filter.customer_name.trim(),
},
},
},
},
]
: []),
...(filter.customer_mobile?.trim()
? [
{
individual: {
is: {
mobile_number: { contains: filter.customer_mobile.trim() },
},
},
},
]
: []),
...(filter.customer_national_id?.trim()
? [
{
individual: {
is: {
national_id: { contains: filter.customer_national_id.trim() },
},
},
},
]
: []),
...(filter.customer_economic_code?.trim()
? [
{
legal: {
is: {
OR: [
{
economic_code: {
contains: filter.customer_economic_code.trim(),
},
},
{
registration_number: {
contains: filter.customer_economic_code.trim(),
},
},
],
},
},
},
]
: []),
],
},
}
}
if (filter.status) {
if (filter.status === TspProviderResponseStatus.NOT_SEND) {
where.tsp_attempts = undefined
} else {
where.tsp_attempts = {
some: {
status: filter.status,
},
}
}
}
return where
} }
async findOne(consumer_id: string, id: string) { async findOne(consumer_id: string, id: string) {
@@ -106,71 +245,8 @@ export class SaleInvoicesService {
const invoice = await this.prisma.salesInvoice.findUniqueOrThrow({ const invoice = await this.prisma.salesInvoice.findUniqueOrThrow({
where: invoicesWhere, where: invoicesWhere,
select: { select: {
...QUERY_CONSTANTS.SALE_INVOICE.select,
...this.defaultSelect, ...this.defaultSelect,
notes: true,
created_at: true,
payments: {
select: {
amount: true,
payment_method: true,
},
},
items: {
select: {
id: true,
notes: true,
unit_price: true,
discount: true,
quantity: true,
total_amount: true,
payload: true,
good: {
select: {
id: true,
name: true,
pricing_model: true,
measure_unit: {
select: {
id: true,
name: true,
},
},
category: {
select: {
id: true,
name: true,
image_url: true,
},
},
},
},
},
},
customer: {
select: {
id: true,
type: true,
legal: {
select: {
name: true,
economic_code: true,
registration_number: true,
postal_code: true,
},
},
individual: {
select: {
first_name: true,
last_name: true,
economic_code: true,
national_id: true,
postal_code: true,
},
},
},
},
unknown_customer: true,
}, },
}) })
@@ -180,15 +256,47 @@ export class SaleInvoicesService {
throw new NotFoundException('فاکتور مورد نظر شما یافت نشد.') throw new NotFoundException('فاکتور مورد نظر شما یافت نشد.')
} }
async send(consumer_id: string, invoice_id: string) { async send(invoiceId: string, posInfo: IPosPayload) {
const tspProviderResult = await this.salesInvoiceTaxService.originalSend( const invoice = await this.sharedSaleInvoiceActionsService.send(
consumer_id, posInfo.consumer_account_id,
invoice_id, posInfo.pos_id,
invoiceId,
) )
return ResponseMapper.single({ return ResponseMapper.single(invoice)
...tspProviderResult, }
})
async retry(invoiceId: string, posInfo: IPosPayload) {
const invoice = await this.sharedSaleInvoiceActionsService.retry(
posInfo.consumer_account_id,
posInfo.pos_id,
invoiceId,
)
return ResponseMapper.single(invoice)
}
async revoke(invoiceId: string, posInfo: IPosPayload) {
const { consumer_account_id, pos_id, business_id, complex_id } = posInfo
const invoice = await this.sharedSaleInvoiceActionsService.revoke(
consumer_account_id,
pos_id,
complex_id,
business_id,
invoiceId,
)
return ResponseMapper.single(invoice)
}
async inquiry(consumer_account_id: string, pos_id: string, invoiceId: string) {
const invoice = await this.sharedSaleInvoiceActionsService.inquiry(
consumer_account_id,
pos_id,
invoiceId,
)
return ResponseMapper.single(invoice)
} }
async sendBulk(consumer_id: string, invoiceIds: string[]) { async sendBulk(consumer_id: string, invoiceIds: string[]) {
@@ -1,8 +1,8 @@
import { TokenAccount } from '@/common/decorators/tokenInfo.decorator' import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
import { Controller, Get } from '@nestjs/common' import { Controller, Get } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger' import { ApiTags } from '@nestjs/swagger'
import { StatisticsService } from './statistics.service'
import type { StatisticsServiceGetInvoicesResponseDto } from './dto/statistics-response.dto' import type { StatisticsServiceGetInvoicesResponseDto } from './dto/statistics-response.dto'
import { StatisticsService } from './statistics.service'
@ApiTags('ConsumerStatistics') @ApiTags('ConsumerStatistics')
@Controller('consumer/statistics') @Controller('consumer/statistics')
@@ -10,7 +10,9 @@ export class StatisticsController {
constructor(private readonly service: StatisticsService) {} constructor(private readonly service: StatisticsService) {}
@Get('invoices') @Get('invoices')
async getInvoices(@TokenAccount('userId') consumerId: string): Promise<StatisticsServiceGetInvoicesResponseDto> { async getInvoices(
@TokenAccount('userId') consumerId: string,
): Promise<StatisticsServiceGetInvoicesResponseDto> {
return this.service.getInvoices(consumerId) return this.service.getInvoices(consumerId)
} }
} }
@@ -1,3 +1,6 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants'
import { translateEnumValue } from '@/common/utils'
import { TspProviderResponseStatus } from '@/generated/prisma/enums'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
@@ -6,6 +9,18 @@ import { ResponseMapper } from 'common/response/response-mapper'
export class StatisticsService { export class StatisticsService {
constructor(private readonly prisma: PrismaService) {} constructor(private readonly prisma: PrismaService) {}
private readonly invoiceMapper = (invoice: any) => {
const { tsp_attempts, ...rest } = invoice || {}
return {
...rest,
status: translateEnumValue(
'TspProviderResponseStatus',
invoice.tsp_attempts?.[0]?.status || TspProviderResponseStatus.NOT_SEND,
),
}
}
async getInvoices(consumer_id: string) { async getInvoices(consumer_id: string) {
const startOfToday = new Date() const startOfToday = new Date()
startOfToday.setHours(0, 0, 0, 0) startOfToday.setHours(0, 0, 0, 0)
@@ -20,10 +35,7 @@ export class StatisticsService {
}, },
}, },
select: { select: {
id: true, ...QUERY_CONSTANTS.SALE_INVOICE.summarySelect,
code: true,
total_amount: true,
created_at: true,
consumer_account: { consumer_account: {
select: { select: {
role: true, role: true,
@@ -53,7 +65,10 @@ export class StatisticsService {
}, },
}, },
}, },
orderBy: {
created_at: 'desc',
},
}) })
return ResponseMapper.list(invoices) return ResponseMapper.list(invoices.map(this.invoiceMapper))
} }
} }
+35 -4
View File
@@ -1,5 +1,6 @@
import translates from '@/common/constants/translates/translates' import translates from '@/common/constants/translates/translates'
import { translateEnumValue } from '@/common/utils/enum-translator.util' import { translateEnumValue } from '@/common/utils/enum-translator.util'
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { import {
AccountStatus, AccountStatus,
AccountType, AccountType,
@@ -26,12 +27,22 @@ import {
TspProviderResponseStatus, TspProviderResponseStatus,
TspProviderType, TspProviderType,
} from '@/generated/prisma/enums' } from '@/generated/prisma/enums'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { GoldKarat, TspProviderCustomerType } from 'common/enums/enums' import { GoldKarat, TspProviderCustomerType } from 'common/enums/enums'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
@Injectable() @Injectable()
export class EnumsService { export class EnumsService {
constructor(private readonly redisService: RedisService) {}
private readonly cacheTtlSeconds = 24 * 60 * 60
private readonly cacheBuildVersion =
process.env.CACHE_BUILD_VERSION ||
process.env.APP_BUILD_ID ||
process.env.npm_package_version ||
'local'
private prepareData( private prepareData(
items: Record<string, string>, items: Record<string, string>,
enumName: keyof typeof translates.enums, enumName: keyof typeof translates.enums,
@@ -45,7 +56,7 @@ export class EnumsService {
}) })
} }
getAllEnums() { private buildAllEnums() {
return { return {
PaymentMethodType: this.prepareData(PaymentMethodType, 'PaymentMethodType'), PaymentMethodType: this.prepareData(PaymentMethodType, 'PaymentMethodType'),
GoldKarat: this.prepareData(GoldKarat, 'GoldKarat'), GoldKarat: this.prepareData(GoldKarat, 'GoldKarat'),
@@ -91,8 +102,28 @@ export class EnumsService {
} }
} }
getEnumValues(enumName: keyof typeof translates.enums) { async getAllEnums() {
const enums = this.getAllEnums() const cacheKey = RedisKeyMaker.enumsAll(this.cacheBuildVersion)
return ResponseMapper.list(enums[enumName] || []) const cached = await this.redisService.getJson<Record<string, unknown[]>>(cacheKey)
if (cached) {
return cached
}
const enums = this.buildAllEnums()
await this.redisService.setJson(cacheKey, enums, this.cacheTtlSeconds)
return enums
}
async getEnumValues(enumName: keyof typeof translates.enums) {
const cacheKey = RedisKeyMaker.enumsValues(this.cacheBuildVersion, enumName)
const cached = await this.redisService.getJson<unknown[]>(cacheKey)
if (cached) {
return ResponseMapper.list(cached)
}
const enums = await this.getAllEnums()
const items = enums[enumName] || []
await this.redisService.setJson(cacheKey, items, this.cacheTtlSeconds)
return ResponseMapper.list(items)
} }
} }
@@ -0,0 +1,167 @@
import { RedisKeyMaker } from '@/common/utils'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common'
@Injectable()
export class PartnersCacheInvalidationService {
constructor(private readonly redisService: RedisService) {}
async invalidatePartnerSummary(partnerId: string): Promise<void> {
await this.invalidatePartnersList()
await this.redisService.delete(RedisKeyMaker.partnerDetail(partnerId))
}
async invalidatePartnersList(): Promise<void> {
await this.redisService.delete(RedisKeyMaker.partnersList())
}
async invalidatePartnerDetail(partnerId: string): Promise<void> {
await this.invalidatePartnerSummary(partnerId)
}
async invalidatePartnerLicenseReadModels(partnerId: string): Promise<void> {
await this.redisService.deleteByPatterns([
RedisKeyMaker.partnerActivatedLicensesListPattern(partnerId),
RedisKeyMaker.partnerLicenseChargeTransactionsListPattern(partnerId),
RedisKeyMaker.partnerLicenseChargeTransactionDetailPattern(partnerId),
])
}
async invalidatePartnerLicenses(partnerId: string): Promise<void> {
await this.invalidatePartnerSummary(partnerId)
await this.invalidatePartnerLicenseReadModels(partnerId)
}
// consumers //
async invalidatePartnerConsumers(
partnerId: string,
page: number,
perPage: number,
): Promise<void> {
await this.redisService.delete(
RedisKeyMaker.partnerConsumersList(partnerId, page, perPage),
)
}
async invalidatePartnerConsumerReadModels(
partnerId: string,
consumerId: string,
): Promise<void> {
await this.redisService.deleteByPatterns([
RedisKeyMaker.partnerConsumersListPattern(partnerId),
RedisKeyMaker.partnerConsumerInfo(partnerId, consumerId),
])
}
async invalidatePartnerConsumerBusinessActivitiesReadModels(
partnerId: string,
consumerId: string,
): Promise<void> {
await this.invalidatePartnerConsumerReadModels(partnerId, consumerId)
await this.redisService.deleteByPattern(
RedisKeyMaker.partnerConsumerBusinessActivitiesPattern(partnerId, consumerId),
)
}
async invalidatePartnerConsumerBusinessActivityReadModels(
partnerId: string,
consumerId: string,
businessActivityId: string,
): Promise<void> {
await this.invalidatePartnerConsumerBusinessActivitiesReadModels(
partnerId,
consumerId,
)
await this.redisService.delete(
RedisKeyMaker.partnerConsumerBusinessActivityInfo(
partnerId,
consumerId,
businessActivityId,
),
)
}
async invalidatePartnerConsumerBusinessActivityComplexesReadModels(
partnerId: string,
consumerId: string,
businessActivityId: string,
): Promise<void> {
await this.invalidatePartnerConsumerBusinessActivitiesReadModels(
partnerId,
consumerId,
)
await this.redisService.deleteByPattern(
RedisKeyMaker.partnerConsumerBusinessActivityComplexesPattern(
partnerId,
consumerId,
businessActivityId,
),
)
}
async invalidatePartnerConsumerBusinessActivityComplexReadModels(
partnerId: string,
consumerId: string,
businessActivityId: string,
complexId: string,
): Promise<void> {
await this.invalidatePartnerConsumerBusinessActivityComplexesReadModels(
partnerId,
consumerId,
businessActivityId,
)
await this.redisService.delete(
RedisKeyMaker.partnerConsumerBusinessActivityComplexInfo(
partnerId,
consumerId,
businessActivityId,
complexId,
),
)
}
async invalidatePartnerConsumerBusinessActivityComplexPosesReadModels(
partnerId: string,
consumerId: string,
businessActivityId: string,
complexId: string,
): Promise<void> {
await this.invalidatePartnerConsumerBusinessActivitiesReadModels(
partnerId,
consumerId,
)
await this.redisService.deleteByPattern(
RedisKeyMaker.partnerConsumerBusinessActivityComplexPosesPattern(
partnerId,
consumerId,
businessActivityId,
complexId,
),
)
}
async invalidatePartnerConsumerBusinessActivityComplexPosReadModels(
partnerId: string,
consumerId: string,
businessActivityId: string,
complexId: string,
posId: string,
): Promise<void> {
await this.invalidatePartnerConsumerBusinessActivityComplexPosesReadModels(
partnerId,
consumerId,
businessActivityId,
complexId,
)
await this.redisService.delete(
RedisKeyMaker.partnerConsumerBusinessActivityComplexPosInfo(
partnerId,
consumerId,
businessActivityId,
complexId,
posId,
),
)
}
}
@@ -1,13 +1,22 @@
import { RedisKeyMaker } from '@/common/utils'
import { BusinessActivitySelect } from '@/generated/prisma/models' import { BusinessActivitySelect } from '@/generated/prisma/models'
import { getPartnerFirstRemainingLicense } from '@/modules/partners/utils/getPartnerRemainingLicenses.util' import { getPartnerFirstRemainingLicense } from '@/modules/partners/utils/getPartnerRemainingLicenses.util'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { BadRequestException, Injectable } from '@nestjs/common' import { BadRequestException, Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { PartnersCacheInvalidationService } from '../../cache/partners-cache-invalidation.service'
import { CreateBusinessActivitiesDto } from './dto/create-business-activities.dto' import { CreateBusinessActivitiesDto } from './dto/create-business-activities.dto'
@Injectable() @Injectable()
export class BusinessActivitiesService { export class BusinessActivitiesService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
private readonly partnersCacheInvalidationService: PartnersCacheInvalidationService,
) {}
private readonly cacheTtlSeconds = 300
private readonly setExpireDate = (starts_at: Date) => { private readonly setExpireDate = (starts_at: Date) => {
return new Date( return new Date(
@@ -85,6 +94,19 @@ export class BusinessActivitiesService {
} }
async findAll(partner_id: string, consumer_id: string, page = 1, perPage = 10) { async findAll(partner_id: string, consumer_id: string, page = 1, perPage = 10) {
const cacheKey = RedisKeyMaker.partnerConsumerBusinessActivitiesList(
partner_id,
consumer_id,
page,
perPage,
)
const cached = await this.redisService.getJson<{ items: unknown[]; total: number }>(
cacheKey,
)
if (cached) {
return ResponseMapper.paginate(cached.items, { total: cached.total, page, perPage })
}
const where = this.defaultWhere(partner_id, consumer_id) const where = this.defaultWhere(partner_id, consumer_id)
const [businessActivities, total] = await this.prisma.$transaction(async tx => [ const [businessActivities, total] = await this.prisma.$transaction(async tx => [
await tx.businessActivity.findMany({ await tx.businessActivity.findMany({
@@ -95,13 +117,26 @@ export class BusinessActivitiesService {
}), }),
await tx.businessActivity.count({ where }), await tx.businessActivity.count({ where }),
]) ])
return ResponseMapper.paginate( const mappedItems = businessActivities.map(this.prepareBusinessActivityResponse)
businessActivities.map(this.prepareBusinessActivityResponse), await this.redisService.setJson(
{ total, page, perPage }, cacheKey,
{ items: mappedItems, total },
this.cacheTtlSeconds,
) )
return ResponseMapper.paginate(mappedItems, { total, page, perPage })
} }
async findOne(partner_id: string, consumer_id: string, id: string) { async findOne(partner_id: string, consumer_id: string, id: string) {
const cacheKey = RedisKeyMaker.partnerConsumerBusinessActivityInfo(
partner_id,
consumer_id,
id,
)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const businessActivity = await this.prisma.businessActivity.findUnique({ const businessActivity = await this.prisma.businessActivity.findUnique({
where: { where: {
...this.defaultWhere(partner_id, consumer_id), ...this.defaultWhere(partner_id, consumer_id),
@@ -109,7 +144,9 @@ export class BusinessActivitiesService {
}, },
select: this.defaultSelect, select: this.defaultSelect,
}) })
return ResponseMapper.single(this.prepareBusinessActivityResponse(businessActivity)) const mappedItem = this.prepareBusinessActivityResponse(businessActivity)
await this.redisService.setJson(cacheKey, mappedItem, this.cacheTtlSeconds)
return ResponseMapper.single(mappedItem)
} }
async create( async create(
@@ -187,6 +224,10 @@ export class BusinessActivitiesService {
}) })
}) })
await this.partnersCacheInvalidationService.invalidatePartnerConsumerBusinessActivitiesReadModels(
partner_id,
consumer_id,
)
return ResponseMapper.create(businessActivity) return ResponseMapper.create(businessActivity)
} }
@@ -196,6 +237,13 @@ export class BusinessActivitiesService {
data, data,
select: this.defaultSelect, select: this.defaultSelect,
}) })
await this.partnersCacheInvalidationService.invalidatePartnerConsumerBusinessActivityReadModels(
partner_id,
consumer_id,
id,
)
return ResponseMapper.update(businessActivity) return ResponseMapper.update(businessActivity)
} }
@@ -3,7 +3,12 @@ import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger' import { ApiTags } from '@nestjs/swagger'
import { BusinessActivityComplexesService } from './complexes.service' import { BusinessActivityComplexesService } from './complexes.service'
import { CreateComplexDto, UpdateComplexDto } from './dto/complex.dto' import { CreateComplexDto, UpdateComplexDto } from './dto/complex.dto'
import type { BusinessActivityComplexesServiceCreateResponseDto, BusinessActivityComplexesServiceFindAllResponseDto, BusinessActivityComplexesServiceFindOneResponseDto, BusinessActivityComplexesServiceUpdateResponseDto } from './dto/complexes-response.dto' import type {
BusinessActivityComplexesServiceCreateResponseDto,
BusinessActivityComplexesServiceFindAllResponseDto,
BusinessActivityComplexesServiceFindOneResponseDto,
BusinessActivityComplexesServiceUpdateResponseDto,
} from './dto/complexes-response.dto'
@ApiTags('PartnerBusinessActivityComplexes') @ApiTags('PartnerBusinessActivityComplexes')
@Controller( @Controller(
@@ -34,10 +39,11 @@ export class BusinessActivityComplexesController {
@Post() @Post()
async create( async create(
@PartnerInfo('id') partnerId: string, @PartnerInfo('id') partnerId: string,
@Param('consumerId') consumerId: string,
@Param('businessActivityId') businessActivityId: string, @Param('businessActivityId') businessActivityId: string,
@Body() data: CreateComplexDto, @Body() data: CreateComplexDto,
): Promise<BusinessActivityComplexesServiceCreateResponseDto> { ): Promise<BusinessActivityComplexesServiceCreateResponseDto> {
return this.service.create(partnerId, businessActivityId, data) return this.service.create(partnerId, consumerId, businessActivityId, data)
} }
@Patch(':id') @Patch(':id')
@@ -1,13 +1,22 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants' import { QUERY_CONSTANTS } from '@/common/queryConstants'
import { RedisKeyMaker } from '@/common/utils'
import { ComplexSelect, ComplexWhereInput } from '@/generated/prisma/models' import { ComplexSelect, ComplexWhereInput } from '@/generated/prisma/models'
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { BadRequestException, Injectable } from '@nestjs/common' import { BadRequestException, Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { CreateComplexDto, UpdateComplexDto } from './dto/complex.dto' import { CreateComplexDto, UpdateComplexDto } from './dto/complex.dto'
@Injectable() @Injectable()
export class BusinessActivityComplexesService { export class BusinessActivityComplexesService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
private readonly partnersCacheInvalidationService: PartnersCacheInvalidationService,
) {}
private readonly cacheTtlSeconds = 300
private readonly defaultSelect: ComplexSelect = { private readonly defaultSelect: ComplexSelect = {
id: true, id: true,
@@ -49,6 +58,20 @@ export class BusinessActivityComplexesService {
page = 1, page = 1,
perPage = 10, perPage = 10,
) { ) {
const cacheKey = RedisKeyMaker.partnerConsumerBusinessActivityComplexesList(
partner_id,
consumer_id,
business_activity_id,
page,
perPage,
)
const cached = await this.redisService.getJson<{ items: unknown[]; total: number }>(
cacheKey,
)
if (cached) {
return ResponseMapper.paginate(cached.items, { total: cached.total, page, perPage })
}
const where = this.defaultWhere(partner_id, consumer_id, business_activity_id) const where = this.defaultWhere(partner_id, consumer_id, business_activity_id)
const [complexes, total] = await this.prisma.$transaction(async tx => [ const [complexes, total] = await this.prisma.$transaction(async tx => [
await tx.complex.findMany({ await tx.complex.findMany({
@@ -74,6 +97,11 @@ export class BusinessActivityComplexesService {
pos_count: _count.pos_list, pos_count: _count.pos_list,
} }
}) })
await this.redisService.setJson(
cacheKey,
{ items: mappedComplexes, total },
this.cacheTtlSeconds,
)
return ResponseMapper.paginate(mappedComplexes, { total, page, perPage }) return ResponseMapper.paginate(mappedComplexes, { total, page, perPage })
} }
@@ -83,18 +111,40 @@ export class BusinessActivityComplexesService {
business_activity_id: string, business_activity_id: string,
id: string, id: string,
) { ) {
const complex = await this.prisma.complex.findUnique({ const cacheKey = RedisKeyMaker.partnerConsumerBusinessActivityComplexInfo(
partner_id,
consumer_id,
business_activity_id,
id,
)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const complex = await this.prisma.complex.findFirst({
where: { where: {
...this.defaultWhere(partner_id, consumer_id, business_activity_id), ...this.defaultWhere(partner_id, consumer_id, business_activity_id),
id, id,
}, },
select: this.defaultSelect, select: this.defaultSelect,
}) })
if (!complex) {
throw new BadRequestException('شعبه مورد نظر یافت نشد.')
}
await this.redisService.setJson(cacheKey, complex, this.cacheTtlSeconds)
return ResponseMapper.single(complex) return ResponseMapper.single(complex)
} }
async create(partner_id: string, business_id: string, data: CreateComplexDto) { async create(
const complex = this.prisma.$transaction(async tx => { partner_id: string,
business_id: string,
consumer_id: string,
data: CreateComplexDto,
) {
const complex = await this.prisma.$transaction(async tx => {
const relatedLicense = await tx.licenseAccountAllocation.findFirst({ const relatedLicense = await tx.licenseAccountAllocation.findFirst({
where: { where: {
license_activation: { license_activation: {
@@ -121,7 +171,7 @@ export class BusinessActivityComplexesService {
) )
} }
return await this.prisma.complex.create({ return await tx.complex.create({
data: { data: {
...data, ...data,
business_activity: { business_activity: {
@@ -133,6 +183,12 @@ export class BusinessActivityComplexesService {
}) })
}) })
await this.partnersCacheInvalidationService.invalidatePartnerConsumerBusinessActivityComplexesReadModels(
partner_id,
consumer_id,
business_id,
)
return ResponseMapper.create(complex) return ResponseMapper.create(complex)
} }
@@ -147,6 +203,13 @@ export class BusinessActivityComplexesService {
where: { ...this.defaultWhere(partner_id, consumer_id, business_activity_id), id }, where: { ...this.defaultWhere(partner_id, consumer_id, business_activity_id), id },
data, data,
}) })
await this.partnersCacheInvalidationService.invalidatePartnerConsumerBusinessActivityComplexReadModels(
partner_id,
consumer_id,
business_activity_id,
id,
)
return ResponseMapper.update(complex) return ResponseMapper.update(complex)
} }
@@ -1,7 +1,7 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants' import { QUERY_CONSTANTS } from '@/common/queryConstants'
import { consumerRelatedPartner } from '@/common/queryConstants/consumer' import { consumerRelatedPartner } from '@/common/queryConstants/consumer'
import { PrismaErrorUtil } from '@/common/utils/prisma-error.util'
import { PasswordUtil } from '@/common/utils/password.util' import { PasswordUtil } from '@/common/utils/password.util'
import { PrismaErrorUtil } from '@/common/utils/prisma-error.util'
import { import {
AccountStatus, AccountStatus,
AccountType, AccountType,
@@ -9,14 +9,22 @@ import {
POSStatus, POSStatus,
} from '@/generated/prisma/enums' } from '@/generated/prisma/enums'
import { PosSelect } from '@/generated/prisma/models' import { PosSelect } from '@/generated/prisma/models'
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { BadRequestException, Injectable } from '@nestjs/common' import { BadRequestException, Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { CreatePosDto, UpdatePosDto } from './dto/pos.dto' import { CreatePosDto, UpdatePosDto } from './dto/pos.dto'
@Injectable() @Injectable()
export class ComplexPosesService { export class ComplexPosesService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
private readonly partnersCacheInvalidationService: PartnersCacheInvalidationService,
) {}
private readonly cacheTtlSeconds = 300
private readonly defaultSelect: PosSelect = { private readonly defaultSelect: PosSelect = {
id: true, id: true,
@@ -1,6 +1,7 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants' import { QUERY_CONSTANTS } from '@/common/queryConstants'
import mapConsumerWithLicenseUtil from '@/common/utils/mappers/consumer_mappers.util' import mapConsumerWithLicenseUtil from '@/common/utils/mappers/consumer_mappers.util'
import { PasswordUtil } from '@/common/utils/password.util' import { PasswordUtil } from '@/common/utils/password.util'
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { import {
AccountStatus, AccountStatus,
AccountType, AccountType,
@@ -15,13 +16,21 @@ import {
ConsumerWhereInput, ConsumerWhereInput,
} from '@/generated/prisma/models' } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { BadRequestException, Injectable } from '@nestjs/common' import { BadRequestException, Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { PartnersCacheInvalidationService } from '../cache/partners-cache-invalidation.service'
import { CreateConsumerDto, UpdateConsumerDto } from './dto/create-consumers.dto' import { CreateConsumerDto, UpdateConsumerDto } from './dto/create-consumers.dto'
@Injectable() @Injectable()
export class PartnerConsumersService { export class PartnerConsumersService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
private readonly partnersCacheInvalidationService: PartnersCacheInvalidationService,
) {}
private readonly infoCacheTtlSeconds = 300
private readonly setExpireDate = (starts_at: Date) => { private readonly setExpireDate = (starts_at: Date) => {
return new Date( return new Date(
@@ -54,6 +63,14 @@ export class PartnerConsumersService {
}) })
async findAll(partner_id: string, page = 1, perPage = 10) { async findAll(partner_id: string, page = 1, perPage = 10) {
const cacheKey = RedisKeyMaker.partnerConsumersList(partner_id, page, perPage)
const cached = await this.redisService.getJson<{ items: unknown[]; total: number }>(
cacheKey,
)
if (cached) {
return ResponseMapper.paginate(cached.items, { total: cached.total, page, perPage })
}
const [consumers, total] = await this.prisma.$transaction(async tx => [ const [consumers, total] = await this.prisma.$transaction(async tx => [
await tx.consumer.findMany({ await tx.consumer.findMany({
where: this.defaultWhere(partner_id), where: this.defaultWhere(partner_id),
@@ -65,7 +82,13 @@ export class PartnerConsumersService {
where: this.defaultWhere(partner_id), where: this.defaultWhere(partner_id),
}), }),
]) ])
return ResponseMapper.paginate(consumers.map(mapConsumerWithLicenseUtil), { const mappedItems = consumers.map(mapConsumerWithLicenseUtil)
await this.redisService.setJson(
cacheKey,
{ items: mappedItems, total },
this.infoCacheTtlSeconds,
)
return ResponseMapper.paginate(mappedItems, {
total, total,
page, page,
perPage, perPage,
@@ -73,6 +96,12 @@ export class PartnerConsumersService {
} }
async findOne(partner_id: string, consumer_id: string) { async findOne(partner_id: string, consumer_id: string) {
const cacheKey = RedisKeyMaker.partnerConsumerInfo(partner_id, consumer_id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const consumer = await this.prisma.consumer.findUniqueOrThrow({ const consumer = await this.prisma.consumer.findUniqueOrThrow({
where: { where: {
...(this.defaultWhere(partner_id) as any), ...(this.defaultWhere(partner_id) as any),
@@ -81,7 +110,14 @@ export class PartnerConsumersService {
select: this.defaultSelect, select: this.defaultSelect,
}) })
return ResponseMapper.single(mapConsumerWithLicenseUtil(consumer)) const mappedConsumer = mapConsumerWithLicenseUtil(consumer)
await this.redisService.setJson(
RedisKeyMaker.consumerInfo(consumer_id),
mappedConsumer,
this.infoCacheTtlSeconds,
)
await this.redisService.setJson(cacheKey, mappedConsumer, this.infoCacheTtlSeconds)
return ResponseMapper.single(mappedConsumer)
} }
async create(partner_id: string, data: CreateConsumerDto) { async create(partner_id: string, data: CreateConsumerDto) {
@@ -224,11 +260,16 @@ export class PartnerConsumersService {
}) })
}) })
await this.partnersCacheInvalidationService.invalidatePartnerConsumerReadModels(
partner_id,
consumer.id,
)
return ResponseMapper.single(mapConsumerWithLicenseUtil(consumer)) return ResponseMapper.single(mapConsumerWithLicenseUtil(consumer))
} }
async update(id: string, partner_id: string, data: UpdateConsumerDto) { async update(id: string, partner_id: string, data: UpdateConsumerDto) {
return this.prisma.consumer.update({ const updatedConsumer = await this.prisma.consumer.update({
where: { where: {
...(this.defaultWhere(partner_id) as any), ...(this.defaultWhere(partner_id) as any),
id, id,
@@ -243,5 +284,13 @@ export class PartnerConsumersService {
}, },
}, },
}) })
await this.partnersCacheInvalidationService.invalidatePartnerConsumerReadModels(
partner_id,
id,
)
await this.redisService.delete(RedisKeyMaker.consumerInfo(id))
return updatedConsumer
} }
} }
@@ -0,0 +1,8 @@
import { ApiProperty } from '@nestjs/swagger'
import { IsString } from 'class-validator'
export class UpdatePartnerPasswordDto {
@IsString()
@ApiProperty({ required: true })
password: string
}
+24 -6
View File
@@ -1,16 +1,24 @@
import { PartnerInfo } from '@/common/decorators/partnerInfo.decorator' import { PartnerInfo } from '@/common/decorators/partnerInfo.decorator'
import type { IPartnerPayload } from '@/common/models/partnerPayload.model'
import { multerImageOptions } from '@/multer.config' import { multerImageOptions } from '@/multer.config'
import { import {
Body, Body,
Controller, Controller,
Get, Get,
Patch, Patch,
Put,
UploadedFile, UploadedFile,
UseInterceptors, UseInterceptors,
} from '@nestjs/common' } from '@nestjs/common'
import { FileInterceptor } from '@nestjs/platform-express' import { FileInterceptor } from '@nestjs/platform-express'
import { ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger' import { ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger'
import { UpdatePartnerProfileDto } from './dto/partner.dto' import { UpdatePartnerProfileDto } from './dto/partner.dto'
import {
PartnerServiceGetInfoResponseDto,
PartnerServiceMeResponseDto,
PartnerServiceUpdateInfoResponseDto,
} from './dto/partners-response.dto'
import { UpdatePartnerPasswordDto } from './dto/update-password-request.dto'
import { PartnerService } from './partners.service' import { PartnerService } from './partners.service'
@ApiTags('Partner') @ApiTags('Partner')
@@ -19,16 +27,20 @@ export class PartnerController {
constructor(private service: PartnerService) {} constructor(private service: PartnerService) {}
@Get('') @Get('')
async me(@PartnerInfo() { id, account_id }: IPartnerPayload): Promise<PartnerServiceMeResponseDto> { async me(
@PartnerInfo() { id, account_id }: IPartnerPayload,
): Promise<PartnerServiceMeResponseDto> {
return this.service.me(id, account_id) return this.service.me(id, account_id)
} }
@Get('info') @Get('info')
async getInfo(@PartnerInfo('id') partnerId: string): Promise<PartnerServiceGetInfoResponseDto> { async getInfo(
@PartnerInfo('id') partnerId: string,
): Promise<PartnerServiceGetInfoResponseDto> {
return this.service.getInfo(partnerId) return this.service.getInfo(partnerId)
} }
@Patch('profile') @Patch('')
@UseInterceptors(FileInterceptor('logo', multerImageOptions)) @UseInterceptors(FileInterceptor('logo', multerImageOptions))
@ApiConsumes('multipart/form-data') @ApiConsumes('multipart/form-data')
@ApiBody({ @ApiBody({
@@ -46,7 +58,13 @@ export class PartnerController {
): Promise<PartnerServiceUpdateInfoResponseDto> { ): Promise<PartnerServiceUpdateInfoResponseDto> {
return this.service.updateInfo(partnerId, data, logo) return this.service.updateInfo(partnerId, data, logo)
} }
}
import type { IPartnerPayload } from '@/common/models/partnerPayload.model' @Put('update-password')
import type { PartnerServiceGetInfoResponseDto, PartnerServiceMeResponseDto, PartnerServiceUpdateInfoResponseDto } from './dto/partners-response.dto' async updatePassword(
@PartnerInfo('id') partnerId: string,
@PartnerInfo('account_id') accountId: string,
@Body() data: UpdatePartnerPasswordDto,
) {
return this.service.updatePassword(partnerId, accountId, data)
}
}
+40 -6
View File
@@ -1,22 +1,23 @@
import { UploadedFileTypes } from '@/common/enums/enums' import { UploadedFileTypes } from '@/common/enums/enums'
import { ResponseMapper } from '@/common/response/response-mapper' import { ResponseMapper } from '@/common/response/response-mapper'
import { PartnerAccountSelect } from '@/generated/prisma/models' import { PasswordUtil } from '@/common/utils'
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
import { UploaderService } from '@/modules/uploader/uploader.service' import { UploaderService } from '@/modules/uploader/uploader.service'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { UpdatePartnerProfileDto } from './dto/partner.dto' import { UpdatePartnerProfileDto } from './dto/partner.dto'
import { UpdatePartnerPasswordDto } from './dto/update-password-request.dto'
@Injectable() @Injectable()
export class PartnerService { export class PartnerService {
constructor( constructor(
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private readonly uploaderService: UploaderService, private readonly uploaderService: UploaderService,
private readonly cacheInvalidationService: PartnersCacheInvalidationService,
) {} ) {}
private readonly defaultSelect: PartnerAccountSelect = {}
async me(partner_id: string, account_id: string) { async me(partner_id: string, account_id: string) {
const partner = await this.prisma.partnerAccount.findUniqueOrThrow({ const partnerAccount = await this.prisma.partnerAccount.findUniqueOrThrow({
where: { where: {
id: account_id, id: account_id,
partner_id, partner_id,
@@ -33,12 +34,21 @@ export class PartnerService {
select: { select: {
id: true, id: true,
name: true, name: true,
code: true,
logo_url: true,
}, },
}, },
}, },
}) })
return ResponseMapper.single(partner) return ResponseMapper.single({
...partnerAccount.partner,
account: {
role: partnerAccount.role,
id: partnerAccount.id,
username: partnerAccount.account.username,
},
})
} }
async getInfo(partner_id: string) { async getInfo(partner_id: string) {
@@ -234,10 +244,34 @@ export class PartnerService {
...rest, ...rest,
...(logo_url ? { logo_url } : {}), ...(logo_url ? { logo_url } : {}),
}, },
select: this.defaultSelect,
}) })
}) })
await this.cacheInvalidationService.invalidatePartnersList()
await this.cacheInvalidationService.invalidatePartnerDetail(partner_id)
return ResponseMapper.single(updatedPartner) return ResponseMapper.single(updatedPartner)
} }
async updatePassword(
partner_id: string,
accountId: string,
data: UpdatePartnerPasswordDto,
) {
const partnerAccount = await this.prisma.partnerAccount.update({
where: {
id: accountId,
partner_id,
},
data: {
account: {
update: {
password: await PasswordUtil.hash(data.password),
},
},
},
})
return ResponseMapper.update(partnerAccount)
}
} }
+25
View File
@@ -0,0 +1,25 @@
import { Injectable } from '@nestjs/common'
import { RedisService } from '@/redis/redis.service'
@Injectable()
export class PosCacheInvalidationService {
constructor(private readonly redisService: RedisService) {}
async invalidateGoodsListByGuild(guildId: string): Promise<void> {
const client = await this.redisService.getClient()
const keys = await client.keys(`pos:ba:*:guild:${guildId}:goods:list`)
if (keys.length > 0) {
await client.del(keys)
}
}
async invalidateGoodsListByBusinessActivity(
businessActivityId: string,
): Promise<void> {
const client = await this.redisService.getClient()
const keys = await client.keys(`pos:ba:${businessActivityId}:guild:*:goods:list`)
if (keys.length > 0) {
await client.del(keys)
}
}
}
@@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/swagger'
import { CreateGoodDto } from './create-good.dto'
export class UpdateGoodDto extends PartialType(CreateGoodDto) {}
+88 -1
View File
@@ -1,12 +1,22 @@
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { GoodSelect } from '@/generated/prisma/models' import { GoodSelect } from '@/generated/prisma/models'
import { PosCacheInvalidationService } from '@/modules/pos/cache/pos-cache-invalidation.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from '../../../common/response/response-mapper' import { ResponseMapper } from '../../../common/response/response-mapper'
import { PrismaService } from '../../../prisma/prisma.service' import { PrismaService } from '../../../prisma/prisma.service'
import { CreateGoodDto } from './dto/create-good.dto' import { CreateGoodDto } from './dto/create-good.dto'
import { UpdateGoodDto } from './dto/update-good.dto'
@Injectable() @Injectable()
export class GoodsService { export class GoodsService {
constructor(private prisma: PrismaService) {} constructor(
private prisma: PrismaService,
private readonly redisService: RedisService,
private readonly posCacheInvalidationService: PosCacheInvalidationService,
) {}
private readonly listCacheTtlSeconds = 300
private readonly defaultSelect: GoodSelect = { private readonly defaultSelect: GoodSelect = {
id: true, id: true,
@@ -18,6 +28,8 @@ export class GoodsService {
select: { select: {
id: true, id: true,
name: true, name: true,
code: true,
VAT: true,
}, },
}, },
local_sku: true, local_sku: true,
@@ -40,6 +52,12 @@ export class GoodsService {
} }
async findAll(business_activity_id: string, guild_id: string) { async findAll(business_activity_id: string, guild_id: string) {
const cacheKey = RedisKeyMaker.posGoodsList(business_activity_id, guild_id)
const cached = await this.redisService.getJson<unknown[]>(cacheKey)
if (cached) {
return ResponseMapper.list(cached)
}
const goods = await this.prisma.good.findMany({ const goods = await this.prisma.good.findMany({
where: { where: {
OR: [ OR: [
@@ -57,6 +75,8 @@ export class GoodsService {
select: this.defaultSelect, select: this.defaultSelect,
}) })
await this.redisService.setJson(cacheKey, goods, this.listCacheTtlSeconds)
return ResponseMapper.list(goods) return ResponseMapper.list(goods)
} }
@@ -115,6 +135,73 @@ export class GoodsService {
select: this.defaultSelect, select: this.defaultSelect,
}) })
await this.posCacheInvalidationService.invalidateGoodsListByBusinessActivity(
business_activity_id,
)
return ResponseMapper.create(good) return ResponseMapper.create(good)
} }
async update(id: string, data: UpdateGoodDto, business_activity_id: string) {
const { category_id, sku_id, measure_unit_id, ...rest } = data
const good = await this.prisma.good.update({
where: {
id,
business_activity_id,
},
data: {
...rest,
...(measure_unit_id
? {
measure_unit: {
connect: {
id: measure_unit_id,
},
},
}
: {}),
...(sku_id
? {
sku: {
connect: {
id: sku_id,
},
},
}
: {}),
...(category_id
? {
category: {
connect: {
id: category_id,
},
},
}
: {}),
},
select: this.defaultSelect,
})
await this.posCacheInvalidationService.invalidateGoodsListByBusinessActivity(
business_activity_id,
)
return ResponseMapper.update(good)
}
async delete(id: string, business_activity_id: string) {
await this.prisma.good.delete({
where: {
id,
business_activity_id,
},
})
await this.posCacheInvalidationService.invalidateGoodsListByBusinessActivity(
business_activity_id,
)
return ResponseMapper.delete()
}
} }
+29 -5
View File
@@ -1,15 +1,29 @@
import { QUERY_CONSTANTS } from '@/common/queryConstants' import { QUERY_CONSTANTS } from '@/common/queryConstants'
import consumer_mappersUtil from '@/common/utils/mappers/consumer_mappers.util' import consumer_mappersUtil from '@/common/utils/mappers/consumer_mappers.util'
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
import { ConsumerStatus } from '@/generated/prisma/enums' import { ConsumerStatus } from '@/generated/prisma/enums'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { RedisService } from '@/redis/redis.service'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
@Injectable() @Injectable()
export class PosService { export class PosService {
constructor(private readonly prisma: PrismaService) {} constructor(
private readonly prisma: PrismaService,
private readonly redisService: RedisService,
) {}
private readonly infoCacheTtlSeconds = 300
private readonly meCacheTtlSeconds = 120
async getInfo(pos_id: string) { async getInfo(pos_id: string) {
const cacheKey = RedisKeyMaker.posInfo(pos_id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const pos = await this.prisma.pos.findUniqueOrThrow({ const pos = await this.prisma.pos.findUniqueOrThrow({
where: { where: {
id: pos_id, id: pos_id,
@@ -71,7 +85,7 @@ export class PosService {
license_activation, license_activation,
} = business_activity } = business_activity
return ResponseMapper.single({ const payload = {
name, name,
complex: { complex: {
id: complexId, id: complexId,
@@ -89,7 +103,9 @@ export class PosService {
license_id: license_activation?.license.id, license_id: license_activation?.license.id,
}, },
partner: license_activation?.license.charge_transaction.partner, partner: license_activation?.license.charge_transaction.partner,
}) }
await this.redisService.setJson(cacheKey, payload, this.infoCacheTtlSeconds)
return ResponseMapper.single(payload)
} }
async getAccessible(account_id: string) { async getAccessible(account_id: string) {
@@ -136,6 +152,12 @@ export class PosService {
} }
async getMe(account_id: string, pos_id: string) { async getMe(account_id: string, pos_id: string) {
const cacheKey = RedisKeyMaker.posMe(account_id, pos_id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const pos = await this.prisma.consumerAccount.findUniqueOrThrow({ const pos = await this.prisma.consumerAccount.findUniqueOrThrow({
where: { where: {
id: account_id, id: account_id,
@@ -177,9 +199,11 @@ export class PosService {
const { consumer, ...rest } = pos const { consumer, ...rest } = pos
return ResponseMapper.single({ const payload = {
...rest, ...rest,
consumer: consumer_mappersUtil(consumer), consumer: consumer_mappersUtil(consumer),
}) }
await this.redisService.setJson(cacheKey, payload, this.meCacheTtlSeconds)
return ResponseMapper.single(payload)
} }
} }
@@ -39,6 +39,11 @@ export class SalesInvoicesController {
return this.salesInvoicesService.send(id, posInfo) return this.salesInvoicesService.send(id, posInfo)
} }
@Post(':id/retry')
retry(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
return this.salesInvoicesService.retry(id, posInfo)
}
@Post(':id/revoke') @Post(':id/revoke')
revoke(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) { revoke(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
return this.salesInvoicesService.revoke(id, posInfo) return this.salesInvoicesService.revoke(id, posInfo)
@@ -1,4 +1,6 @@
import { SharedSaleInvoiceCreateService } from '@/common/services/saleInvoices/sale-invoice-create.service' import { SharedSaleInvoiceCreateService } from '@/common/services/saleInvoices/sale-invoice-create.service'
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
import { SharedSaleInvoiceAccessService } from '@/common/services/saleInvoices/sale-invoice-access.service'
import { SaleInvoiceTspModule } from '@/modules/tspProviders/sales-invoice-tsp.module' import { SaleInvoiceTspModule } from '@/modules/tspProviders/sales-invoice-tsp.module'
import { Module } from '@nestjs/common' import { Module } from '@nestjs/common'
import { SalesInvoicesController } from './sales-invoices.controller' import { SalesInvoicesController } from './sales-invoices.controller'
@@ -7,6 +9,11 @@ import { SalesInvoicesService } from './sales-invoices.service'
@Module({ @Module({
imports: [SaleInvoiceTspModule], imports: [SaleInvoiceTspModule],
controllers: [SalesInvoicesController], controllers: [SalesInvoicesController],
providers: [SalesInvoicesService, SharedSaleInvoiceCreateService], providers: [
SalesInvoicesService,
SharedSaleInvoiceCreateService,
SharedSaleInvoiceActionsService,
SharedSaleInvoiceAccessService,
],
}) })
export class PosSalesInvoicesModule {} export class PosSalesInvoicesModule {}
@@ -1,15 +1,13 @@
import { IPosPayload } from '@/common/models/posPayload.model' import { IPosPayload } from '@/common/models/posPayload.model'
import { QUERY_CONSTANTS } from '@/common/queryConstants'
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
import { SharedSaleInvoiceCreateService } from '@/common/services/saleInvoices/sale-invoice-create.service' import { SharedSaleInvoiceCreateService } from '@/common/services/saleInvoices/sale-invoice-create.service'
import { translateEnumValue } from '@/common/utils' import { translateEnumValue } from '@/common/utils'
import { PrismaService } from '@/prisma/prisma.service' import { PrismaService } from '@/prisma/prisma.service'
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common' import { Injectable, NotFoundException } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper' import { ResponseMapper } from 'common/response/response-mapper'
import { Prisma } from 'generated/prisma/client' import { Prisma } from 'generated/prisma/client'
import { import { TspProviderRequestType, TspProviderResponseStatus } from 'generated/prisma/enums'
ConsumerRole,
TspProviderRequestType,
TspProviderResponseStatus,
} from 'generated/prisma/enums'
import { SalesInvoiceTspService } from '../../tspProviders/sales-invoice-tsp.service' import { SalesInvoiceTspService } from '../../tspProviders/sales-invoice-tsp.service'
import { CreateSalesInvoiceDto } from './dto/create-sales-invoice.dto' import { CreateSalesInvoiceDto } from './dto/create-sales-invoice.dto'
import { SalesInvoicesFilterDto } from './dto/sales-invoices-filter.dto' import { SalesInvoicesFilterDto } from './dto/sales-invoices-filter.dto'
@@ -20,6 +18,7 @@ export class SalesInvoicesService {
private prisma: PrismaService, private prisma: PrismaService,
private salesInvoiceTaxService: SalesInvoiceTspService, private salesInvoiceTaxService: SalesInvoiceTspService,
private sharedSaleInvoiceCreateService: SharedSaleInvoiceCreateService, private sharedSaleInvoiceCreateService: SharedSaleInvoiceCreateService,
private sharedSaleInvoiceActionsService: SharedSaleInvoiceActionsService,
) {} ) {}
async findAll(posInfo: IPosPayload, query: SalesInvoicesFilterDto = {}) { async findAll(posInfo: IPosPayload, query: SalesInvoicesFilterDto = {}) {
@@ -36,41 +35,7 @@ export class SalesInvoicesService {
skip: (page - 1) * perPage, skip: (page - 1) * perPage,
take: perPage, take: perPage,
select: { select: {
id: true, ...QUERY_CONSTANTS.SALE_INVOICE.summarySelect,
code: true,
invoice_number: true,
invoice_date: true,
created_at: true,
total_amount: true,
customer: {
select: {
type: true,
individual: {
select: {
first_name: true,
last_name: true,
mobile_number: true,
national_id: true,
},
},
legal: {
select: {
name: true,
economic_code: true,
registration_number: true,
},
},
},
},
tsp_attempts: {
orderBy: {
created_at: 'desc',
},
take: 1,
select: {
status: true,
},
},
}, },
}), }),
await tx.salesInvoice.count({ where }), await tx.salesInvoice.count({ where }),
@@ -99,120 +64,7 @@ export class SalesInvoicesService {
}, },
}, },
select: { select: {
id: true, ...QUERY_CONSTANTS.SALE_INVOICE.select,
code: true,
invoice_number: true,
invoice_date: true,
created_at: true,
updated_at: true,
notes: true,
total_amount: true,
unknown_customer: true,
tax_id: true,
customer: {
select: {
id: true,
type: true,
individual: {
select: {
first_name: true,
last_name: true,
mobile_number: true,
national_id: true,
postal_code: true,
economic_code: true,
},
},
legal: {
select: {
name: true,
economic_code: true,
registration_number: true,
postal_code: true,
},
},
},
},
pos: {
select: {
id: true,
name: true,
complex: {
select: {
id: true,
name: true,
business_activity: {
select: {
id: true,
name: true,
},
},
},
},
},
},
consumer_account: {
select: {
id: true,
role: true,
account: {
select: {
username: true,
},
},
},
},
items: {
select: {
id: true,
good_id: true,
service_id: true,
quantity: true,
measure_unit_code: true,
measure_unit_text: true,
sku_code: true,
unit_price: true,
discount: true,
total_amount: true,
notes: true,
payload: true,
good_snapshot: true,
},
},
payments: {
select: {
id: true,
amount: true,
payment_method: true,
paid_at: true,
created_at: true,
terminal_info: {
select: {
terminal_id: true,
stan: true,
rrn: true,
transaction_date_time: true,
customer_card_no: true,
description: true,
},
},
},
},
tsp_attempts: {
orderBy: {
created_at: 'desc',
},
select: {
id: true,
attempt_no: true,
status: true,
message: true,
sent_at: true,
received_at: true,
created_at: true,
},
take: 1,
},
}, },
}) })
@@ -253,7 +105,18 @@ export class SalesInvoicesService {
} }
async send(invoiceId: string, posInfo: IPosPayload) { async send(invoiceId: string, posInfo: IPosPayload) {
const invoice = await this.salesInvoiceTaxService.originalSend( const invoice = await this.sharedSaleInvoiceActionsService.send(
posInfo.consumer_account_id,
posInfo.pos_id,
invoiceId,
)
return ResponseMapper.single(invoice)
}
async retry(invoiceId: string, posInfo: IPosPayload) {
const invoice = await this.sharedSaleInvoiceActionsService.retry(
posInfo.consumer_account_id,
posInfo.pos_id, posInfo.pos_id,
invoiceId, invoiceId,
) )
@@ -262,11 +125,9 @@ export class SalesInvoicesService {
} }
async revoke(invoiceId: string, posInfo: IPosPayload) { async revoke(invoiceId: string, posInfo: IPosPayload) {
await this.checkAccessToInvoice(posInfo.consumer_account_id, posInfo.pos_id)
const { consumer_account_id, pos_id, business_id, complex_id } = posInfo const { consumer_account_id, pos_id, business_id, complex_id } = posInfo
const invoice = await this.salesInvoiceTaxService.revoke( const invoice = await this.sharedSaleInvoiceActionsService.revoke(
consumer_account_id, consumer_account_id,
pos_id, pos_id,
complex_id, complex_id,
@@ -278,8 +139,11 @@ export class SalesInvoicesService {
} }
async inquiry(consumer_account_id: string, pos_id: string, invoiceId: string) { async inquiry(consumer_account_id: string, pos_id: string, invoiceId: string) {
const consumer_id = await this.checkAccessToInvoice(consumer_account_id, pos_id) const invoice = await this.sharedSaleInvoiceActionsService.inquiry(
const invoice = await this.salesInvoiceTaxService.get(invoiceId, pos_id, consumer_id) consumer_account_id,
pos_id,
invoiceId,
)
return ResponseMapper.single(invoice) return ResponseMapper.single(invoice)
} }
@@ -434,33 +298,4 @@ export class SalesInvoicesService {
return where return where
} }
private async checkAccessToInvoice(
consumer_account_id: string,
pos_id: string,
): Promise<string> {
const consumer = await this.prisma.consumerAccount.findUnique({
where: {
id: consumer_account_id,
OR: [
{
pos: {
id: pos_id,
},
},
{
role: ConsumerRole.OWNER,
},
],
},
select: {
consumer_id: true,
},
})
if (!consumer) {
throw new BadRequestException('شما دسترسی لازم برای ارسال فاکتور را ندارید.')
}
return consumer.consumer_id
}
} }
@@ -33,6 +33,52 @@ export class SalesInvoiceTspService {
private sharedSaleInvoiceCreateService: SharedSaleInvoiceCreateService, private sharedSaleInvoiceCreateService: SharedSaleInvoiceCreateService,
) {} ) {}
private mapProviderError(error: any) {
const isProviderFailureObject =
error &&
typeof error === 'object' &&
('provider_request_payload' in error ||
'provider_response_payload' in error ||
'sent_at' in error ||
'received_at' in error)
if (isProviderFailureObject) {
return {
hasError: true,
status: error.status || TspProviderResponseStatus.FAILURE,
message:
error.message?.toString() ||
'خطا در ارتباط با سامانه مالیاتی. لطفا مجددا تلاش کنید.',
provider_request_payload: error.provider_request_payload,
provider_response_payload: error.provider_response_payload,
sent_at: error.sent_at || new Date().toISOString(),
received_at: error.received_at || new Date().toISOString(),
}
}
return {
hasError: true,
status: TspProviderResponseStatus.FAILURE,
message:
error?.message?.toString() ||
'خطا در ارتباط با سامانه مالیاتی. لطفا مجددا تلاش کنید.',
provider_response_payload: {
error: error?.message || 'fetch failed',
cause: error?.cause || null,
},
sent_at: new Date().toISOString(),
received_at: new Date().toISOString(),
}
}
private async runProviderCall(fn: () => Promise<any>) {
try {
return await fn()
} catch (error: any) {
return this.mapProviderError(error)
}
}
async originalSend( async originalSend(
posId: string, posId: string,
invoice_id: string, invoice_id: string,
@@ -40,6 +86,7 @@ export class SalesInvoiceTspService {
const payload = await buildPayload(this.prisma, invoice_id, posId) const payload = await buildPayload(this.prisma, invoice_id, posId)
const attemptNumber = await getOriginalResendAttemptNumber(this.prisma, invoice_id) const attemptNumber = await getOriginalResendAttemptNumber(this.prisma, invoice_id)
console.log('attemptNumber', attemptNumber)
const attempt = await this.prisma.saleInvoiceTspAttempts.create({ const attempt = await this.prisma.saleInvoiceTspAttempts.create({
data: { data: {
@@ -51,7 +98,15 @@ export class SalesInvoiceTspService {
}, },
}) })
const result = await trySend(this.tspSwitchService, payload) const result = await this.runProviderCall(() =>
trySend(this.tspSwitchService, payload),
)
if (result?.hasError) {
result.provider_request_payload =
result.provider_request_payload || JSON.parse(JSON.stringify(payload))
result.sent_at = result.sent_at || new Date().toISOString()
result.received_at = result.received_at || new Date().toISOString()
}
return await onResult(this.prisma, result, attempt.id) return await onResult(this.prisma, result, attempt.id)
} }
@@ -260,7 +315,16 @@ export class SalesInvoiceTspService {
}, },
) )
const result = await trySend(this.tspSwitchService, correctionPayload) const result = await this.runProviderCall(() =>
trySend(this.tspSwitchService, correctionPayload),
)
if (result?.hasError) {
result.provider_request_payload =
result.provider_request_payload ||
JSON.parse(JSON.stringify(correctionPayload))
result.sent_at = result.sent_at || new Date().toISOString()
result.received_at = result.received_at || new Date().toISOString()
}
console.log('sendResult') console.log('sendResult')
console.log(result) console.log(result)
@@ -447,7 +511,15 @@ export class SalesInvoiceTspService {
}, },
) )
const result = await this.tspSwitchService.revoke(revokePayload) const result = await this.runProviderCall(() =>
this.tspSwitchService.revoke(revokePayload),
)
if (result?.hasError) {
result.provider_request_payload =
result.provider_request_payload || JSON.parse(JSON.stringify(revokePayload))
result.sent_at = result.sent_at || new Date().toISOString()
result.received_at = result.received_at || new Date().toISOString()
}
return await onResult(this.prisma, result, attempt.id) return await onResult(this.prisma, result, attempt.id)
} }
@@ -80,8 +80,6 @@ export class NamaProviderSwitchAdapter implements IProviderSwitchAdapter {
): Promise<TspProviderSendItemResultDto> { ): Promise<TspProviderSendItemResultDto> {
const mappedRequest = this.namaProviderUtils.mapToNamaRequestDto(payload) const mappedRequest = this.namaProviderUtils.mapToNamaRequestDto(payload)
try { try {
console.log(mappedRequest)
const response = await this.httpClient.request( const response = await this.httpClient.request(
this.buildSendUrl(), this.buildSendUrl(),
{ {
@@ -120,7 +118,7 @@ export class NamaProviderSwitchAdapter implements IProviderSwitchAdapter {
tax_id: null, tax_id: null,
status: TspProviderResponseStatus.NOT_SEND, status: TspProviderResponseStatus.NOT_SEND,
} }
return failure throw failure
} }
} }
@@ -31,6 +31,9 @@ export async function getOriginalResendAttemptNumber(
}, },
}, },
}, },
orderBy: {
created_at: 'desc',
},
}) })
if (existingAttempt) { if (existingAttempt) {
@@ -464,6 +467,8 @@ export async function onResult(
provider_request_payload: result.provider_request_payload, provider_request_payload: result.provider_request_payload,
provider_response_payload: JSON.parse(JSON.stringify(result)), provider_response_payload: JSON.parse(JSON.stringify(result)),
status: result.status, status: result.status,
sent_at: result.sent_at || new Date().toISOString(),
received_at: result.received_at || new Date().toISOString(),
message: result.message?.toString() || 'وجود مشکل در ارسال به سامانه مالیاتی', message: result.message?.toString() || 'وجود مشکل در ارسال به سامانه مالیاتی',
}, },
select: { select: {
@@ -507,7 +512,27 @@ export async function onResult(
} }
} }
throw new NotFoundException( const updatedAttempt = await prisma.saleInvoiceTspAttempts.update({
where: {
id: attempt_id,
},
data: {
provider_response_payload: {},
status: TspProviderResponseStatus.FAILURE,
message:
'متاسفانه امکان ارسال فاکتور به سیستم مالیاتی در حال حاضر وجود ندارد. لطفا بعدا تلاش کنید.', 'متاسفانه امکان ارسال فاکتور به سیستم مالیاتی در حال حاضر وجود ندارد. لطفا بعدا تلاش کنید.',
) received_at: new Date().toISOString(),
},
select: {
status: true,
invoice: true,
message: true,
},
})
return {
invoice: updatedAttempt.invoice,
status: updatedAttempt.status,
message: updatedAttempt.message,
}
} }
+1 -1
View File
@@ -25,7 +25,7 @@ export function getPrismaOptions(): any {
} else { } else {
options.log = [ options.log = [
{ emit: 'stdout', level: 'query' }, { emit: 'stdout', level: 'query' },
{ emit: 'stdout', level: 'info' }, // { emit: 'stdout', level: 'info' },
{ emit: 'stdout', level: 'warn' }, { emit: 'stdout', level: 'warn' },
{ emit: 'stdout', level: 'error' }, { emit: 'stdout', level: 'error' },
] ]
+22
View File
@@ -0,0 +1,22 @@
import { Global, Module } from '@nestjs/common'
import { AdminGuildCacheInvalidationService } from '@/modules/admin/guilds/cache/admin-guild-cache-invalidation.service'
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
import { PosCacheInvalidationService } from '@/modules/pos/cache/pos-cache-invalidation.service'
import { RedisService } from './redis.service'
@Global()
@Module({
providers: [
RedisService,
AdminGuildCacheInvalidationService,
PartnersCacheInvalidationService,
PosCacheInvalidationService,
],
exports: [
RedisService,
AdminGuildCacheInvalidationService,
PartnersCacheInvalidationService,
PosCacheInvalidationService,
],
})
export class RedisModule {}
+133
View File
@@ -0,0 +1,133 @@
import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common'
import Redis from 'ioredis'
@Injectable()
export class RedisService implements OnModuleDestroy {
private readonly logger = new Logger(RedisService.name)
private readonly client: Redis
constructor() {
const host = process.env.REDIS_HOST || 'redis'
const port = Number(process.env.REDIS_PORT || 6379)
const password = process.env.REDIS_PASSWORD || undefined
const db = Number(process.env.REDIS_DB || 0)
this.client = new Redis({
host,
port,
password,
db,
lazyConnect: true,
maxRetriesPerRequest: 3,
})
this.client.on('error', (error) => {
this.logger.error(`Redis error: ${error.message}`)
})
}
async getClient(): Promise<Redis> {
if (this.client.status !== 'ready') {
await this.client.connect()
}
return this.client
}
async get(key: string): Promise<string | null> {
const client = await this.getClient()
return client.get(key)
}
async getJson<T>(key: string): Promise<T | null> {
const value = await this.get(key)
if (!value) {
return null
}
try {
return JSON.parse(value) as T
} catch {
this.logger.warn(`Invalid JSON for key "${key}"`)
return null
}
}
async set(
key: string,
value: string,
ttlSeconds?: number,
): Promise<'OK' | null> {
const client = await this.getClient()
if (ttlSeconds && ttlSeconds > 0) {
return client.set(key, value, 'EX', ttlSeconds)
}
return client.set(key, value)
}
async setJson(
key: string,
value: unknown,
ttlSeconds?: number,
): Promise<'OK' | null> {
return this.set(key, JSON.stringify(value), ttlSeconds)
}
async delete(key: string): Promise<number> {
const client = await this.getClient()
return client.del(key)
}
async exists(key: string): Promise<boolean> {
const client = await this.getClient()
const result = await client.exists(key)
return result === 1
}
async expire(key: string, ttlSeconds: number): Promise<boolean> {
const client = await this.getClient()
const result = await client.expire(key, ttlSeconds)
return result === 1
}
async deleteByPattern(pattern: string): Promise<number> {
const client = await this.getClient()
let deletedCount = 0
let cursor = '0'
do {
const [nextCursor, keys] = await client.scan(
cursor,
'MATCH',
pattern,
'COUNT',
100,
)
cursor = nextCursor
if (keys.length > 0) {
const pipeline = client.pipeline()
keys.forEach(k => pipeline.del(k))
const results = await pipeline.exec()
if (results) {
deletedCount += results.reduce((sum, [, value]) => {
return sum + (typeof value === 'number' ? value : 0)
}, 0)
}
}
} while (cursor !== '0')
return deletedCount
}
async deleteByPatterns(patterns: string[]): Promise<number> {
const deletedCounts = await Promise.all(
patterns.map(pattern => this.deleteByPattern(pattern)),
)
return deletedCounts.reduce((sum, count) => sum + count, 0)
}
async onModuleDestroy() {
await this.client.quit()
}
}