commit 12765d00c29dd23696745776c4d0c86a78cc1170 Author: Josh John Date: Thu Jul 4 11:23:01 2024 +0530 init push diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..f6c62be --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,24 @@ +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + sourceType: 'module', + }, + plugins: ['@typescript-eslint/eslint-plugin'], + extends: [ + 'plugin:@typescript-eslint/recommended', + 'plugin:prettier/recommended', + ], + root: true, + env: { + node: true, + jest: true, + }, + ignorePatterns: ['.eslintrc.js'], + rules: { + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + }, +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d333b23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,109 @@ +# ---> Node +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..dcb7279 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e119de0 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# movie-bucket-project-api + +Online Movie Show Management and Ticket Booking API \ No newline at end of file diff --git a/config/default.yml b/config/default.yml new file mode 100644 index 0000000..8274d9e --- /dev/null +++ b/config/default.yml @@ -0,0 +1,113 @@ +server: + port: 3500 +db: + type: 'postgres' + port: '5432' + sid: 'artnouveau' + oraclesid: 'tbnkdb' + oracleport: '1521' + +jwt: + expiresIn: 3600 + +otp: + expiresIn: 5 + +crypto: + accessToken: 'accessToken@#123' + refreshToken: 'refreshToken@#123' + commonKey: 'commonKey@#123' + +google: + clientID: '42183132451-b2p8fit0okhec8dq8d15ddgu6msa4mro.apps.googleusercontent.com' + clientSecret: 'EZvk3XK4_C1mhVXHm_izCDX6' + callbackURL : 'https://myfin.api.teorainfotech.com/api/v1/auth/google/callback' + succesRedirectURL : 'https://myfin.teorainfotech.com/#/auth/google' + failRedirectURL: 'https://myfin.teorainfotech.com/login/failure' + +facebook: + appId: 2250938211710092 + appSecret: 4eabf9e73c1871a84645d1fffeb07c39 + callbackURL: 'https://myfin.api.teorainfotech.com/api/v1/auth/facebook/redirect' + +mail: + fromMail: 'tenderartnouveau@gmail.com' + user: 'tenderartnouveau@gmail.com' + pass: 'tvrhahtabrwfjshn' + +cron: + scheduler: false + +body: + from: 'Nexmo' + text: 'Test Message from innovations cochin' + to: '+9181390 12392' + api_key: '6b8c19bc' + api_secret: 'BWbmroBtJfX0HPQ1' + +smsPhoneNumberArgName: + phoneno: 'to' + message: 'text' + +url: + url: "https://www.thrickodithanamscb.in/#" + +bodyWay2SMS: + apikey: "CKDG9HL5KYFLLILRMX3QX1CPKOIP8QF1" + secret: "N373LNKAAJ079JY7" + usetype: "stage" + phone: "8139012392" + message: "Haiii..." + senderid: "WAYSMS" + +smsPhoneNumberArgNameWay2SMS: + phoneno: 'phone' + messsgae: 'message' + +urlWay2SMS: + url: "http://www.way2sms.com/api/v1/sendCampaign" + +sms-headers: + headers: { "content-type": "application/json" } + +phonepe-gateway: + salt : "f53ab68c-456e-4850-9ff6-ebd6139a8959" + merchantId : "M224VO4ETK6Z8" + indexKey : 1 + url : "https://api.phonepe.com/apis/hermes/pg/v1/pay" + redirectUrlT : "https://tender.artnouveau.in/#/dashboard" + redirectUrlE : "https://tender.artnouveau.in/#/tender-upload" + callbackUrl : "https://tenderapi.artnouveau.in/api/v1/phonepe-payment-gateway/payment-status" + statusUrl : "https://api.phonepe.com/apis/hermes/pg/v1/status" + testing : true + + +payment-gateway: + successRedirectUrl: "/tender-view" + failureRedirectUrl: "/tender-view" + successRedirectUrlStudent: "/student/payment-redirection" + failureRedirectUrlStudent: "/student/payment-redirection" + successRedirectUrlStudentInternal: "/transaction/student-fee" + failureRedirectUrlStudentInternal: "/transaction/student-fee" + successRedirectUrlAcceptance: "/student/application" + failureRedirectUrlAcceptance: "/student/application" + successRedirectUrlAcceptancePublic: "/auth/public/admission-form" + failureRedirectUrlAcceptancePublic: "auth/public/admission-form" + furl: "https://tenderapi.simssoftware.in/api/v1/payment-gateway/failure" + surl: "https://tenderapi.simssoftware.in/api/v1/payment-gateway/success" + key : "MY3BX1lo" + salt : "9BISuuPeit" + testing : true + +sms-merabt: + url: "http://reseller.smschub.com/api/sms/format/json" + peId: "1201160336050556744" + # peTemplateId: 1207163341521627472 + peTemplateId: "1207164196662343521" + apiKey: "b6bf2ebf9bb6e74d9538892569f7e9cc" + urlEncd: "Y" + sender: "TRISCB" + +default-bank: + id: "acc1" + \ No newline at end of file diff --git a/config/development.yml b/config/development.yml new file mode 100644 index 0000000..38df595 --- /dev/null +++ b/config/development.yml @@ -0,0 +1,14 @@ +db: + host: '3.110.164.8' + username: 'postgres' + password: 'inv123' + sid: 'artnouveau' + synchronize: false + oraclehost: '59.94.179.105' + oracleusername: 'simsmobapp' + oraclepassword: 'simsmobapp' + oraclesid: 'pacs' + oracleType: 'oracle' + +jwt: + secret: 'topSecret51' \ No newline at end of file diff --git a/config/production.yml b/config/production.yml new file mode 100644 index 0000000..e69de29 diff --git a/nest-cli.json b/nest-cli.json new file mode 100644 index 0000000..56167b3 --- /dev/null +++ b/nest-cli.json @@ -0,0 +1,4 @@ +{ + "collection": "@nestjs/schematics", + "sourceRoot": "src" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f6b0a82 --- /dev/null +++ b/package.json @@ -0,0 +1,99 @@ +{ + "name": "artnouveau-api", + "version": "0.0.1", + "description": "", + "author": "", + "private": true, + "license": "UNLICENSED", + "scripts": { + "prebuild": "rimraf dist", + "build": "nest build", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "start": "nest start", + "start:dev": "nest start --watch", + "start:debug": "nest start --debug --watch", + "start:prod": "node dist/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:e2e": "jest --config ./test/jest-e2e.json" + }, + "dependencies": { + "@nest-modules/mailer": "^1.3.22", + "@nestjs/axios": "^3.0.0", + "@nestjs/common": "^9.4.3", + "@nestjs/core": "^9.4.3", + "@nestjs/jwt": "^10.0.3", + "@nestjs/passport": "^9.0.3", + "@nestjs/platform-express": "^9.4.3", + "@nestjs/schedule": "^3.0.2", + "@nestjs/typeorm": "^9.0.1", + "@types/passport-jwt": "^3.0.8", + "archiver": "^5.3.1", + "bcrypt": "^5.1.0", + "class-transformer": "^0.5.1", + "config": "^3.3.9", + "crypto-js": "^4.1.1", + "i": "^0.3.7", + "js-sha512": "^0.8.0", + "jspdf": "^2.5.1", + "jspdf-autotable": "^3.5.31", + "node-forge": "^1.3.1", + "npm": "^9.8.1", + "otp-generator": "^4.0.1", + "passport": "^0.6.0", + "passport-jwt": "^4.0.1", + "payu": "^0.0.1", + "payumoney_nodejs": "^2.0.4", + "payumoney-node": "^2.0.1", + "pg": "^8.10.0", + "reflect-metadata": "^0.1.13", + "rimraf": "^3.0.2", + "rxjs": "^7.2.0", + "typeorm": "^0.3.16", + "uuid": "^9.0.1" + }, + "devDependencies": { + "@nestjs/cli": "^9.5.0", + "@nestjs/schematics": "^9.2.0", + "@nestjs/testing": "^9.4.3", + "@types/crypto-js": "^4.1.1", + "@types/express": "^4.17.13", + "@types/jest": "28.1.8", + "@types/node": "^16.0.0", + "@types/supertest": "^2.0.11", + "@typescript-eslint/eslint-plugin": "^5.0.0", + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^8.0.1", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^4.0.0", + "jest": "28.1.3", + "prettier": "^2.3.2", + "source-map-support": "^0.5.20", + "supertest": "^6.1.3", + "ts-jest": "28.0.8", + "ts-loader": "^9.2.3", + "ts-node": "^10.0.0", + "tsconfig-paths": "4.1.0", + "typescript": "^4.7.4" + }, + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "src", + "testRegex": ".*\\.spec\\.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "../coverage", + "testEnvironment": "node" + } +} diff --git a/src/app.module.ts b/src/app.module.ts new file mode 100644 index 0000000..8d630eb --- /dev/null +++ b/src/app.module.ts @@ -0,0 +1,84 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { typeOrmConfig } from './config/typeorm.config'; +import { AuthModule } from './auth/auth.module'; +import { FileUploadModule } from './file-upload/file-upload.module'; +import { ScheduleModule } from '@nestjs/schedule'; +import { TenderDetailsModule } from './tables/tender-master/tender-details.module'; +import { FormOfContractModule } from './tables/form-of-contract/form-of-contract.module'; +import { PaymentModeModule } from './tables/payment-mode/payment-mode.module'; +import { TenderTypeModule } from './tables/tender-type/tender-type.module'; +import { basicCategoryModule } from './tables/category/category.module'; +import { TenderCategoryModule } from './tables/tender-category/tender-category.module'; +import { EmdFeeTypeModule } from './tables/emd-fee-type/emd-fee-type.module'; +import { TenderModule } from './transactions/tender/tender.module'; +import { TenderDocModule } from './tables/tender-documents/tender-doc.module'; +import { DocumentTypeModule } from './tables/document-type/document-type.module'; +import { CoversLovModule } from './tables/covers-lov/covers-lov.module'; +import { FileFormatLovModule } from './tables/file-format-lov/file-format-lov.module'; +import { CoversMasterModule } from './tables/covers-master/covers-master.module'; +import { PaymentGatewayModule } from './payment-gateway/payment-gateway.module'; +import { PayuTransactionListModule } from './tables/payu-transaction-list/payu-transaction-list.module'; +import { PaymentStatusModule } from './tables/payment-status/payment-status.module'; +import { PaymentMasterModule } from './tables/payment-master/payment-master.module'; +import { CommonModule } from './tables/common/common.module'; +import { DataSource } from 'typeorm'; +import { ReportAuthenticationModule } from './tables/report-authentication/report-authentication.module'; +import { TenderSubcategoryModule } from './tables/tender-subcategory/tender-subcategory.module'; +import { TenderSubcategoryMasterModule } from './tables/tender-subcategory-master/tender-subcategory-master.module'; +import { ClosedTenderUsersModule } from './tables/closed-tender-users/closed-tender-users.module'; +import { galleryModule } from './tables/gallery/gallery.module'; +import { SubGalleryModule } from './tables/sub-gallery/sub-gallery.module'; +import { ImagesService } from './transactions/images/images.service'; +import { ImagesModule } from './transactions/images/images.module'; +import { galleryRepository } from './tables/gallery/gallery.repository'; +import { subGalleryRepository } from './tables/sub-gallery/sub-gallery.repository'; +import { CategoryModule } from './tables/userCategory-master/category.module'; +import { PhonepeTransactionListModule } from './tables/phonepe-transaction-list/phonepe-transaction-list.module'; +import { RevisedTenderModule } from './tables/revised-tender/revised-tender.module'; +import { UserSubcategoryMasterModule } from './tables/user-subcategory-master/user-subcategory-master.module'; + + + +@Module({ + imports: [ + ScheduleModule.forRoot(), + TypeOrmModule.forRoot(typeOrmConfig), + FileUploadModule, + AuthModule, + TenderDetailsModule, + FormOfContractModule, + PaymentModeModule, + TenderTypeModule, + basicCategoryModule, + TenderCategoryModule, + EmdFeeTypeModule, + TenderModule, + TenderDocModule, + DocumentTypeModule, + CoversLovModule, + FileFormatLovModule, + CoversMasterModule, + PaymentGatewayModule, + PayuTransactionListModule, + PaymentStatusModule, + PaymentMasterModule, + CommonModule, + ReportAuthenticationModule, + TenderSubcategoryModule, + TenderSubcategoryMasterModule, + ClosedTenderUsersModule, + galleryModule, + SubGalleryModule, + ImagesModule, + CategoryModule, + PhonepeTransactionListModule, + RevisedTenderModule, + UserSubcategoryMasterModule + + ], + providers: [ImagesService,galleryRepository,subGalleryRepository], +}) +export class AppModule { + constructor(private dataSource: DataSource) {} + } diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts new file mode 100644 index 0000000..57a0e42 --- /dev/null +++ b/src/auth/auth.controller.ts @@ -0,0 +1,178 @@ +import { Controller, Get, UseGuards, Res, Req, Body, ValidationPipe, Post, HttpCode, Ip, HostParam, HttpStatus, Put, Param, Patch, Delete, Query } from '@nestjs/common'; + +import { TokenDto } from './dto/token.dto'; + +import * as config from 'config'; +import { AuthCreadentialsDto } from './dto/auth-credentials.dto'; +import { AuthService } from './auth.service'; +import { TempSignUpDto } from './dto/temp-sign-up.dto'; +import { AuthGuard } from '@nestjs/passport'; +import { GetUser } from './dto/get-user.decorator'; +import { Pcduser } from './pcduser.entity'; +import { PcduserDto } from './dto/pcd-user.dto'; +import { Cron } from '@nestjs/schedule'; +import { ChangePasswordDto } from './dto/change-password.dto'; +import { UserBankDto } from './dto/user-bank.dto'; +import { FindManyOptions } from 'typeorm'; + +@Controller('auth') +export class AuthController { + constructor( + private authService: AuthService + ) { } + + // @Get('user-data') + // async userData() { + // return this.authService.getAll() + // } + // @Get('users') + // async usersData() { + // return this.authService.getusers() + // } + // @Get('user-data/:id') + // async userDataById( + // @Param('id') id:string + // ) { + // return this.authService.getbyUserId(id) + // } + + @UseGuards(AuthGuard()) + @Put('user-data/:id') + async editUser( + @Param('id') id:string, + @Body() body : PcduserDto, + @GetUser() user:PcduserDto + ){ + return await this.authService.editUser(id,body,user) + } + + // @Delete('user-data/:id') + // async deleteUser( + // @Param('id') id:string, + + // ){ + // return await this.authService.deleteUser(id) + // } + + @Post('/user-info') + async userInfo(@Body() authCredentialDto: AuthCreadentialsDto) { + return this.authService.userInfo(authCredentialDto) + } + + + @Post('/signin') + async signIn(@Body(ValidationPipe) + authCredentialDto: AuthCreadentialsDto, + @Req() req): Promise { + return this.authService.signIn(authCredentialDto, req.ip); + } + + @Get() + async getall() { + return this.authService + } + + @Post('/signup') + async signUp(@Body() pcdUserDto: PcduserDto): Promise { + // request.connection.remoteAddress + console.log("hello"); + + return this.authService.tempSignUp(pcdUserDto); + } + + @Post('/forgot-password') + async forgotPassword( + @Body() body: { pass: string, email: string, otp: string }, + ): Promise { + return await this.authService.forgotPassword(body); + } + + @Post('/otp/:flag') + async sendOtp( + @Body() body: { email: string, custName: string, tenderName?: string, bidOpenDate?: string }, + @Param('flag') flag: string + ): Promise { + console.log("helo=========================="); + + return await this.authService.sendOtp(body, flag); + } + + // @Post('/resend-otp/:flag') + // async resendOtp( + // @Body() body: { code?: string | number, email?: string, mobile: string }, + // @Param('flag') flag: string + // ): Promise { + // return await this.authService.resendOtp(body,flag); + // } + + @Post('/verifyOtp/:flag') + async verifyOtp( + @Body() body: { otp: string, email: string }, + @Param('flag') flag: string + ): Promise { + return await this.authService.verifyOtp(body, flag); + } + + @Get('statusVerify') + async statusVerify( + ){ + return this.authService.statusVerify(); + } + + @Post('reqUser') + async reqUser( + @Body() body: {status :string,userId:any }, + // @GetUser() user: PcduserDto + + ){ + console.log(body.status); + + return await this.authService.reqUser(body) + } +} +@UseGuards(AuthGuard()) +@Controller('admin') +export class AdminAuthController { + constructor( + private authService: AuthService + ) { } + + @Get('user-data') + async userData( + @GetUser() user:PcduserDto + ) { + return this.authService.getAll(user) + } + @Get('users') + async usersData( + @Query() filter: FindManyOptions, + @GetUser() user:PcduserDto + ) { + return await this.authService.getusers(user,filter) + } + @Get('user-data/:id') + async userDataById( + @Param('id') id:string, + @GetUser() user:PcduserDto + ) { + return await this.authService.getbyUserId(id,user) + } + + @Put('user-data/:id') + async editUser( + @Param('id') id:string, + @Body() body : PcduserDto, + @GetUser() user:PcduserDto + ){ + return await this.authService.editUser(id,body,user) + } + + @Delete('user-data/:id') + async deleteUser( + @Param('id') id:string, + @GetUser() user:PcduserDto + ){ + return await this.authService.deleteUser(id,user) + } +} + \ No newline at end of file diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts new file mode 100644 index 0000000..0aae782 --- /dev/null +++ b/src/auth/auth.module.ts @@ -0,0 +1,60 @@ +import { Module } from '@nestjs/common'; +import { AdminAuthController, AuthController } from './auth.controller'; +import { AuthService } from './auth.service'; + +import * as config from 'config'; +import { PassportModule } from '@nestjs/passport'; +import { JwtModule } from '@nestjs/jwt'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { CryptoService } from './crypto.service'; +import { JwtStrategy } from './jwt.stategy'; +import { PcduserRepository } from './pcduser.repository'; +import { PcdotpRepository } from './pcdotp.repository'; +import { EmailService } from 'src/email/email.service'; +import { EmailModule } from 'src/email/email.module'; +import { Pcduser } from './pcduser.entity'; +import { Pcdotp } from './pcdotp.entity'; +import { categoryRepository } from 'src/tables/userCategory-master/category.repository'; +import { TenderMasterRepository } from 'src/tables/tender-master/tender-master.repository'; +import { userSubCategoryMasterRepo } from 'src/tables/user-subcategory-master/user-subcategory-master.repository'; + + +const jwtConfig = config.get('jwt'); + +@Module({ + imports: [ + PassportModule.register({ defaultStrategy: 'jwt' }), + JwtModule.register({ + secret: process.env.JWT_SECRET || jwtConfig.secret, + signOptions: { + expiresIn: jwtConfig.expiresIn, + } + }), + TypeOrmModule.forFeature([ + Pcduser, + Pcdotp, + + ]),EmailModule,AuthModule + ], + controllers: [AuthController,AdminAuthController], + providers: [ + AuthService, + CryptoService, + JwtStrategy, + PcdotpRepository, + PcduserRepository, + categoryRepository, + TenderMasterRepository, + userSubCategoryMasterRepo + + + ], + exports: [ + JwtStrategy, + JwtModule, + PassportModule, + CryptoService + ], +}) +export class AuthModule { } diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts new file mode 100644 index 0000000..2dd26c5 --- /dev/null +++ b/src/auth/auth.service.ts @@ -0,0 +1,1154 @@ +import { BadRequestException, Body, Logger, RequestTimeoutException, UnauthorizedException, } from '@nestjs/common'; +import { JwtService } from '@nestjs/jwt'; +import * as config from 'config'; +import { v4 as uuidv4 } from 'uuid'; +const https = require('https'); +const fs = require('fs'); +import { CryptoService } from './crypto.service'; +import { AuthCreadentialsDto } from './dto/auth-credentials.dto'; +import { TokenDto } from './dto/token.dto'; +import { JwtPayload } from './jwt-payload.interface'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { Connection, createConnection, FindManyOptions, getConnection, getCustomRepository, In, IsNull, Like, Not, QueryRunner } from 'typeorm'; +import { TempSignUpDto } from './dto/temp-sign-up.dto'; +import { PcduserRepository } from './pcduser.repository'; +import { InjectRepository } from '@nestjs/typeorm'; +import * as bcrypt from 'bcrypt'; +import { PcdotpDto } from './dto/pcdotp.dto'; +import { PcdotpRepository } from './pcdotp.repository'; + +const { exec } = require("child_process"); +import { generateOtp } from 'otp-generator'; + +const dbConfig = config.get('db'); +const oracledb = require('oracledb'); +import { Pcduser } from './pcduser.entity'; +import { convertDateString } from 'src/pipe/pcd-date.pipe'; +import { UserBankDto } from './dto/user-bank.dto'; + +import { ChangePasswordDto } from './dto/change-password.dto'; +import { log } from 'console'; +import { version } from 'os'; +import { EmailService } from 'src/email/email.service'; +import { categoryDto } from 'src/dto/category.dto'; +import { categoryRepository } from 'src/tables/userCategory-master/category.repository'; +import { TenderMasterRepository } from 'src/tables/tender-master/tender-master.repository'; +import { throwError } from 'rxjs'; +import { userSubCategoryDto } from 'src/dto/user-subcategory-master.dto'; +import { userSubCategoryMasterRepo } from 'src/tables/user-subcategory-master/user-subcategory-master.repository'; +export enum Provider { + GOOGLE = 'google' +} + +export class AuthService { + private logger = new Logger('AuthService'); // for logging + newUserId: any; + categoryDto: any; + + constructor( + @InjectRepository(PcduserRepository) + private readonly pcduserRepository: PcduserRepository, + private jwtService: JwtService, + private crypto: CryptoService, + private readonly pcdotpRepository: PcdotpRepository, + private mailService: EmailService, + private categoryMasterRepo: categoryRepository, + private tenderMasterRepository: TenderMasterRepository, + private UsersubCategoryRepo : userSubCategoryMasterRepo + + ) { + + } + + async getAll(user1 : PcduserDto) { + + if (user1.secuLevel == 'SuperAdmin') { + return await this.pcduserRepository.find({ + select: ['active', 'email', 'userName', 'secuLevel', 'mobileNumber', 'userId' ,'employee'], + where: { + // secuLevel: Not('SuperAdmin') + employee: true + } + }); + + + } else if (user1.secuLevel == 'Admin') { + let user = await this.pcduserRepository.find({ + select: ['active', 'email', 'userName', 'secuLevel', 'mobileNumber', 'userId' , 'employee' ,'maxAmount'], + where: { + secuLevel: 'User', + employee: false + } + + }); + for (let u of user) { + let category1 = await this.UsersubCategoryRepo.find({ + where: { + userId: parseInt(u.userId) + } + }) + + u.userSubcategoryMaster = category1 + + } + return user + } else { + throw new UnauthorizedException("You have No right to Access this url") + } + + } + + async getusers(user, filter) { + // console.log(filter); + // console.log( filter.where["subCategory"]); + + + + if (user.secuLevel == 'User') { + throw new UnauthorizedException("You have No right to Access this url") + } + + let query = ` + select DISTINCT + p.active as "active" , p.email as "email" , + p.user_name as "userName" , + p.secu_level as "secuLevel" ,p.mobile_number as "mobileNumber" , + p.user_id as "userId", + usm.category as "categoryId" , tc.tender_category + from pcduser p + left join user_subcategory_master usm on usm."userId" = p.user_id + left join tender_category tc on tc.id = usm.category + where p.secu_level = 'User' and p.active = true + and p.employee = false and usm.sub_category In (${filter.where["subCategory"]}) + ` + // console.log('hello',query); + return await this.pcduserRepository.query(query) + + + } + + + async getbyUserId(id, user) { + if (user.secuLevel != 'SuperAdmin' && user.secuLevel != 'Admin') { + throw new UnauthorizedException("You have No right to Access this url") + } + return await this.pcduserRepository.findOne({ + select: ['active', 'email', 'userName', 'secuLevel', 'mobileNumber', 'userId' , 'employee' , 'projectCompletedCert' , 'companyProfile'], + where: { + userId: id + } + }); + + + } + + + + async editUser(id, body, users) { + + let user: PcduserDto = await this.pcduserRepository.findOne({ + + where: { + userId: id + } + }) + + if (users.secuLevel == 'SuperAdmin' || users.secuLevel == 'Admin') { + user.active = body.active; + user.secuLevel = body.secuLevel; + user.employee = body.employee + + await this.pcduserRepository.save(user) + return { msg: 'User Details Edited Successfully' } + } + if (users.secuLevel == 'User') { + user.maxAmount = body.maxAmount + user.companyProfile = body.companyProfile + user.projectCompletedCert = body.projectCompletedCert + await this.pcduserRepository.save(user) + return { msg: 'User Details Edited Successfully' } + } + + + + + + + } + + async deleteUser(id, user) { + if (user.secuLevel != 'SuperAdmin') { + throw new UnauthorizedException("You have No right to Access this url") + } + try { + await this.categoryMasterRepo.delete({ userId: id }) + await this.pcduserRepository.delete({ userId: id }) + return { msg: 'User Deleted Successfully' } + } catch (err) { + throw new BadRequestException('Error in Delete User') + } + + + } + + async userInfo(authCredentialsDto: AuthCreadentialsDto) { + const { username, secuLevel } = authCredentialsDto; + let user = await this.pcduserRepository.findOne({ where: { email: (username.trim()).toLocaleLowerCase() } }); + if (!user) { + throw new BadRequestException('User Details not found') + } + if (user) { + return { username: user.userName, + secuLevel: user.secuLevel, + userId: user.userId, + mobile: user.mobileNumber, + email: user.email, + maxAmount : user.maxAmount, + companyProfile:user.companyProfile, + projectCompletedCert:user.projectCompletedCert + + } + } + } + + async signIn(authCredentialsDto: AuthCreadentialsDto, ip?: string): Promise { + + const user: PcduserDto = await this.validateUserPassword(authCredentialsDto); + + if (!user) { + throw new UnauthorizedException('User not Registered') + } + + if (!user.active && user.status == 'S') { // status : S = Approved + console.log(" User is Deactive. Please contact Administrator "); + throw new UnauthorizedException(" User is Deactive. Please contact Administrator ") + } + if (!user.active && user.status == 'R') { // status : R = register + throw new UnauthorizedException(" Registration is currently in progress; Access will be granted upon admin approval ") + } + + return await this.generateTokens(user, user.userName, ip, authCredentialsDto.module, user['changePassword']); + } + + + async validateUserPassword(authCredentialsDto: AuthCreadentialsDto): Promise { + const { username, password } = authCredentialsDto; + + let user = await this.pcduserRepository.findOne({ where: { email: (username.trim()).toLocaleLowerCase() } }); + console.log("user=============", user); + if (!user) { + throw new UnauthorizedException('User not Registered') + } + + if (user && await user.validatePassword(password, user)) { + return user; + } + else { + throw new BadRequestException("Wrong Password"); + } + } + + async forgotPassword(body: { pass: string, email: string, otp: string }): Promise { + let iuserData: PcduserDto = await this.pcduserRepository.findOne({ where: { email: body.email } }); + console.log("iuserdata", iuserData); + + const filter: FindManyOptions = { where: { "refCode": body.email, "status": "I" }, order: { code: "DESC" } }; + const newOtp = await this.pcdotpRepository.find(filter); + + if (body.otp != newOtp[0].otp) { + throw new UnauthorizedException('Unauthorized Access') + } + console.log("salt1234"); + const salt = await bcrypt.genSalt(); + iuserData.salt = salt; + iuserData.pass = await bcrypt.hash(body.pass, salt); + console.log("salt", iuserData.salt); + console.log("pass", iuserData.pass); + + try { + await this.pcduserRepository.save(iuserData); + } + catch (err) { + throw new BadRequestException("Error in Password Reset"); + } + } + + + async sendMail(email: string, custName: string, tenderName: string, bidOpenDate: string, data: string, flag: string) { + + let content: string; + let subject: string = "Login Credentials"; + if (flag == 'otp') { + content = ` + + + + + + OTP + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

ARTNOUVEAU ARCHITECTS

+
 
+ + + + + + + + + + +
 
+

OTP +

+

+ Please Register immediately after getting OTP ,
+ Your one time password(OTP) for register in tenders is.

+ +

+ + OTP + +

${data}

+

+ + +
 
+
 
+

© www.artnouveau.in

+
 
+
+ + + + `; + subject = 'OTP' + + } + if (flag == 'uDocSub') { + content = ` + + + + + + OTP + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+ +

+ Dear ${custName} ,
+ We hope this email finds you well. We would like to express our sincere gratitude for your participation in the tender process for ${tenderName}. We are pleased to inform you that your tender documents have been successfully submitted.

+ The bid opening for the tender you have participated in is scheduled for ${bidOpenDate}. During this process, all submitted tenders will be carefully reviewed and assessed. We will diligently consider each proposal and evaluate it against the criteria outlined in the tender documentation.
+ Should any additional information or documents be required, we will promptly reach out to you via the contact details provided during the submission process.

+ For any inquiries or clarifications, please contact

+ +
+ +

+ +
+

Name:Subash

+

Email: subash@artnouveau.in

+

Phone: +91 94469 64558

+
+
+ +
+

Name:Boncy

+

Email: boncy@artnouveau.in

+

Phone: +91 85473 42848

+
+
+
+
+ Best regards,
+ Artnouveau Architects

+ + + + +
 
+
 
+

© www.artnouveau.in

+
 
+
+ + + + `; + subject = 'Tender Submission Successful - Thank you for your participation!' + } + + if (flag == 'fpwd') { + content = ` + + + + + OTP + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+

OTP +

+

+ Please Register immediately after getting OTP ,
+ Your one time password(OTP) for Reset Password is.

+ +

+ + OTP +

${data}

+

+ + +
 
+
 
+

© + www.artnouveau.in

+
 
+
+ + + + `; + subject = 'OTP' + } + + if (flag == 'confP') { + content = ` + + + + + + OTP + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+ +

+ Dear ${custName} ,
+ We hope this email finds you well. We are writing to inform you that your payment for the tender documents has been successfully processed and accepted by our bank. You can now proceed to download the tender documents as per your requirement.

+ Once again, we appreciate your prompt payment and cooperation. We look forward to receiving your tender submission.
+ Thank you for your participation.

+ For any inquiries or clarifications, please contact

+ +
+ +

+ +
+

Name:Subash

+

Email: subash@artnouveau.in

+

Phone: +91 94469 64558

+
+
+ +
+

Name:Boncy

+

Email: boncy@artnouveau.in

+

Phone: +91 85473 42848

+
+
+
+
+ Best regards,
+ Artnouveau Architects

+ + +
 
+
 
+

© www.artnouveau.in

+
 
+
+ + + + `; + subject = 'Payment Confirmation - Tender Document Download Available' + } + + await this.mailService.sendMail(email, subject, content, content); + + } + + + + async sendOtp(body: { email: string, custName: string, tenderName?: string, bidOpenDate?: string }, flag: string): Promise { + + if (body.email) { + if (flag == 'F' || flag == 'R' || flag == 'UD' || flag == 'CP') { + const email = body.email.toLowerCase(); + let isUserExist = await this.pcduserRepository.findOne({ where: { email: email } }); + + console.log("isUserExist", isUserExist); + + if (!isUserExist && flag == "F") { + throw new BadRequestException("User not found"); + } + if (flag == 'R' && isUserExist) { + throw new BadRequestException("Already registered with this email Id."); + } else { + let newOtp = await this.generateOtp(body.email, flag); + if (body.email && flag == 'R') { // Register Mail + await this.sendMail(body.email, body.custName, body.tenderName, body.bidOpenDate, newOtp, 'otp'); + } + if (body.email && flag == 'F') { //Forget Password Mail + await this.sendMail(body.email, body.custName, body.tenderName, body.bidOpenDate, newOtp, 'fpwd'); + } + if (body.email && flag == 'UD') { //user Document Submission Successfull Mail + await this.sendMail(body.email, body.custName, body.tenderName, body.bidOpenDate, newOtp, 'uDocSub'); + } + if (body.email && flag == 'CP') { //Confirm Payment Mail + await this.sendMail(body.email, body.custName, body.tenderName, body.bidOpenDate, newOtp, 'confP'); + } + + } + + } err => { + console.log(err, "hello12345"); + + }; + + + } + } + + async tempSignUp(pcdUserDto: PcduserDto): Promise { + const filter: FindManyOptions = { where: { "refCode": pcdUserDto.email, "status": "I" }, order: { code: "DESC" } }; + const newOtp = await this.pcdotpRepository.find(filter); + + const email = pcdUserDto.email.toLowerCase(); + console.log("toLowercase",email); + + + const existingUser = await this.pcduserRepository.findOne({ where: { email: email } }); + if (existingUser) { + throw new BadRequestException('User Already Exists'); + } + if (pcdUserDto.otp != newOtp[0].otp) { + throw new UnauthorizedException('Unauthorized Access'); + } + + //Creating Random User_Id for every user registered + const lastUser: PcduserDto = await this.pcduserRepository.findOne({ + where: {}, + order: { userId: 'DESC' }, + }); + let maxCode = 10000; + if (lastUser && lastUser.userId) { + const lastUserId = parseInt(lastUser.userId); + maxCode = Math.max(maxCode, lastUserId); + } + this.newUserId = String(maxCode + 1).padStart(5, '0'); + ///////////////////////////////////////////////////////////// + console.log("pcdUserDto.category=====", pcdUserDto.subCategory); + + + + + ///////////////////////////////////////////////////////////// + + pcdUserDto.userId = this.newUserId; + const salt = await bcrypt.genSalt(); + pcdUserDto.salt = salt; + pcdUserDto.pass = await bcrypt.hash(pcdUserDto.pass, salt); + pcdUserDto.secuLevel = 'User'; + pcdUserDto.active = false; + pcdUserDto.status = 'R' + pcdUserDto.employee = false + delete pcdUserDto['otp']; + await this.pcduserRepository.save(pcdUserDto); + this.logger.verbose("User created with email:", pcdUserDto.email); + /////////////////////////////////////////////////// + for (let s of pcdUserDto.Category) { + + let categoryDto = new userSubCategoryDto() + categoryDto.userId = parseInt(this.newUserId) + categoryDto.Category = s.Category + categoryDto.subCategory = s.subCategory + console.log("categoryDto-------", categoryDto); + + await this.UsersubCategoryRepo.save(categoryDto) + } + return { data: "Successfully Registered" }; + } + + + async verifyOtp(body: { otp: string, email: string }, flag: string): Promise { + + console.log('body===', body, flag); + + const filter: FindManyOptions = { where: { "refCode": body.email, "status": "I" }, order: { code: "DESC" } }; + + + const newOtp = await this.pcdotpRepository.find(filter); + if (!newOtp) + throw new BadRequestException("OTP Error. Resend OTP"); + let currentDateTime = new Date().valueOf(); + let otpTime = newOtp[0].createdDate.valueOf(); + let diffMs = (currentDateTime - otpTime); + let otpExpiry = 600000; //otp expire in 10 minutes + + let diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000); + + if (diffMins > config.get('otp').expiresIn) + throw new RequestTimeoutException('*OTP Expired'); + + + if (diffMs > otpExpiry) + throw new RequestTimeoutException('*OTP Expired'); + + if (newOtp[0].otp != body.otp) + throw new UnauthorizedException("*Invalid OTP"); + if (newOtp[0].otp == body.otp) { + return { data: 'success' }; + } + + } + // async resendOtp(body: { code?: string | number, email?: string, mobile: string }, flag: string): Promise { + // // const newOtp = await this.generateOtp(body.code.toString(), 'RR'); + + // // await this.smsService.sendSms(body.mobile, ` Your one time password(OTP) for Accurate Application Registration is,${newOtp}`); + // const isUserExist = await this.pcduserRepository.findOne({ where: { mobileNumber: body.mobile } }); + // const newOtp = await this.generateOtp(isUserExist.userId.toString(), flag); + + // if (body.mobile) + // await this.smsService.sendSms(body.mobile, newOtp); + + // } + + + async generateOtp(refCode: string, flag: string): Promise { + + var otpGenerator = require('otp-generator') + + const newOtp = await otpGenerator.generate(6, { digits: true, upperCaseAlphabets: false, specialChars: false, lowerCaseAlphabets: false }); + console.log("===newOtp====", newOtp); + + let usedFor: string = ''; + + + switch (flag) { + case "R": + usedFor = "REGISTRATION"; + break; + case "RR": + usedFor = "REGISTRATION RESEND" + break; + case "F": + usedFor = "FORGOT PASSWORD"; + break; + case "FR": + usedFor = "FORGOT PASSWORD RESEND"; + break; + + } + try { + + let igotp: PcdotpDto = new PcdotpDto(); + igotp.otp = newOtp; + igotp.createdBy = 'SYSTEM'; + igotp.createdDate = new Date(); + igotp.modifiedBy = 'SYSTEM'; + igotp.modifiedDate = new Date(); + igotp.refCode = refCode; + igotp.usedFor = usedFor; + igotp.status = 'I'; + await this.pcdotpRepository.save(igotp); + return newOtp; + } + catch (err) { + console.log("====otperr===", err); + } + + } + + + /* The below method is used for generating the access token and refresh token when login */ + async generateTokens(user: PcduserDto, username: string, ip: string, module: string, changePassword?: string): Promise { + + const sessionId = (Math.floor((Math.random() * 100000000) + 1)).toString(); + const payload: JwtPayload = { userId: user.userId.trim(), userName: user.userName.trim(), emailId: user.email, module: module, sessionId: sessionId }; + const accessToken = await this.jwtService.sign(payload, { expiresIn: config.get('jwt').expiresIn }); + + const refreshToken = uuidv4(); + await this.pcduserRepository.updateRefreshToken(user.userId, refreshToken); + + + this.logger.debug(`generated JWT Token with Payload ${JSON.stringify(payload)}`); + const result: TokenDto = { accessToken: this.crypto.set(config.get('crypto').accessToken, accessToken), refreshToken: this.crypto.set(config.get('crypto').accessToken, refreshToken), emailId: user.email, module: module, changePassword: changePassword }; + + return result; + } + + private async hashPassword(password: string, salt: string): Promise { + return await bcrypt.hash(password, salt); + } + + + async statusVerify() { + + let unverifiedUsers = await this.pcduserRepository.find({ + where: { status: 'R', active: false }, select: ["status", "createdDate", "email", "userName", "userId", "mobileNumber", "maxAmount" ,"companyProfile" , "projectCompletedCert"] + }) + return unverifiedUsers; + } + + + async reqUser(body) { + let user: PcduserDto = await this.pcduserRepository.findOne({ where: { userId: body.userId } }) + await this.verifyMail(body, user) + + if (body.status == "A") { + try { + + let user: PcduserDto = await this.pcduserRepository.findOne({ where: { userId: body.userId } }) + if (user) + user.active = true; + user.status = 'S' + // console.log("user=========",user); + await this.pcduserRepository.save(user) + return { msg: "User Approved Successfully" } + } catch (err) { + console.log(err); + + } + } else if (body.status == "R") { + + try { + await this.UsersubCategoryRepo.delete({userId: body.userId }) + await this.pcduserRepository.delete({ userId: body.userId }) + return { msg: "User Rejected Successfully" } + + } catch (err) { + console.log(err); + + } + } + } + + + async verifyMail(body, user) { + + let content: string + let subject: string + + if (body.status == "A") { + content = ` + + + + Account Approved + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+

Account Approved +

+

+ Dear ${user.userName},
+ Your account request has been approved by the admin. + + You can now log in and access your account on our platform. +
+

+ +
 
+
 
+

© + www.artnouveau.in

+
 
+
+ + + + `; + subject = 'Account Approved'; + } else if (body.status == "R") { + + content = ` + + + + + Account Rejected + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+

Account Rejected +

+

+ Dear ${user.userName},
+ We regret to inform you that your account registration request has been rejected by the admin. +
+

+ +
 
+
 
+

© + www.artnouveau.in

+
 
+
+ + + + `; + subject = 'Account Rejected'; + } + await this.mailService.sendMail(user.email, subject, content, content) + } + +} \ No newline at end of file diff --git a/src/auth/crypto.service.ts b/src/auth/crypto.service.ts new file mode 100644 index 0000000..d17a632 --- /dev/null +++ b/src/auth/crypto.service.ts @@ -0,0 +1,55 @@ +import { Injectable } from '@nestjs/common'; +import * as CryptoJS from 'crypto-js'; + + +@Injectable() +export class CryptoService { + constructor() { } + + //The set method is use for encrypt the value. + set(keys, value) { + var key = CryptoJS.enc.Utf8.parse(keys); + var iv = CryptoJS.enc.Utf8.parse(keys); + var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(value.toString()), key, + { + keySize: 128 / 8, + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }); + + return encrypted.toString(); + } + + //The get method is used for decrypt the value. + get(keys, value) { + var key = CryptoJS.enc.Utf8.parse(keys); + var iv = CryptoJS.enc.Utf8.parse(keys); + var decrypted = CryptoJS.AES.decrypt(value, key, { + keySize: 128 / 8, + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }); + + return decrypted.toString(CryptoJS.enc.Utf8); + } + + //encryption method + encryptAesB64(value) { + let b64 = CryptoJS.AES.encrypt(value.toString(), 'etarucca').toString(); + let e64 = CryptoJS.enc.Base64.parse(b64); + let encryptedCode = e64.toString(CryptoJS.enc.Hex); + return { "data": encryptedCode }; + } + + //decryption method + decryptAesB64(value) { + var reb64 = CryptoJS.enc.Hex.parse(value); + var bytes = reb64.toString(CryptoJS.enc.Base64); + var decrypt = CryptoJS.AES.decrypt(bytes, 'etarucca'); + var dycryptedCode = decrypt.toString(CryptoJS.enc.Utf8); + return dycryptedCode + } + +} \ No newline at end of file diff --git a/src/auth/dto/auth-credentials.dto.ts b/src/auth/dto/auth-credentials.dto.ts new file mode 100644 index 0000000..6bc46ac --- /dev/null +++ b/src/auth/dto/auth-credentials.dto.ts @@ -0,0 +1,21 @@ +import { IsNotEmpty, IsString, MaxLength, maxLength, MinLength } from "class-validator"; + +export class AuthCreadentialsDto { + + + @IsString() + @MinLength(2) + @MaxLength(100) + username: string; + + password: string; + + module?: string; + + custId: string; + + email: string; + + secuLevel: any; + +} \ No newline at end of file diff --git a/src/auth/dto/change-password.dto.ts b/src/auth/dto/change-password.dto.ts new file mode 100644 index 0000000..4b59cd5 --- /dev/null +++ b/src/auth/dto/change-password.dto.ts @@ -0,0 +1,22 @@ +import { IsString, MaxLength, MinLength } from "class-validator"; + +export class ChangePasswordDto{ + + // @MinLength(4) + // @Matches(/((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/, + // { message: 'password is too weak' } + // ) + currentPwd:string; + + // @MinLength(4) + pass: string; + + + tpass?: string; + + deviceId?:string; + + mobNo? : string + + + } diff --git a/src/auth/dto/get-user.decorator.ts b/src/auth/dto/get-user.decorator.ts new file mode 100644 index 0000000..bdeea6f --- /dev/null +++ b/src/auth/dto/get-user.decorator.ts @@ -0,0 +1,10 @@ +import { createParamDecorator, ExecutionContext } from "@nestjs/common"; +import {Pcduser} from "src/auth/pcduser.entity"; + +export const GetUser = createParamDecorator( + (data: unknown, ctx: ExecutionContext):Pcduser => { + const request = ctx.switchToHttp().getRequest(); + + return request.user; + }, + ); \ No newline at end of file diff --git a/src/auth/dto/google-profile.dto.ts b/src/auth/dto/google-profile.dto.ts new file mode 100644 index 0000000..0cc0703 --- /dev/null +++ b/src/auth/dto/google-profile.dto.ts @@ -0,0 +1,15 @@ +export class GoogleProfileDto{ + displayName: string; + + name: { familyName: string, givenName: string}; + + emails: {value: string, verified: true}[]; + + photos: {value: string}[]; + + provider: string; + + _row: { sub: string, name: string, given_name: string, family_name: string, picture: string, email: string, email_verified: boolean, locale: string}; + + _json: { sub: string, name: string, given_name: string, family_name: string, picture: string, email: string, email_verified: boolean }; +} \ No newline at end of file diff --git a/src/auth/dto/pcd-user.dto.ts b/src/auth/dto/pcd-user.dto.ts new file mode 100644 index 0000000..4663b41 --- /dev/null +++ b/src/auth/dto/pcd-user.dto.ts @@ -0,0 +1,59 @@ +import { userSubCategoryDto } from "src/dto/user-subcategory-master.dto"; + +export class PcduserDto { + + userId: string; + + userName: string; + + groupOrUser: string; + + pass: string | null; + + salt: string | null; + + secuLevel: string | null; + + pwdExpDays: number | null; + + email: string; + + mobileNumber: string; + + userImagePath: string; + + refreshtoken: string; + + memberNo: string; + + custId: string; + + status: string; + + bankId: string; + + tPass: string | null; + + tSalt: string | null; + + deviceId:string; + + otp?:string; + + subCategory?:any + + active: boolean; + + employee:boolean; + + maxAmount : number + + companyProfile:string + + projectCompletedCert:string + + Category? : any + + + +} \ No newline at end of file diff --git a/src/auth/dto/pcdotp.dto.ts b/src/auth/dto/pcdotp.dto.ts new file mode 100644 index 0000000..a2a16fd --- /dev/null +++ b/src/auth/dto/pcdotp.dto.ts @@ -0,0 +1,15 @@ +import { PcdBaseDto } from "src/framework/custom/pcd-dto.custom"; + +export class PcdotpDto extends PcdBaseDto{ + + code: number; + + otp: string; + + refCode: string; + + usedFor: string; + + status: string; + +} \ No newline at end of file diff --git a/src/auth/dto/rtgs.dto.ts b/src/auth/dto/rtgs.dto.ts new file mode 100644 index 0000000..c20097b --- /dev/null +++ b/src/auth/dto/rtgs.dto.ts @@ -0,0 +1,84 @@ +import { IsNotEmpty } from "class-validator"; + +export class RtgsDto { + + rtgsId: string; + + brCode: string; + + dayDt: string; + + code: string; + + @IsNotEmpty() + accNo: string; + + @IsNotEmpty() + name: string; + + @IsNotEmpty() + toAccNo: string; + + @IsNotEmpty() + toParti: string; + + toEmail: null; + + toMobile: null; + + @IsNotEmpty() + toBank: string; + + @IsNotEmpty() + toBranch: string; + + @IsNotEmpty() + ifscCode: string; + + cashAdj: string; + + payMode: string; + + remarks: string; + + uploadStatus: string; + + credit: null; + + @IsNotEmpty() + debit: number; + + slipNo: number; + + clerk: string; + + cashier: string; + + manager: string; + + clerkId: number; + + mgrId: number; + + cashierId: null; + + rejectReason: null; + + entryTime: string; + + appScr: string; + + @IsNotEmpty() + commAmt: number; + + chNo: null; + + chDate: null; + + dayDate: any; + + @IsNotEmpty() + depType: any; + + dayBeginDt: any; +} diff --git a/src/auth/dto/temp-sign-up.dto.ts b/src/auth/dto/temp-sign-up.dto.ts new file mode 100644 index 0000000..7a6b189 --- /dev/null +++ b/src/auth/dto/temp-sign-up.dto.ts @@ -0,0 +1,28 @@ +import { IsString, MinLength, MaxLength, Matches, IsNotEmpty, IsNumber, IsIn } from "class-validator"; + +export class TempSignUpDto { + + // @IsString() + // @MinLength(0) + // @MaxLength(12) + // @IsNotEmpty() + email: string; + + + + @IsString() + @MinLength(2) + @MaxLength(20) + username: string; + + + @IsString() + @MinLength(4) + @MaxLength(20) + password: string; + + tpassword?: string; + + mobile?:string; + +} \ No newline at end of file diff --git a/src/auth/dto/token.dto.ts b/src/auth/dto/token.dto.ts new file mode 100644 index 0000000..fb823b4 --- /dev/null +++ b/src/auth/dto/token.dto.ts @@ -0,0 +1,14 @@ +export class TokenDto { + + accessToken: string; + + refreshToken: string; + + emailId: string; + + module: string; + + changePassword?:string + + secuLevel?:string +} \ No newline at end of file diff --git a/src/auth/dto/user-bank.dto.ts b/src/auth/dto/user-bank.dto.ts new file mode 100644 index 0000000..872c3fa --- /dev/null +++ b/src/auth/dto/user-bank.dto.ts @@ -0,0 +1,16 @@ + +export class UserBankDto { + custId:string; + + custName:string; + + mobile:string; + + mPin:string; + + tPin:string; + + email:string; + + bankId:string; +} diff --git a/src/auth/jwt-payload.interface.ts b/src/auth/jwt-payload.interface.ts new file mode 100644 index 0000000..dc6518e --- /dev/null +++ b/src/auth/jwt-payload.interface.ts @@ -0,0 +1,13 @@ +export interface JwtPayload { + + userId: string; + + emailId: string; + + userName: string; + + sessionId: string; + + module: string; + +} \ No newline at end of file diff --git a/src/auth/jwt.stategy.ts b/src/auth/jwt.stategy.ts new file mode 100644 index 0000000..df99a3b --- /dev/null +++ b/src/auth/jwt.stategy.ts @@ -0,0 +1,46 @@ +import { PassportStrategy } from '@nestjs/passport'; +import { Strategy, ExtractJwt } from 'passport-jwt'; +import { Injectable, UnauthorizedException, Logger, Inject, Scope } from '@nestjs/common'; +import { JwtPayload } from './jwt-payload.interface'; +import * as config from 'config'; +import { DataSource, getConnection } from 'typeorm'; +import { PcduserRepository } from './pcduser.repository'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { InjectRepository } from '@nestjs/typeorm'; + +@Injectable() +export class JwtStrategy extends PassportStrategy(Strategy) { + + private logger = new Logger('Jwt Strategy'); // for logging + + constructor( + @InjectRepository(PcduserRepository) + private pcduserRepository: PcduserRepository, + ) { + super({ + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), + ignoreExpiration: true, + secretOrKey: process.env.JWT_SECRET || config.get('jwt').secret, + }) + } + + async validate(payload: JwtPayload) { + const { userId, userName, emailId, module } = payload; + this.logger.log(`Payload ${JSON.stringify(payload)}`); + + let connect = DataSource; + const repo = this.pcduserRepository; + const user:PcduserDto = await repo.findOne({where:{userId:userId}}); + delete user.pass; + delete user.salt; + if (!user) { + this.logger.log(` Unauthorized `); + throw new UnauthorizedException(); + } + + user["payload"] = payload; + + return user; + } + +} \ No newline at end of file diff --git a/src/auth/pcdotp.entity.ts b/src/auth/pcdotp.entity.ts new file mode 100644 index 0000000..8618ee9 --- /dev/null +++ b/src/auth/pcdotp.entity.ts @@ -0,0 +1,42 @@ +import { Entity, PrimaryColumn, Column, PrimaryGeneratedColumn } from "typeorm"; +import { PcdBaseEntity } from "../framework/custom/pcd-entity.custom"; + +@Entity('pcdotp') +export class Pcdotp extends PcdBaseEntity { + + @PrimaryGeneratedColumn({ + name: 'code', + }) + code: number; + + @Column({ + type: 'varchar', + name: 'otp', + length: 6, + nullable: false, + }) + otp: string; + + @Column({ + type: 'varchar', + name: 'ref_code', + nullable: true, + }) + refCode: string; + + @Column({ + type: 'varchar', + name: 'used_for', + length: 500, + nullable: true, + }) + usedFor: string; + + @Column({ + type: 'char', + name: 'status', + length: 1, + nullable: false, + }) + status: string; +} \ No newline at end of file diff --git a/src/auth/pcdotp.repository.ts b/src/auth/pcdotp.repository.ts new file mode 100644 index 0000000..af49ae5 --- /dev/null +++ b/src/auth/pcdotp.repository.ts @@ -0,0 +1,14 @@ +import { DataSource, Repository } from "typeorm"; +import { Injectable, Logger } from "@nestjs/common"; +import { Pcdotp } from "./pcdotp.entity"; +import * as config from 'config'; + +@Injectable() +export class PcdotpRepository extends Repository{ + constructor(private dataSource: DataSource) { + super(Pcdotp, dataSource.createEntityManager()); + } + private logger = new Logger('PcdotpRepository'); // for logging + + +} \ No newline at end of file diff --git a/src/auth/pcduser.entity.ts b/src/auth/pcduser.entity.ts new file mode 100644 index 0000000..5d65465 --- /dev/null +++ b/src/auth/pcduser.entity.ts @@ -0,0 +1,227 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, OneToMany, PrimaryColumn } from "typeorm"; +import * as bcrypt from 'bcrypt'; +import { BadRequestException } from "@nestjs/common"; +import { TenderDoc } from "src/tables/tender-documents/tender-doc.entity"; +import { PaymentMaster } from "src/tables/payment-master/payment-master.entity"; +import { category } from "src/tables/userCategory-master/category.entity"; +import { closedTenderUsers } from "src/tables/closed-tender-users/closed-tender-users.entity"; +import { PaymentStatus } from "src/tables/payment-status/payment-status.entity"; +import { revisedTender } from "src/tables/revised-tender/revised-tender.entity"; +import { userSubcategoryMaster } from "src/tables/user-subcategory-master/user-subcategory-master.entity"; + +@Entity('pcduser') +export class Pcduser extends PcdBaseEntity { + @PrimaryColumn({ + name: "user_id", + primary: true, + type: "varchar", + length: 12, + }) + userId: string; + @Column({ + name: "user_name", + type: "varchar", + length: 100 + }) + userName: string; + + @Column({ + name: "group_or_user", + type: "char", + length: 1, + default: () => "'U'", + }) + groupOrUser: string; + + @Column({ + name: "pass", + type: "varchar", + length: 500 + }) + pass: string | null; + + + @Column({ + name: "salt", + type: "varchar", + nullable: true, + length: 50 + }) + salt: string | null; + + + @Column({ + name: "secu_level", + type: "varchar", + nullable: true, + length: 50 + }) + secuLevel: string | null; + + @Column({ + name: "pwd_exp_days", + type: "int", + nullable: true, + default: () => "(0)" + }) + pwdExpDays: number | null; + + @Column({ + name: 'email', + type: 'varchar', + length: 500, + // unique: true, + nullable: true + }) + email: string; + + @Column({ + name: 'mobile_number', + type: 'varchar', + length: 100, + nullable: true, + unique: false + }) + mobileNumber: string; + + @Column({ + name: 'refresh_token', + type: 'varchar', + nullable: true, + length: 100, + }) + refreshtoken: string; + + @Column({ + name: 'user_image_path', + type: 'varchar', + length: 500, + nullable: true + }) + userImagePath: string; + + @Column({ + name: 'member_no', + type: 'varchar', + length: 20, + nullable: true + }) + memberNo: string; + + @Column({ + type: 'varchar', + name: "cust_id", + nullable: true, + length: 20, + }) + custId: string; + + @Column({ + name: "device_id", + type: "varchar", + nullable: true, + }) + deviceId:string; + + @Column({ + type: 'char', + name: "status", + nullable: true, + length: 1 + }) + status: string; + @Column({ + type: 'varchar', + name: "bank_id", + nullable: true, + unique: true, + length: 20, + }) + bankId: string; + @Column({ + nullable:true, + name: "t_pass", + type: "varchar", + length: 500 + }) + tPass: string | null; + + @Column({ + name: "t_salt", + type: "varchar", + nullable: true, + length: 50 + }) + tSalt: string | null; + + @Column({ + name: "active", + type: "boolean", + + }) + active: boolean; + + @Column({ + name:"employee", + type:"boolean" + }) + employee:boolean + + @Column({ + name:"max_amount", + type:"numeric", + nullable:true + }) + maxAmount:number + + @Column({ + name:"company_profile", + type:"varchar", + nullable:true + }) + companyProfile:string + + @Column({ + name:"project_compl_cert", + type:"varchar", + nullable:true + }) + projectCompletedCert:string + + @OneToMany(() => PaymentMaster, (paymentMaster) => paymentMaster.pcduserD) + paymentMaster : PaymentMaster[] + + + @OneToMany(() => TenderDoc, (tenderDoc) => tenderDoc.userD ) + tenderDoc:TenderDoc[] + async validatePassword(password: string,user ): Promise { + const hash = await bcrypt.hash(password, this.salt); + return hash === this.pass; + } + + + @OneToMany(() => category, (category) => category.userD ) + category:category[] + + @OneToMany(() => closedTenderUsers, (closedTenderUsers) => closedTenderUsers.userD ) + closedTenderUsers:closedTenderUsers[] + + // async validateTransactionPassword(password: string): Promise { + // const hash = await bcrypt.hash(password, this.tSalt); + // return hash === this.tPass; + + // } + + @OneToMany(() => PaymentStatus, (PaymentStatus) => PaymentStatus.userD ) + paymentStatusD:PaymentStatus[] + + @OneToMany(() => revisedTender, (revisedTender) => revisedTender.userD ) + revisedTenderD:revisedTender[] + + @OneToMany(() => userSubcategoryMaster, (userSubcategoryMaster) => userSubcategoryMaster.userD) + userSubcategoryMaster: userSubcategoryMaster[] + + + +} \ No newline at end of file diff --git a/src/auth/pcduser.repository.ts b/src/auth/pcduser.repository.ts new file mode 100644 index 0000000..ffcf790 --- /dev/null +++ b/src/auth/pcduser.repository.ts @@ -0,0 +1,92 @@ +import { BadRequestException, Injectable, Logger } from "@nestjs/common"; +import { DataSource, ILike, Like, Repository } from "typeorm"; +import { TempSignUpDto } from "./dto/temp-sign-up.dto"; +import { Pcduser } from "./pcduser.entity"; +import * as bcrypt from 'bcrypt'; +import { AuthCreadentialsDto } from "./dto/auth-credentials.dto"; +import { PcduserDto } from "src/auth/dto/pcd-user.dto"; + +@Injectable() +export class PcduserRepository extends Repository{ + constructor(private dataSource: DataSource) { + super(Pcduser, dataSource.createEntityManager()); + } + private logger = new Logger('Pcduser Repo'); // for logging + async updateRefreshToken(userId: string, refreshToken: string) { + const user = await this.findOne({where:{ userId: userId }}); + user.refreshtoken = refreshToken; + this.save(user); + } + + async signUp(authCredentials: TempSignUpDto, customerMobileNo, memberNo?, bankId?, secuLevel?): Promise { + + const salt = await bcrypt.genSalt(); + const tsalt = await bcrypt.genSalt(); + const user = new Pcduser(); + // user.userId = authCredentials.userId; + let maxCode: number = 10001; + const maxRow: PcduserDto = await this.findOne({ + where: { userId: Like('1%') }, + order: { + "userId": "DESC" + } + }); + + if (maxRow) { + maxCode = parseInt(maxRow.userId) + 1; + } + if (!customerMobileNo) { + user.status = 'V'; + } + else { + user.status = 'N'; + user.mobileNumber = customerMobileNo; + } + user.userId = maxCode.toString(); + user.userName = authCredentials.username; + + user.email = authCredentials.email; + user.createdBy = "SYSTEM"; + user.modifiedBy = "SYSTEM"; + user.groupOrUser = 'U'; + + user.secuLevel = secuLevel; + user.salt = salt; + user.pass = await this.hashPassword(authCredentials.password, salt); + user.tSalt = tsalt; + user.tPass = await this.hashPassword(authCredentials.tpassword, tsalt); + user.bankId = bankId; + try { + return await user.save(); + } catch (error) { + // if(error.code==23505) not working in orcale + throw new BadRequestException(error.message); + } + } + + + async getEagerColumns(): Promise { + /* + For getting Eager true columns having Many to One relations. + We need to remove the eager columns before insertions or updations or it will not allow to save data (But save message will show, but data not updated) + */ + const COLUMNS: string[] = []; + for (let columnProperty of this.metadata.eagerRelations) { + COLUMNS.push(columnProperty.propertyName); + } + return COLUMNS; + } + + + + async encryptPassword(password: string, salt: string): Promise { + return await this.hashPassword(password, salt); + } + + + + private async hashPassword(password: string, salt: string): Promise { + return await bcrypt.hash(password, salt); + } + +} \ No newline at end of file diff --git a/src/config/typeorm.config.ts b/src/config/typeorm.config.ts new file mode 100644 index 0000000..65e392f --- /dev/null +++ b/src/config/typeorm.config.ts @@ -0,0 +1,17 @@ +import { TypeOrmModuleOptions } from "@nestjs/typeorm"; +import * as config from 'config' + +//const dbConfig = config.get('db'); + +export const typeOrmConfig: TypeOrmModuleOptions = { + type:'postgres', + host:'3.110.164.8', + port:5432, + username:'postgres', + password:'inv123', + database:'artnouveau', + entities: [__dirname + '/../**/*.entity.{js,ts}'], + synchronize:true, + logging:false + +}; \ No newline at end of file diff --git a/src/dto/basic-category.dto.ts b/src/dto/basic-category.dto.ts new file mode 100644 index 0000000..b76f59c --- /dev/null +++ b/src/dto/basic-category.dto.ts @@ -0,0 +1,6 @@ +export class basicCategoryDto { + + id:number; + + productCategory:string; +} \ No newline at end of file diff --git a/src/dto/category.dto.ts b/src/dto/category.dto.ts new file mode 100644 index 0000000..34c84dc --- /dev/null +++ b/src/dto/category.dto.ts @@ -0,0 +1,9 @@ +export class categoryDto{ + id?:number + + category : number + + userId? : number + + +} \ No newline at end of file diff --git a/src/dto/closed-tender-users.dto.ts b/src/dto/closed-tender-users.dto.ts new file mode 100644 index 0000000..80d3db6 --- /dev/null +++ b/src/dto/closed-tender-users.dto.ts @@ -0,0 +1,7 @@ +export class closedTenderUsersDto{ + + tenderId : number + + userId : number + +} \ No newline at end of file diff --git a/src/dto/common.dto.ts b/src/dto/common.dto.ts new file mode 100644 index 0000000..31a34f4 --- /dev/null +++ b/src/dto/common.dto.ts @@ -0,0 +1,3 @@ +export class CommonDto{ + marquee : string +} \ No newline at end of file diff --git a/src/dto/cover-master.dto.ts b/src/dto/cover-master.dto.ts new file mode 100644 index 0000000..e0b2110 --- /dev/null +++ b/src/dto/cover-master.dto.ts @@ -0,0 +1,10 @@ +export class CoverMasterDto{ + + tenderId:number; + + coverType:string; + + Description:string; + + fileFormat:string +} \ No newline at end of file diff --git a/src/dto/cover-type.dto.ts b/src/dto/cover-type.dto.ts new file mode 100644 index 0000000..97b5cf1 --- /dev/null +++ b/src/dto/cover-type.dto.ts @@ -0,0 +1,6 @@ +export class coverTypeDto{ + + id:number + + coverType:string +} \ No newline at end of file diff --git a/src/dto/document-type.dto.ts b/src/dto/document-type.dto.ts new file mode 100644 index 0000000..7ae5fad --- /dev/null +++ b/src/dto/document-type.dto.ts @@ -0,0 +1,7 @@ +export class DocumentTypeDto{ + id:number; + + documentType:string; + + docCategory:string +} \ No newline at end of file diff --git a/src/dto/emd-fee-type.dto.ts b/src/dto/emd-fee-type.dto.ts new file mode 100644 index 0000000..7e20921 --- /dev/null +++ b/src/dto/emd-fee-type.dto.ts @@ -0,0 +1,6 @@ +export class EmdFeeTypeDto { + id:number; + + emdFeeType:string; + +} \ No newline at end of file diff --git a/src/dto/file-format-lov.dto.ts b/src/dto/file-format-lov.dto.ts new file mode 100644 index 0000000..7cc8ea4 --- /dev/null +++ b/src/dto/file-format-lov.dto.ts @@ -0,0 +1,5 @@ +export class FileFormatLovDto{ + id:number; + + fileFormat:string; +} \ No newline at end of file diff --git a/src/dto/form-of-contract.dto.ts b/src/dto/form-of-contract.dto.ts new file mode 100644 index 0000000..b1fdeee --- /dev/null +++ b/src/dto/form-of-contract.dto.ts @@ -0,0 +1,4 @@ +export class FormOfContractDto { + id: number; + formOfContract: string; +} \ No newline at end of file diff --git a/src/dto/gallery.dto.ts b/src/dto/gallery.dto.ts new file mode 100644 index 0000000..28a0d4d --- /dev/null +++ b/src/dto/gallery.dto.ts @@ -0,0 +1,15 @@ +export class galleryDto{ + + id?:number + + category : string + + imageUrl : string + + title: string + + description:string + + projectType:string + +} \ No newline at end of file diff --git a/src/dto/mail-config.dto.ts b/src/dto/mail-config.dto.ts new file mode 100644 index 0000000..7dd4549 --- /dev/null +++ b/src/dto/mail-config.dto.ts @@ -0,0 +1,14 @@ +export class MailConfigDto { + + smtpUserName: string; + + smtpId: number; + + smtpPassword: string; + + smtpHost: string; + + encryptionType: string; + + smtpPort: string; +} diff --git a/src/dto/menu.dto.ts b/src/dto/menu.dto.ts new file mode 100644 index 0000000..d94d678 --- /dev/null +++ b/src/dto/menu.dto.ts @@ -0,0 +1,16 @@ +export class MenuDto { + + menuId: number; + + menuName: string; + + moduleId: number; + + menuIcon: string; + + menuOrder: number; + + routerLink: string; + + menuParentId: number; +} diff --git a/src/dto/payment-master.dto.ts b/src/dto/payment-master.dto.ts new file mode 100644 index 0000000..bf5a6e2 --- /dev/null +++ b/src/dto/payment-master.dto.ts @@ -0,0 +1,24 @@ +export class PaymentMasterDto { + + userId:string + + tenderId:number + + transId:number + + status?:string + + finalBidAmt?:number + + notificationViewed?:string + + message?:string + + emdFeeStatus?:string + + emdFeetxnId?:number + + emdFeeType:string + + +} \ No newline at end of file diff --git a/src/dto/payment-mode.dto.ts b/src/dto/payment-mode.dto.ts new file mode 100644 index 0000000..26b4ec5 --- /dev/null +++ b/src/dto/payment-mode.dto.ts @@ -0,0 +1,7 @@ +export class PaymentModeDto{ + + id:number ; + + paymentMode:string; + +} \ No newline at end of file diff --git a/src/dto/payment-status.dto.ts b/src/dto/payment-status.dto.ts new file mode 100644 index 0000000..4d6eddd --- /dev/null +++ b/src/dto/payment-status.dto.ts @@ -0,0 +1,44 @@ +import { PcdBaseDto } from "src/framework/custom/pcd-dto.custom"; + +export class PaymentStatusDto extends PcdBaseDto { + + id: number; + + paymentDate: Date; + + paymentOption: string; + + paymentCardDetails: string; + + status: string; + + type: string + + email: string; + + mobile: string; + + application: number; + + paymentId: number; + + billingAddress1: string; + + billingAddress2: string; + + billingAddress3: string; + + billingAddress4: string; + + amount: number; + + remarks: string; + + txnid: number; + + identifier: string; + + userId : string + + tenderId : number +} \ No newline at end of file diff --git a/src/dto/payment.dto.ts b/src/dto/payment.dto.ts new file mode 100644 index 0000000..5afba7e --- /dev/null +++ b/src/dto/payment.dto.ts @@ -0,0 +1,26 @@ +export class PaymentDto { + firstname: string; + lastname: string; + email: string; + phone: number; + amount: number; + productinfo: string; + txnid: number; + surl: string; + furl: string; + service_provider: string; + + constructor() { + this.furl = 'http://localhost:3100/api/v1/payment-gateway/failure'; + this.surl = 'http://localhost:3100/api/v1/payment-gateway/success'; + + // this.furl = 'https://flexdata.api.teorainfotech.com/API/V1/payment-gateway/failure'; + // this.surl = 'https://flexdata.api.teorainfotech.com/API/V1/payment-gateway/success'; + + this.txnid = this.getRandomInt(); + } + + getRandomInt() { + return Math.floor(100000 + Math.random() * 900000); + } +} diff --git a/src/dto/payu-transaction-list.dto.ts b/src/dto/payu-transaction-list.dto.ts new file mode 100644 index 0000000..c17f9af --- /dev/null +++ b/src/dto/payu-transaction-list.dto.ts @@ -0,0 +1,102 @@ +export class PayuTransactionListDto { + + id: string + + status: string + + key: string + + merchantname: string + + firstname: string + + lastname: string + + addedon: Date + + bank_name: string + + payment_gateway: string + + phone: number | any + + email: string + + transaction_fee: number + + amount: number | any + + discount: number | any + + additional_charges: number | any + + productinfo: string + + error_code: string + + bank_ref_no: number | any + + ibibo_code: string + + mode: string + + ip: string + + card_no: number | any + + cardtype: string + + offer_key: string + + field0: string + + field1: string + + field2: string + + field3: string + + field4: string + + field5: string + + field6: string + + field7: string + + field8: string + + field9: string + + udf1: string + + udf2: string + + udf3: string + + udf4: string + + udf5: string + + address2: string + + city: string + + zipcode: string + + pg_mid: string + + issuing_bank: string + + offer_type: string + + failure_reason: string + + mer_service_fee: string + + mer_service_tax: string + + txnid: string; + + gateway: string; +} \ No newline at end of file diff --git a/src/dto/phonepeTransaction.dto.ts b/src/dto/phonepeTransaction.dto.ts new file mode 100644 index 0000000..b35ab83 --- /dev/null +++ b/src/dto/phonepeTransaction.dto.ts @@ -0,0 +1,13 @@ +export class phonepeTransactionDto { + merchantId: string + merchantTransactionId: number + transactionId: string + amount: number + code: string + message: string + state: string + responseCode: string + paymentType: string + success: boolean + txnDate: Date +} \ No newline at end of file diff --git a/src/dto/purchase.dto.ts b/src/dto/purchase.dto.ts new file mode 100644 index 0000000..5adb0f7 --- /dev/null +++ b/src/dto/purchase.dto.ts @@ -0,0 +1,17 @@ + +export class PurchaseDto { + + amount: number; + + application: string; + + mobile: string; + + email: string; + + type: string; + + menuId?: string; + + +} \ No newline at end of file diff --git a/src/dto/report-authentication.dto.ts b/src/dto/report-authentication.dto.ts new file mode 100644 index 0000000..475b3e9 --- /dev/null +++ b/src/dto/report-authentication.dto.ts @@ -0,0 +1,11 @@ +export class reportAuthenticationDto{ + + id:number; + + adminUsers:string + + key:number[] + + + +} \ No newline at end of file diff --git a/src/dto/revised-tender.dto.ts b/src/dto/revised-tender.dto.ts new file mode 100644 index 0000000..8859219 --- /dev/null +++ b/src/dto/revised-tender.dto.ts @@ -0,0 +1,10 @@ +export class revisedTenderDto{ + + userId : string + + tenderId : number + + revisedDocument : string + + requotedOrder : number +} \ No newline at end of file diff --git a/src/dto/sub-gallery.dto.ts b/src/dto/sub-gallery.dto.ts new file mode 100644 index 0000000..798a5f3 --- /dev/null +++ b/src/dto/sub-gallery.dto.ts @@ -0,0 +1,7 @@ +export class subGalleryDto{ + + gallery_id : number + + imageUrl : string + +} \ No newline at end of file diff --git a/src/dto/tender-category.dto.ts b/src/dto/tender-category.dto.ts new file mode 100644 index 0000000..ca63c1c --- /dev/null +++ b/src/dto/tender-category.dto.ts @@ -0,0 +1,6 @@ +export class TenderCategoryDto{ + + tenderCategory:string; + + active : boolean +} \ No newline at end of file diff --git a/src/dto/tender-document.dto.ts b/src/dto/tender-document.dto.ts new file mode 100644 index 0000000..2f5cd8c --- /dev/null +++ b/src/dto/tender-document.dto.ts @@ -0,0 +1,16 @@ +export class TenderDocumentDto{ + + tenderId:number; + + docName:string; + + description:string; + + docType:string; + + documentSize:number; + + documentCategory:string; + + userId?:string +} \ No newline at end of file diff --git a/src/dto/tender-master.dto.ts b/src/dto/tender-master.dto.ts new file mode 100644 index 0000000..5c3b2a8 --- /dev/null +++ b/src/dto/tender-master.dto.ts @@ -0,0 +1,63 @@ +export class TenderDetailDto { + createdBy: string; + createdDate: string; + modifiedBy: string; + modifiedDate: string; + versionNo: number; + sessionNo: number; + id: number; + orgChain: string; + tenderRefNo: string; + tenderId: string; + allowTechEval: string; + paymentMode: number; + allowWithdraw: string; + noOfCovers: number; + itemwiseTechEval: string; + allowTwoStageBid: string; + tenderFee: number; + feePayableTo: string; + feePayableAt: string; + tenderFeeExemption: number; + emdAmt: number; + emdPayableTo: string; + allowEmdBgOrSt: string; + emdPercentage: number; + emdPayableAt: string; + title: string; + workDesc: string; + ndaPreQualification: string; + remarks: string; + tenderValue: number; + contractType: string; + location: string; + preBidMeetAdd: string; + allowNdaTender: string; + productCategory: number; + bidValidity: number; + pincode: number; + preBidDate: Date; + allowPreferencialBidder: string; + subCategory: string; + periodOfWork: number; + preBidMeetPlace: string; + bidOpeningPlace: string; + publishDate: Date; + saleStartDate: Date; + clarificationStartDate: Date; + bidSubStartDate: Date; + bidOpenDate: Date; + saleEndDate: Date; + clarificationEndDate: Date; + bidSubEndDate: Date; + tenderInvName: string; + tenderInvAddess: string; + tenderType: number; + tenderCategory: number; + formOfContract: number; + emdFeeType: string; + activeYn: string; + sendReport: string; + bidOpenAddress: string + emdFeeApplied: boolean +} \ No newline at end of file diff --git a/src/dto/tender-subcategory-master.dto.ts b/src/dto/tender-subcategory-master.dto.ts new file mode 100644 index 0000000..3e8dd85 --- /dev/null +++ b/src/dto/tender-subcategory-master.dto.ts @@ -0,0 +1,6 @@ +export class tenderSubcategoryMasterDto{ + + tenderId : number + + subCategoryId : number +} \ No newline at end of file diff --git a/src/dto/tender-subcategory.dto.ts b/src/dto/tender-subcategory.dto.ts new file mode 100644 index 0000000..b7dac9f --- /dev/null +++ b/src/dto/tender-subcategory.dto.ts @@ -0,0 +1,7 @@ +export class tenderSubCategoryDto{ + + tenderSubCategory:string; + + active : boolean + +} \ No newline at end of file diff --git a/src/dto/tender-type.dto.ts b/src/dto/tender-type.dto.ts new file mode 100644 index 0000000..1991b41 --- /dev/null +++ b/src/dto/tender-type.dto.ts @@ -0,0 +1,6 @@ +export class TenderTypeDto{ + + id:number; + + tenderType:string; +} \ No newline at end of file diff --git a/src/dto/user-subcategory-master.dto.ts b/src/dto/user-subcategory-master.dto.ts new file mode 100644 index 0000000..ae09295 --- /dev/null +++ b/src/dto/user-subcategory-master.dto.ts @@ -0,0 +1,10 @@ +export class userSubCategoryDto{ + id?:string + + Category:number + + subCategory:number + + userId:number +} + diff --git a/src/email/email.controller.ts b/src/email/email.controller.ts new file mode 100644 index 0000000..6f6a2cb --- /dev/null +++ b/src/email/email.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Get, Post, Body, Param } from '@nestjs/common'; +import { EmailService } from './email.service'; + +@Controller('email') +export class EmailController { + + constructor( + private service: EmailService + ) { } + + @Post('report/:id') + sendReport( + @Param('id') id:string, + @Body() body : {toMail : string[]} + ){ + return this.service.pdfReport(id,body.toMail) + } + + @Post() + sendMail(@Body() body){ + console.log("===here===") + console.log(body); + + return this.service.sendmailManually(body.toMail,body.subject,body.content); + } + + // @Get('create-new') + // sendNewTenderMail(){ + // console.log("===here===") + + // return this.service.tenderPublishEmail(); + // } +} + \ No newline at end of file diff --git a/src/email/email.module.ts b/src/email/email.module.ts new file mode 100644 index 0000000..fe13d64 --- /dev/null +++ b/src/email/email.module.ts @@ -0,0 +1,59 @@ +import { Module } from '@nestjs/common'; +import { EmailController } from './email.controller'; +import { EmailService } from './email.service'; +import { HandlebarsAdapter, MailerModule } from '@nest-modules/mailer'; +import * as config from 'config'; +import { TenderMasterRepository } from 'src/tables/tender-master/tender-master.repository'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { tenderDocRepository } from 'src/tables/tender-documents/tender-doc.repository'; +import { PaymentMasterRepository } from 'src/tables/payment-master/payment-master.repository'; +import { tenderSubCategoryMasterRepository } from 'src/tables/tender-subcategory-master/tender-subcategory-master.repository'; +import { tenderSubCategoryRepository } from 'src/tables/tender-subcategory/tender-subcategory.repository'; +import { PcduserRepository } from 'src/auth/pcduser.repository'; +import { categoryRepository } from 'src/tables/userCategory-master/category.repository'; +import { closedTenderUsersRepository } from 'src/tables/closed-tender-users/closed-tender-users.repository'; +import { TenderMaster } from 'src/tables/tender-master/tender-master.entity'; +import { PaymentMaster } from 'src/tables/payment-master/payment-master.entity'; +import { tenderSubCategoryMaster } from 'src/tables/tender-subcategory-master/tender-subcategory-master.entity'; +import { tenderSubCategory } from 'src/tables/tender-subcategory/tender-subcategory.entity'; +import { Pcduser } from 'src/auth/pcduser.entity'; +import { category } from 'src/tables/userCategory-master/category.entity'; +import { closedTenderUsers } from 'src/tables/closed-tender-users/closed-tender-users.entity'; +import { userSubCategoryMasterRepo } from 'src/tables/user-subcategory-master/user-subcategory-master.repository'; +import { userSubcategoryMaster } from 'src/tables/user-subcategory-master/user-subcategory-master.entity'; + +const emailConfig = config.get('mail'); + +@Module({ + imports: [ + MailerModule.forRootAsync({ + useFactory: () => ({ + // remember to turn-on the Less secure app access in the gmail security + transport: { + host: 'smtp.gmail.com', + port: 465, + secure: true, + auth: { + user: emailConfig.user, + pass: emailConfig.pass + }, + tls: { rejectUnauthorized: false } + }, + + }), + }), + TypeOrmModule.forFeature([TenderMaster,PaymentMaster, + tenderSubCategoryMaster,tenderSubCategory,Pcduser, + category,closedTenderUsers,userSubcategoryMaster]), + ], + controllers: [EmailController], + providers: [EmailService,TenderMasterRepository,PaymentMasterRepository, + tenderSubCategoryMasterRepository,tenderSubCategoryRepository,PcduserRepository,categoryRepository, + closedTenderUsersRepository,userSubCategoryMasterRepo + ], + exports: [ + MailerModule, + EmailService + ] +}) +export class EmailModule { } diff --git a/src/email/email.service.ts b/src/email/email.service.ts new file mode 100644 index 0000000..b20d93d --- /dev/null +++ b/src/email/email.service.ts @@ -0,0 +1,728 @@ +import { Injectable, NotFoundException } from '@nestjs/common'; +import { MailerService } from '@nest-modules/mailer'; +import * as config from 'config'; +import { TenderMasterRepository } from 'src/tables/tender-master/tender-master.repository'; +import { PaymentMasterRepository } from 'src/tables/payment-master/payment-master.repository'; +import { log } from 'console'; +import * as nodemailer from 'nodemailer'; +import { createFolders } from 'src/file-upload/file-upload.controller'; +const mail = config.get('mail'); +import jsPDF from 'jspdf'; +import autoTable from 'jspdf-autotable'; +import { promisify } from 'util'; +const emailConfig = config.get('mail'); +import axios from 'axios'; +import { Between, Not } from 'typeorm'; +import { categoryRepository } from 'src/tables/userCategory-master/category.repository'; +import { tenderSubCategoryMasterRepository } from 'src/tables/tender-subcategory-master/tender-subcategory-master.repository'; +import { tenderSubCategoryRepository } from 'src/tables/tender-subcategory/tender-subcategory.repository'; +import { PcduserRepository } from 'src/auth/pcduser.repository'; +import { Cron } from '@nestjs/schedule'; +import { closedTenderUsersRepository } from 'src/tables/closed-tender-users/closed-tender-users.repository'; +import { userSubCategoryMasterRepo } from 'src/tables/user-subcategory-master/user-subcategory-master.repository'; +@Injectable() +export class EmailService { + reportArray: any; + constructor( + private readonly mailerService: MailerService, + private tenderMasterRepository: TenderMasterRepository, + private paymentMasterRepository: PaymentMasterRepository, + private tenderSubCategoryMasterRepository: tenderSubCategoryMasterRepository, + private tenderSubCategoryRepo: tenderSubCategoryRepository, + private pcdRepo: PcduserRepository, + private userCategoryRepo: categoryRepository, + private closedTenderRepo: closedTenderUsersRepository, + private userSubCategoryMasterRepo : userSubCategoryMasterRepo + ) { } + // documenation : https://www.npmjs.com/package/@nest-modules/mailer + + async pdfReport(id,toMail) { + let query = `SELECT tm.id , tm.title ,tm.send_report,tm.bid_open_date FROM tender_master tm WHERE tm.id = ${id} + ` + let reportNotSend = await this.tenderMasterRepository.query(query) + + let query1 = `SELECT "PaymentMaster"."id" AS "id", + "PaymentMaster"."user_id" AS "userId", + tm.tender_id AS "tenderId", + "PaymentMaster"."trans_id" AS "transId", + "PaymentMaster"."final_bid_amt" AS "finalBidAmt", + "PaymentMaster_pcduserD"."user_name" AS "userName", + "PaymentMaster_pcduserD"."email" AS "email", + "PaymentMaster_pcduserD"."mobile_number" AS "mobileNumber" + FROM "payment-master" "PaymentMaster" + LEFT JOIN "pcduser" "PaymentMaster_pcduserD" ON"PaymentMaster_pcduserD"."user_id"="PaymentMaster"."user_id" + LEFT join "tender_master" "tm" on "tm"."id" = "PaymentMaster"."tender_id" + WHERE "PaymentMaster"."tender_id" = ${id} + and "PaymentMaster"."status"= 'S' + AND "PaymentMaster"."final_bid_amt" IS NOT NULL;` + let report = await this.paymentMasterRepository.query(query1); + + if (report.length == 0) { + throw new NotFoundException('Document entry not found.'); + } + + return this.generateReport(report, id ,toMail) + + } + + + async generateReport(report, id ,toMail) { + + const enq = await report; + + const doc = new jsPDF('landscape'); + let headers = (['id', 'userId', 'tenderId', 'transId', 'finalBidAmt', 'userName', 'email', 'mobileNumber']); + + // Prepare the data in the required format for autoTable + let data = []; + enq.forEach((item) => { + data.push([ + item.id, + item.userId, + item.tenderId, + item.transId, + item.finalBidAmt, + item.userName, + item.email, + item.mobileNumber + ]); + }); + + // Create the table in the PDF document + + + autoTable(doc, { + startY: 1, // Adjust the starting position of the table (Y coordinate) + head: [headers], + body: data, + }); + + // Save the PDF + const filePath: string = './uploads/Report'; + createFolders(filePath); + doc.save(`${filePath}/${id}.pdf`); + console.log(id); + const pdfFileName = `${id}.pdf`; + const filePathReport: string = './uploads/Report/'; + + // Update pdfStatus + let pdfStatus = await this.tenderMasterRepository.findOne({ where: { id: id } }); + pdfStatus.sendReport = 'Y' + this.tenderMasterRepository.save(pdfStatus) + + // Send email with attachment + const transporter = nodemailer.createTransport({ + host: 'smtp.gmail.com', + port: 465, + secure: true, + auth: { + user: emailConfig.user, + pass: emailConfig.pass + }, + tls: { + rejectUnauthorized: false, + }, + }); + + const mailOptions = { + from: emailConfig.user, + to: emailConfig.user, + subject: `Generated PDF Report for ID: ${report[0].tenderId}`, + text: 'Attached PDF report.', + headers: { + bcc: toMail, // BCC recipients + //bcc: ["joshjohn212@gmail.com","atlejs47@gmail.com"] , // BCC recipients + + }, + attachments: [ + { + filename: pdfFileName, + path: `${filePathReport}${pdfFileName}`, + }, + ], + }; + + const sendMail = promisify(transporter.sendMail.bind(transporter)); + + try { + await sendMail(mailOptions); + console.log('Email sent successfully'); + return { data: "Email sent successfully" } + } catch (error) { + console.error('Error sending email:', error); + return { data: "Error sending email:", error } + } + + } + + async sendmailManually(email, subject, content) { + let content1 = ` + + + + + + OTP + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+ +

+ Dear customer ,
+ + ${content}
+ + For any inquiries or clarifications, please contact

+ +
+ +

+ +
+

Name:Subash

+

Email: subash@artnouveau.in

+

Phone: +91 94469 64558

+
+
+ +
+

Name:Boncy

+

Email: boncy@artnouveau.in

+

Phone: +91 85473 42848

+
+
+
+
+ Best regards,
+ Artnouveau Architects

+ + +
 
+
 
+

© www.artnouveau.in

+
 
+
+ + + + `; + let subject1 = subject + + await this.sendMailManually(email, subject1, content1, content1); + } + + async sendMailManually(toMail: string[], subject: string, bodyText: string, htmlText: string) { + + this.mailerService.sendMail({ + to: '', // sender address + subject: subject, // Subject line + text: bodyText, // plaintext body + html: htmlText,// HTML body content + headers: { + bcc: toMail, // BCC recipients + //bcc: ["joshjohn212@gmail.com","atlejs47@gmail.com"] , // BCC recipients + + }, + }) + .then((res) => { + console.log("==== here==res==", res) + + }) + .catch((err) => { + console.log("=====err====", err); + }); + + } + + + + async sendMail(toMail: string, subject: string, bodyText: string, htmlText: string) { + this.mailerService.sendMail({ + to: toMail, // sender address + subject: subject, // Subject line + text: bodyText, // plaintext body + html: htmlText, // HTML body content + + }) + .then((res) => { + console.log("==== here==res==", res) + }) + .catch((err) => { + console.log("=====err====", err); + }); + } + // @Cron('* * * * *', { name: 'send-mail' }) + @Cron('1 0 * * *', { name: 'send-mail'}) + async tenderMail() { + await this.tenderPublishEmail() + await this.closedTenderPublishEmail() + } + + async tenderPublishEmail() { + let date = new Date() + const day = date.getDate().toString().padStart(2, '0'); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Months are zero-based + const year = date.getFullYear(); + + let convertedDate = `${year}-${month}-${day}`; + + const startDate = new Date(convertedDate + 'T00:00:00.000'); + const endDate = new Date(convertedDate + 'T23:59:59.999'); + console.log(convertedDate); + + let tendersToday = await this.tenderMasterRepository.find({ + where: { + publishDate: Between(startDate, endDate), activeYn: 'Y', tenderType: Not(7), + } + }) + + // console.log("uigiuygu",tendersToday.length); + + let tenderSubCategroyArray = [] + let emailArray = [] + + for (let t of tendersToday) { + + let tenderSubCategory = await this.tenderSubCategoryMasterRepository.find({ + where: { + tenderId: t.id + } + }) + for (let s of tenderSubCategory) { + tenderSubCategroyArray.push(s.subCategoryId) + } + // for (let s of tenderSubCategory) { + // let tenderCategory = await this.tenderSubCategoryRepo.find({ where: { id: s.subCategoryId } }) + // for (let t of tenderCategory) { + // tenderCategroyArray.push(t.tenderCategory) + // } + + // } + + + + + + + //User Category --------> + + let users = await this.pcdRepo.find({ + where: { + secuLevel: 'User', active: true + } + }) + + + for (let u of users) { + let userCategory = await this.userSubCategoryMasterRepo.find({ + where: { + userId: parseInt(u.userId) + } + }) + for (let c of userCategory) { + if (tenderSubCategroyArray.includes(c.subCategory)) { + if(!emailArray.includes(u.email)){ + emailArray.push(u.email) + + } + } + } + } + let date = new Date(t.publishDate); + const day = date.getDate().toString().padStart(2, '0'); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Months are zero-based + const year = date.getFullYear(); + let hours = date.getHours(); + const minutes = date.getMinutes().toString().padStart(2, '0'); + + // Determine AM or PM + const ampm = hours >= 12 ? 'PM' : 'AM'; + + // Convert to 12-hour format + hours = hours % 12; + hours = hours ? hours : 12; // If hours is 0, set it to 12 + + const publishDate = `${day}-${month}-${year} ${hours}:${minutes} ${ampm}`; + console.log(publishDate); + + let html = ` + + + + + + OTP + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+ +

+ Dear Customer ,
+ We are excited to inform you that a ${t.title} tender in the ${t.tenderCategoryD['productCategory']} category will been added on our ArtNouveau website.

+ You can view the details on ${publishDate} and submit your bids by visiting the website at tender.artnouveau.in

+ + For any inquiries or clarifications, please contact

+
+ +

+ +
+

Name:Subash

+

Email: subash@artnouveau.in

+

Phone: +91 94469 64558

+
+
+ +
+

Name:Boncy

+

Email: boncy@artnouveau.in

+

Phone: +91 85473 42848

+
+
+
+
+ Best regards,
+ Artnouveau Architects

+ + +
 
+
 
+

© www.artnouveau.in

+
 
+
+ + + + ` + let subject = `New Tender Added in ${t.tenderCategoryD['productCategory']} Category on ArtNouveau Website` + + emailArray = this.removeDuplicates(emailArray); + // console.log(emailArray); + + await this.sendMailManually(emailArray, subject, html, html) + tenderSubCategroyArray = [] + emailArray = [] + } + } + + removeDuplicates(arr: T[]): T[] { + return arr.filter((value, index, self) => self.indexOf(value) === index); + } + + async closedTenderPublishEmail() { + let date = new Date() + const day = date.getDate().toString().padStart(2, '0'); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Months are zero-based + const year = date.getFullYear(); + + let convertedDate = `${year}-${month}-${day}`; + + const startDate = new Date(convertedDate + 'T00:00:00.000'); + const endDate = new Date(convertedDate + 'T23:59:59.999'); + console.log("startDate",startDate,"endDate",endDate); + let tendersToday = await this.tenderMasterRepository.find({ + where: { + publishDate: Between(startDate, endDate), activeYn: 'Y', tenderType: 7, + } + }) + console.log(tendersToday.length); + + let closedTenderUsers = [] + for (let t of tendersToday) { + // console.log(t); + let users = await this.closedTenderRepo.find({ + where: { + tenderId: t.id + } + }) + for (let u of users) { + console.log("11111111", u.userId); + + let user = await this.pcdRepo.findOne({ + where: { + userId: u.userId.toString() + } + }) + closedTenderUsers.push(user.email) + } + let date = new Date(t.publishDate); + const day = date.getDate().toString().padStart(2, '0'); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Months are zero-based + const year = date.getFullYear(); + let hours = date.getHours(); + const minutes = date.getMinutes().toString().padStart(2, '0'); + + // Determine AM or PM + const ampm = hours >= 12 ? 'PM' : 'AM'; + + // Convert to 12-hour format + hours = hours % 12; + hours = hours ? hours : 12; // If hours is 0, set it to 12 + + const publishDate = `${day}-${month}-${year} ${hours}:${minutes} ${ampm}`; + console.log(publishDate); + let html = ` + + + + + + OTP + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+ +

+ Dear Customer ,
+ We are excited to inform you that a ${t.title} closed tender in the ${t.tenderCategoryD['productCategory']} category will been added on our ArtNouveau website.

+ You can view the details on ${publishDate} and submit your bids by visiting the website at tender.artnouveau.in

+ + For any inquiries or clarifications, please contact

+ +
+ +

+ +
+

Name:Subash

+

Email: subash@artnouveau.in

+

Phone: +91 94469 64558

+
+
+ +
+

Name:Boncy

+

Email: boncy@artnouveau.in

+

Phone: +91 85473 42848

+
+
+
+
+ Best regards,
+ Artnouveau Architects

+ + +
 
+
 
+

© www.artnouveau.in

+
 
+
+ + + + ` + let subject = `New Tender Added in ${t.tenderCategoryD['productCategory']} Category on ArtNouveau Website` + // console.log(closedTenderUsers); + await this.sendMailManually(closedTenderUsers, subject, html, html) + closedTenderUsers = [] + + } + + } + +} + diff --git a/src/file-upload/file-upload.controller.ts b/src/file-upload/file-upload.controller.ts new file mode 100644 index 0000000..c438309 --- /dev/null +++ b/src/file-upload/file-upload.controller.ts @@ -0,0 +1,859 @@ +import { BadRequestException, Controller, Delete, Get, NotFoundException, Param, Post, Req, Res, UploadedFile, UseGuards, UseInterceptors } from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { existsSync, mkdirSync } from 'fs'; +import { diskStorage } from 'multer'; +import { v4 as uuidv4 } from 'uuid'; + +import { GetUser } from 'src/auth/dto/get-user.decorator'; +import { FileUploadService } from './file-upload.service'; +import * as fs from 'fs'; +import * as archiver from 'archiver'; +import * as path from 'path'; +import { join, extname } from 'path'; +import { tenderDocRepository } from 'src/tables/tender-documents/tender-doc.repository'; +import { TenderDocumentDto } from 'src/dto/tender-document.dto'; +import { InjectRepository } from '@nestjs/typeorm'; +import { log } from 'console'; + +export function createFolders(filePath: string) { + + + const splitPath = filePath.split('/'); + splitPath.reduce((path, subPath) => { + let currentPath; + if (subPath != '.') { + currentPath = path + '/' + subPath; + + if (!existsSync(currentPath)) { + mkdirSync(currentPath); + } + } + else { + currentPath = subPath; + } + return currentPath + + }, '') +} + + +@Controller('file-upload') +export class FileUploadController { + constructor( + @InjectRepository(tenderDocRepository) + private readonly tenderDocRepository: tenderDocRepository, + + private iservice: FileUploadService, + ) { + } + + + @Post('user-documents/:id/:userId') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + destination: (req, res, cb) => { + const parentFolder: string = './uploads/userDocuments/' + req.params.id; + createFolders(parentFolder); + const childFolder: string = parentFolder + '/' + req.params.userId; + createFolders(childFolder); + return cb(null, childFolder); + }, + filename: (req, file, cb) => { + // Use the original filename instead of generating a random name + return cb(null, `${file.originalname}`); + } + }) + })) + userDoc(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + // To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + + + @UseGuards(AuthGuard()) + @Post('Bank-documents/:id') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + + + const filePath: string = './uploads/BankDocuments/' + req.params.id; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + // Use the original filename instead of generating a random name + return cb(null, `${file.originalname}`); + } + }) + })) + bankDoc(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + @UseGuards(AuthGuard()) + @Post('drawings/:id') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + // console.log(req); + + const filePath: string = './uploads/Drawings/' + req.params.id; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + // Use the original filename instead of generating a random name + return cb(null, `${file.originalname}`); + } + }) + })) + drawings(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + @UseGuards(AuthGuard()) + @Delete('R-drawing/:id/:filename') + async deleteDrawing( + @Param('filename') filename: string, + @Param('id') id: string): Promise { + const filePath = './uploads/Drawings/' + id + '/' + filename; + try { + console.log("deleted=====", id, filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename, id: id }; + const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, tenderId: parseInt(id), documentCategory: 'D' } }); + if (deletedEntry) { + console.log('helloooooo'); + await this.tenderDocRepository.remove(deletedEntry); + console.log('Entry deleted successfully.'); + } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + + + @Delete('R-userDoc/:id/:userId/:filename') + async deleteUserDoc( + @Param('userId') userId: string, + @Param('filename') filename: string, + @Param('id') id: string, + ): Promise { + const filePath = './uploads/userDocuments/' + id + '/' + userId + '/' + filename; + try { + console.log("deleted=====", userId, filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename }; + const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, tenderId: parseInt(id), userId: parseInt(userId), documentCategory: 'USERD' } }); + if (deletedEntry) { + console.log('helloooooo'); + await this.tenderDocRepository.remove(deletedEntry); + console.log('Entry deleted successfully.'); + } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + @UseGuards(AuthGuard()) + @Delete('R-bankDoc/:id/:filename') + async deleteBankDoc( + @Param('filename') filename: string, + @Param('id') id: string): Promise { + const filePath = './uploads/BankDocuments/' + id + '/' + filename; + console.log("filepath===", filePath); + try { + console.log("deleted=====", id, filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename }; + const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, tenderId: parseInt(id), documentCategory: 'WID' } }); + if (deletedEntry) { + console.log('helloooooo'); + await this.tenderDocRepository.remove(deletedEntry); + console.log('Entry deleted successfully.'); + } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + + @UseGuards(AuthGuard()) + @Delete('R-notice/:id/:filename') + async deleteNotice( + @Param('filename') filename: string, + @Param('id') id: string): Promise { + const filePath = './uploads/Notice/' + id + '/' + filename; + console.log("filepath===", filePath); + try { + console.log("deleted=====", id, filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename }; + const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, tenderId: parseInt(id), documentCategory: 'NIT' } }); + if (deletedEntry) { + console.log('helloooooo'); + await this.tenderDocRepository.remove(deletedEntry); + console.log('Entry deleted successfully.'); + } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + + @UseGuards(AuthGuard()) + @Post('notice/:id') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + // console.log(req); + + const filePath: string = './uploads/Notice/' + req.params.id; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + // Use the original filename instead of generating a random name + return cb(null, `${file.originalname}`); + } + }) + })) + + notice(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + + @Get('notice/:id/:imgpath') + getNotice( + @Param('imgpath') image: string, + @Param('id') id: string, + @Res() res, + @Req() req, + ) { + return res.sendFile(image, { root: './uploads/Notice/' + id }, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + + + + + @UseGuards(AuthGuard()) + @Get('Bank-Documents/:id/:imgpath') + getBankDocuments( + @Param('imgpath') image: string, + @Param('id') id: string, + @Res() res, + @Req() req, + + ) { + return res.sendFile(image, { root: './uploads/BankDocuments/' + id }, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + + + @Get('user-Documents/:id/:userId/:imgpath') + getUserDocuments( + @Param('imgpath') image: string, + @Param('userId') userId: string, + @Param('id') id: string, + @Res() res, + @Req() req, + + ) { + return res.sendFile(image, { root: './uploads/userDocuments/' + id + '/' + userId }, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + + + + @Get('Bank-Documents-Arc/:id') + async getBankDocumentsAsZip( + @Param('id') id: string, + @Res() res, + @Req() req, + ) { + const folderPath = path.join('./uploads/BankDocuments', id); + if (!fs.existsSync(folderPath)) { + res.status(404).send({ error: 'File not found' }); + return; + } + + //Uncomment when we want tender id as the zip file name + //const zipFileName = id + '.zip'; + const zipFileName = 'tenderDocuments.zip'; + const zipPath = path.join('./uploads/BankDocuments', zipFileName); + + // Create a new archive + const archive = archiver('zip', { + zlib: { level: 9 } // Set compression level (optional) + }); + + // Create a write stream to the zip file + const output = fs.createWriteStream(zipPath); + + // Pipe the archive to the write stream + archive.pipe(output); + + // Add the entire folder to the archive + archive.directory(folderPath, id); + + // Finalize the archive + await archive.finalize(); + + // Set the appropriate headers for downloading the zip file + res.attachment(zipFileName); + res.setHeader('Content-Type', 'application/zip'); + + // Stream the zip file to the response + const readStream = fs.createReadStream(zipPath); + readStream.pipe(res); + + // Remove the temporary zip file once it's streamed + readStream.on('end', () => { + fs.unlinkSync(zipPath); + }); + + // Handle any errors that occur during the archiving process + archive.on('error', function (err) { + console.log(err); + res.status(500).send({ error: 'Failed to create the zip file' }); + }); + + + } + + + + @Get('Drawings-Arc/:id') + async getDrawingsAsZip( + @Param('id') id: string, + @Res() res, + @Req() req, + ) { + const folderPath = path.join('./uploads/Drawings', id); + console.log(folderPath); + + if (!fs.existsSync(folderPath)) { + console.log( + "helloo" + ); + + res.status(404).send({ error: 'File not found' }); + return; + } + + //Uncomment when we want tender id as the zip file name + //const zipFileName = id + '.zip'; + const zipFileName = 'Drawings.zip'; + const zipPath = path.join('./uploads/Drawings', zipFileName); + + // Create a new archive + const archive = archiver('zip', { + zlib: { level: 9 } // Set compression level (optional) + }); + + // Create a write stream to the zip file + const output = fs.createWriteStream(zipPath); + + // Pipe the archive to the write stream + archive.pipe(output); + + // Add the entire folder to the archive + archive.directory(folderPath, id); + + // Finalize the archive + await archive.finalize(); + + // Set the appropriate headers for downloading the zip file + res.attachment(zipFileName); + res.setHeader('Content-Type', 'application/zip'); + + // Stream the zip file to the response + const readStream = fs.createReadStream(zipPath); + readStream.pipe(res); + + // Remove the temporary zip file once it's streamed + readStream.on('end', () => { + fs.unlinkSync(zipPath); + }); + + // Handle any errors that occur during the archiving process + archive.on('error', function (err) { + console.log(err); + res.status(500).send({ error: 'Failed to create the zip file' }); + }); + + + } + + + @Get('user-doc-arc/:id/:userId') + async getUserDocsAsZip( + @Param('id') id: string, + @Param('userId') userId: string, + @Res() res, + @Req() req, + ) { + const folderPath = path.join('./uploads/userDocuments' + '/' + id + '/' + userId); + + + if (!fs.existsSync(folderPath)) { + res.status(404).send({ error: 'File not found' }); + return; + } + + //Uncomment when we want tender id as the zip file name + //const zipFileName = id + '.zip'; + const zipFileName = 'userDocuments.zip'; + const zipPath = path.join('./uploads/userDocuments', zipFileName); + + // Create a new archive + const archive = archiver('zip', { + zlib: { level: 9 } // Set compression level (optional) + }); + + // Create a write stream to the zip file + const output = fs.createWriteStream(zipPath); + + // Pipe the archive to the write stream + archive.pipe(output); + + // Add the entire folder to the archive + archive.directory(folderPath, id); + + // Finalize the archive + await archive.finalize(); + + // Set the appropriate headers for downloading the zip file + res.attachment(zipFileName); + res.setHeader('Content-Type', 'application/zip'); + + // Stream the zip file to the response + const readStream = fs.createReadStream(zipPath); + readStream.pipe(res); + + // Remove the temporary zip file once it's streamed + readStream.on('end', () => { + fs.unlinkSync(zipPath); + }); + + // Handle any errors that occur during the archiving process + archive.on('error', function (err) { + console.log(err); + res.status(500).send({ error: 'Failed to create the zip file' }); + }); + + + } + + + + // @UseGuards(AuthGuard()) + @Post('picture') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + // console.log(req); + + const filePath: string = './uploads/Pictures'; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + // Useing a random name + const randomName = uuidv4(); + const fileExtension = file.originalname.split('.').pop(); + return cb(null, `${randomName}.${fileExtension}`); + } + }) + })) + + pictures(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + @Get('picture/:imgpath') + getPicture( + @Param('imgpath') image: string, + // @Param('id') id: string, + @Res() res, + @Req() req, + ) { + console.log("filegettt"); + + return res.sendFile(image, { root: './uploads/Pictures' }, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + + // @UseGuards(AuthGuard()) + @Delete('picture/:filename') + async deletePicture( + @Param('filename') filename: string, + // @Param('id') id:string + ): Promise { + const filePath = './uploads/Pictures/' + filename; + console.log("filepath===", filePath); + try { + console.log("deleted=====", filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename }; + const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, documentCategory: 'WEBSITE' } }); + if (deletedEntry) { + await this.tenderDocRepository.remove(deletedEntry); + console.log('Entry deleted successfully.'); + } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + + + + @UseGuards(AuthGuard()) + @Post('dd') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + // console.log(req); + + const filePath: string = './uploads/DD'; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + // Useing a random name + const randomName = uuidv4(); + const fileExtension = file.originalname.split('.').pop(); + return cb(null, `${randomName}.${fileExtension}`); + } + }) + })) + + DD(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + @Get('dd/:imgpath') + getDD( + @Param('imgpath') image: string, + // @Param('id') id: string, + @Res() res, + @Req() req, + ) { + console.log("filegettt"); + + return res.sendFile(image, { root: './uploads/DD' }, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + + @UseGuards(AuthGuard()) + @Delete('dd/:filename') + async deleteDD( + @Param('filename') filename: string, + // @Param('id') id:string + ): Promise { + const filePath = './uploads/DD/' + filename; + console.log("filepath===", filePath); + try { + console.log("deleted=====", filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename }; + const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, documentCategory: 'DD' } }); + if (deletedEntry) { + await this.tenderDocRepository.remove(deletedEntry); + console.log('Entry deleted successfully.'); + } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + // @UseGuards(AuthGuard()) + @Post('company-profile') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + // console.log(req); + + const filePath: string = './uploads/company'; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + // Useing a random name + const randomName = uuidv4(); + const fileExtension = file.originalname.split('.').pop(); + return cb(null, `${randomName}.${fileExtension}`); + } + }) + })) + + companyProfile(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + @Get('company-profile/:imgpath') + getCompanyProfile( + @Param('imgpath') image: string, + // @Param('id') id: string, + @Res() res, + @Req() req, + ) { + console.log("filegettt"); + + return res.sendFile(image, { root: './uploads/company' }, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + + // @UseGuards(AuthGuard()) + @Delete('company-profile/:filename') + async deleteCompanyProfile( + @Param('filename') filename: string, + // @Param('id') id:string + ): Promise { + const filePath = './uploads/company/' + filename; + console.log("filepath===", filePath); + try { + console.log("deleted=====", filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename }; + // const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, documentCategory: 'DD' } }); + // if (deletedEntry) { + // await this.tenderDocRepository.remove(deletedEntry); + // console.log('Entry deleted successfully.'); + // } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + + // @UseGuards(AuthGuard()) + @Post('project-complete_cert') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + // console.log(req); + + const filePath: string = './uploads/company'; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + // Useing a random name + const randomName = uuidv4(); + const fileExtension = file.originalname.split('.').pop(); + return cb(null, `${randomName}.${fileExtension}`); + } + }) + })) + + projectCompletionCert(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + @Get('project-complete_cert/:imgpath') + getprojectCompletionCert( + @Param('imgpath') image: string, + // @Param('id') id: string, + @Res() res, + @Req() req, + ) { + console.log("filegettt"); + + return res.sendFile(image, { root: './uploads/company' }, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + + // @UseGuards(AuthGuard()) + @Delete('project-complete_cert/:filename') + async deleteprojectCompletionCert( + @Param('filename') filename: string, + // @Param('id') id:string + ): Promise { + const filePath = './uploads/company/' + filename; + console.log("filepath===", filePath); + try { + console.log("deleted=====", filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename }; + // const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, documentCategory: 'DD' } }); + // if (deletedEntry) { + // await this.tenderDocRepository.remove(deletedEntry); + // console.log('Entry deleted successfully.'); + // } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + @UseGuards(AuthGuard()) + @Post('quoted-tender') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + // console.log(req); + + const filePath: string = './uploads/QuotedTender'; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + // Useing a random name + const randomName = uuidv4(); + const fileExtension = file.originalname.split('.').pop(); + return cb(null, `${randomName}.${fileExtension}`); + } + }) + })) + QuotedTender(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + @UseGuards(AuthGuard()) + @Get('quoted-tender/:imgpath') + GetQuotedTender( + @Param('imgpath') image: string, + // @Param('id') id: string, + @Res() res, + @Req() req, + ) { + console.log("filegettt"); + + return res.sendFile(image, { root: './uploads/QuotedTender' }, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + + @UseGuards(AuthGuard()) + @Delete('quoted-tender/:filename') + async deleteQuotedTender( + @Param('filename') filename: string, + // @Param('id') id:string + ): Promise { + const filePath = './uploads/QuotedTender/' + filename; + console.log("filepath===", filePath); + try { + console.log("deleted=====", filename); + + await fs.promises.unlink(filePath); + const filter = { docName: filename }; + // const deletedEntry = await this.tenderDocRepository.findOne({ where: { docName: filename, documentCategory: 'DD' } }); + // if (deletedEntry) { + // await this.tenderDocRepository.remove(deletedEntry); + // console.log('Entry deleted successfully.'); + // } + return { message : 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + + + +} \ No newline at end of file diff --git a/src/file-upload/file-upload.module.ts b/src/file-upload/file-upload.module.ts new file mode 100644 index 0000000..5604cd8 --- /dev/null +++ b/src/file-upload/file-upload.module.ts @@ -0,0 +1,24 @@ +import { Module } from '@nestjs/common'; +import { FileUploadController } from './file-upload.controller'; +import { FileUploadService } from './file-upload.service'; +import { MulterModule } from '@nestjs/platform-express'; +import { AuthModule } from 'src/auth/auth.module'; +import { tenderDocRepository } from 'src/tables/tender-documents/tender-doc.repository'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { TenderDoc } from 'src/tables/tender-documents/tender-doc.entity'; + +@Module({ + imports: [ + MulterModule.register({ + dest: './uploads' + }), + TypeOrmModule.forFeature([ + TenderDoc + ]), + AuthModule, + ], + controllers: [FileUploadController], + providers: [FileUploadService,tenderDocRepository + ] +}) +export class FileUploadModule { } diff --git a/src/file-upload/file-upload.service.ts b/src/file-upload/file-upload.service.ts new file mode 100644 index 0000000..8e68f46 --- /dev/null +++ b/src/file-upload/file-upload.service.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class FileUploadService {} diff --git a/src/framework/beans/pcd-form-grid.controller.ts b/src/framework/beans/pcd-form-grid.controller.ts new file mode 100644 index 0000000..3ead31c --- /dev/null +++ b/src/framework/beans/pcd-form-grid.controller.ts @@ -0,0 +1,63 @@ +import { Body, DefaultValuePipe, Delete, Get, Logger, Param, ParseIntPipe, Post, Put, Query, UsePipes, ValidationPipe } from "@nestjs/common"; +import { GetUser } from "src/auth/dto/get-user.decorator"; +import { PcduserDto } from "src/auth/dto/pcd-user.dto"; +import { FindManyOptions } from "typeorm"; +import { PcdFormGridService } from "./pcd-form-grid.service"; +import { AuthGuard } from "@nestjs/passport"; +import { AuthModule } from "src/auth/auth.module"; + +export class PcdFormGridController{ + private logger = new Logger('PcdFormGridController'); // for logging + constructor( + private service: PcdFormGridService + ) { + } + + @Get() + async findAll( + @Query() filter: FindManyOptions, + @GetUser() user: PcduserDto + ): Promise { + return await this.service.findAll(filter, user); + } + + + @Get('/:id') + async getOne( + @Query() filterDto: FindManyOptions, + @Param('id') id: string, + @GetUser() user: PcduserDto, + ): Promise { + + return await this.service.findOne(filterDto, id, user); + } + + @UsePipes(ValidationPipe) + @Post() + async createOne( + @Body() body: T, + @GetUser() user: PcduserDto + ): Promise { + + return await this.service.createOne(body, user); + } + + @Put('/:id') + async updateOne( + @Body(ValidationPipe) body: any, + @Param('id') id: number, + @GetUser() user: PcduserDto + ) { + return await this.service.updateOne(body, id, user); + } + + @Delete('/:id') + async deleteOne( + @Query() filter: FindManyOptions, + @Param('id') id: string, + @GetUser() user: PcduserDto, + ): Promise { + return await this.service.deleteOne(filter, id, user); + } + +} \ No newline at end of file diff --git a/src/framework/beans/pcd-form-grid.service.ts b/src/framework/beans/pcd-form-grid.service.ts new file mode 100644 index 0000000..6118caf --- /dev/null +++ b/src/framework/beans/pcd-form-grid.service.ts @@ -0,0 +1,278 @@ +import { BadRequestException, ConflictException, HttpException, InternalServerErrorException, NotAcceptableException } from '@nestjs/common'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { FindManyOptions, Not, Repository } from 'typeorm'; +import { PcdFormGridInterface } from '../interface/pcd-form-grid.interface'; + + +export class PcdFormGridService implements PcdFormGridInterface { + MAIN_KEY: string = 'id'; + CUSTID: string = ''; + MANDATORY_FEILDS: string[] = []; + DUPLICATE_CHK: string[] = []; + FK_FEILDS: { column: string, relation: Repository }[] = []; + ROW_COUNT: string = ''; + constructor( + // @Inject(TENANT_CONNECTION) conn:Connection, + private repo: Repository + ) { } + async preFindAll(filter: FindManyOptions, user: PcduserDto): Promise { + return true; + } + async findAll(filter: FindManyOptions, user: PcduserDto): Promise { + if (!filter.where) filter.where = {}; + + if (!await this.preFindAll(filter, user)) + throw new BadRequestException(`Unepected Error Occured in findAll`); + // console.log("====1==== filter===", filter); + const result = await this.repo.find(filter); + // console.log("====2==== result===", result); + return await this.postFindAll(filter, user, result); + } + + + + async postFindAll(filter: FindManyOptions, user: PcduserDto, result: T[]): Promise { + return result; + } + + async preFindOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise { + return true; + } + + async findOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise { + if (!filter.where) filter.where = {}; + + filter.where[this.MAIN_KEY] = id; + + if (!await this.preFindOne(filter, id, user)) + throw new BadRequestException(`Unepected Error Occured in findAll`); + + const result = await this.repo.findOne(filter); + + return await this.postFindOne(filter, id, user, result); + } + + async postFindOne(filter: FindManyOptions, id: string | number, user: PcduserDto, result: T): Promise { + return result; + } + async preCreateOne(body: T, user: PcduserDto): Promise { + return true; + } + + + async createOne(body: any, user: PcduserDto): Promise { + for (let colMan of this.MANDATORY_FEILDS) { + if (!body[colMan] || body[colMan].toString().trim() == "") { + throw new BadRequestException(`${colMan} field Cannot be Blank`); + } + } + console.log("==this.DUPLICATE_CHK===", this.DUPLICATE_CHK); + + for (let dupCol of this.DUPLICATE_CHK) { + const dupfilter = { where: {} }; + // if (!dupCol.isSl || (user.coCodeD.secondryLangauge && user.coCodeD.multiLanguageYn == 'Y' && dupCol.isSl)) { + // if (dupCol && isArray(dupCol) && dupCol.column.length > 0) { + // dupCol.forEach(element => { + // console.log("===element====", element); + dupfilter.where[dupCol] = body[dupCol]; + // }) + // } + // else + // dupfilter.where[dupCol.column] = body[dupCol.column]; + // } + // else + // continue; + console.log("===dupRec filter====", dupfilter); + + let dupRec = await this.repo.findOne(dupfilter); + if (dupRec) + throw new BadRequestException(`Duplication not allowed for ${dupCol}`); + } + + console.log("==user.userId==", user); + if (user ) { + body["createdBy"] = user.userId; + body["modifiedBy"] = user.userId; + // body[this.CUSTID] = user.custId; + } + + if (!await this.preCreateOne(body, user)) + throw new BadRequestException(`Unexpected Error Occured in create`); + for (let eagerCol of await this.getEagerColumns()) { + delete body[eagerCol]; + } + try { + await this.repo.save(body); + const filter: FindManyOptions = await this.getFilterWithPrimaryKey(body); + const result = await this.findOne(filter, body[this.MAIN_KEY], user); + + return await this.postCreateOne(body, user, result); + } catch (err) { + console.log("==err==", err); + throw new InternalServerErrorException(err); + } + } + async postCreateOne(body: T, user: PcduserDto, result: T): Promise { + return result; + } + async preUpdateOne(body: T, id: string | number, user: PcduserDto): Promise { + return true; + } + async updateOne(body: any, id: string | number, user: PcduserDto): Promise { + + for (let colMan of this.MANDATORY_FEILDS) { + + if (!body[colMan] || body[colMan].toString().trim() == "") { + throw new BadRequestException(`${colMan} field Cannot be Blank`); + } + } + + for (let dupCol of this.DUPLICATE_CHK) { + const dupfilter = { where: {} }; + dupfilter.where[this.MAIN_KEY] = Not(body[this.MAIN_KEY]); + + // if (!dupCol.isSl || (user.coCodeD.secondryLangauge && user.coCodeD.multiLanguageYn == 'Y' && dupCol.isSl)) { + // if (dupCol.column && isArray(dupCol.column) && dupCol.column.length > 0) { + // dupCol.column.forEach(element => { + // dupfilter.where[element] = body[element]; + // }) + // } + // else + dupfilter.where[dupCol] = body[dupCol]; + // } + // else + // continue; + + let dupRec = await this.repo.findOne(dupfilter); + if (dupRec) + throw new BadRequestException(`Duplication not allowed for ${dupCol}`); + + } + const filter: FindManyOptions = await this.getFilterWithPrimaryKey(body); + const updateRow = await this.getOne(filter, body[this.MAIN_KEY], user); + console.log("====updateRow====", updateRow); + + for (let eagerCol of await this.getEagerColumns()) { + delete body[eagerCol]; + } + // updateRow["coCode"] = user.coCode; + const COLUMNS = await this.getAllColumns(); + const PRIMARY_KEYS = await this.getPrimaryKeys(); + + COLUMNS.forEach((row) => { + if (!PRIMARY_KEYS.includes(row)) + updateRow[row] = body[row]; + }); + console.log("====update row 1 ====", updateRow); + await this.repo.save(updateRow); + // const filter: FindManyOptions = await this.getFilterWithPrimaryKey(body); + const result = await this.findOne(filter, body[this.MAIN_KEY], user); + return await this.postUpdateOne(body, id, user, result); + } + + async postUpdateOne(body: T, id: string | number, user: PcduserDto, result: T): Promise { + return result; + } + + async preDeleteOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise { + for (let fkRel of this.FK_FEILDS) { + const fkFilter = { where: {} }; + fkFilter.where[fkRel.column] = id; + const result = await fkRel.relation.findOne(fkFilter); + if (result) + throw new ConflictException(`Can't delete Record. Detail Records Exists.`); + } + return true; + } + + + async deleteOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise { + if (!filter.where) filter.where = {}; + filter.where[this.MAIN_KEY] = id; + if (this.CUSTID) + filter.where[this.CUSTID] = user.custId; + if (!await this.preDeleteOne(filter, id, user)) + throw new BadRequestException(`Unexpected Error Occured in delete`); + + const delFilter = await this.getDeleteFilter(filter); + + if (!delFilter[this.MAIN_KEY]) + throw new NotAcceptableException(`Please select a data to delete`); + try { + const result = await this.repo.delete(delFilter); + return await this.postDeleteOne(filter, id, user, result); + } catch (err) { + if (err.status) throw new HttpException(err.message, err.status); + + throw new InternalServerErrorException(`${err.message}`); + } + } + + async postDeleteOne(filter: FindManyOptions, id: string | number, user: PcduserDto, result: any): Promise { + return result; + } + + async getDeleteFilter(whereFilter: FindManyOptions): Promise { + const filter: FindManyOptions = {}; + const PRIMARY_KEYS = await this.getPrimaryKeys(); + await PRIMARY_KEYS.forEach((column) => { + filter[column] = whereFilter.where[column]; + }); + return filter; + } + + async getOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise { + if (!filter.where) filter.where = {}; + if (this.CUSTID) + filter.where[this.CUSTID] = user.custId; + filter.where[this.MAIN_KEY] = id; + + const result = await this.repo.findOne(filter); + + return result; + } + async getAllColumns(): Promise { + const COLUMNS: string[] = []; + for (let columnProperty in this.repo.metadata.propertiesMap) { + COLUMNS.push(this.repo.metadata.propertiesMap[columnProperty]); + } + // in the below method it will not take the forignKey columns Like modelD etc.. + // await this.repo.metadata.columns.forEach((row) => { + // COLUMNS.push(row.propertyName); + // }); + return COLUMNS; + } + + async getPrimaryKeys(): Promise { + const PRIMARY_KEYS: string[] = []; + await this.repo.metadata.primaryColumns.forEach((row) => { + PRIMARY_KEYS.push(row.propertyName); + }); + return PRIMARY_KEYS; + } + + async getFilterWithPrimaryKey(body: T): Promise { + const filter: FindManyOptions = { where: {} }; + const PRIMARY_KEYS = await this.getPrimaryKeys(); + await PRIMARY_KEYS.forEach((column) => { + filter.where[column] = body[column]; + }); + return filter; + } + + + async getEagerColumns(): Promise { + /* + For getting Eager true columns having Many to One relations. + We need to remove the eager columns before insertions or updations or it will not allow to save data (But save message will show, but data not updated) + */ + const COLUMNS: string[] = []; + for (let columnProperty of this.repo.metadata.eagerRelations) { + COLUMNS.push(columnProperty.propertyName); + } + return COLUMNS; + } + + + +} \ No newline at end of file diff --git a/src/framework/beans/pcd-transaction.controller.ts b/src/framework/beans/pcd-transaction.controller.ts new file mode 100644 index 0000000..b07ed5d --- /dev/null +++ b/src/framework/beans/pcd-transaction.controller.ts @@ -0,0 +1,42 @@ +import { Logger, Get, Query, Delete, Post, Body, Param, UseGuards } from "@nestjs/common"; +import { AuthGuard } from "@nestjs/passport"; +import { AuthModule } from "src/auth/auth.module"; +import { FindManyOptions } from "typeorm"; +import { PcdTransactionService } from "./pcd-transaction.service"; +import { GetUser } from "src/auth/dto/get-user.decorator"; +import { PcduserDto } from "src/auth/dto/pcd-user.dto"; + +export class PcdTransactionController { + + private logger = new Logger('PcdTransactionController'); // for logging + + constructor( + private service: PcdTransactionService + ) { } + + @Get() + async findList(@Query() filter: FindManyOptions, + @GetUser() user: PcduserDto + ): Promise { + return await this.service.findList(filter, user); + } + + @Get('/:id') + async findOne(@Query() filter: FindManyOptions, @Param('id') id: string,): Promise { + return await this.service.findOne(filter, id); + } + + @UseGuards(AuthGuard()) + @Post() + async createOne(@Body() body: T, + @GetUser() user: PcduserDto): Promise { + return await this.service.createOne(body, user); + } + + + @UseGuards(AuthGuard()) + @Delete('/:id') + async delete(@Query() filter: FindManyOptions, @Param('id') id: string,): Promise { + return await this.service.deleteOne(filter, id,); + } +} \ No newline at end of file diff --git a/src/framework/beans/pcd-transaction.service.ts b/src/framework/beans/pcd-transaction.service.ts new file mode 100644 index 0000000..5239e44 --- /dev/null +++ b/src/framework/beans/pcd-transaction.service.ts @@ -0,0 +1,357 @@ +import { PcdtTransactionInterface } from "../interface/pcd-transaction.interface"; +import { FindManyOptions, Repository, getConnection, QueryRunner, Connection, DataSource, FindOneOptions } from "typeorm"; +import { BadRequestException, NotAcceptableException, UnauthorizedException, InternalServerErrorException, MethodNotAllowedException, HttpException, Inject } from "@nestjs/common"; +import { TransactionDetailDto } from "src/framework/custom/transaction-detail.dto"; +import { PcduserDto } from "src/auth/dto/pcd-user.dto"; +//import { TENANT_CONNECTION } from "src/tenant/tenant.module"; +// import { IintDto } from "../../dto/iint.dto"; +// import { IintvrnoDto } from "../../dto/iintvrno.dto"; +// import { IintService } from "../../tables/iint/iint.service"; + +export class PcdTransactionService implements PcdtTransactionInterface { + + MAIN_KEY: string = "id"; + TXN_TYPE: string = ""; + + DETAIL_DATA_FORMAT: TransactionDetailDto[] = []; + + constructor( + private connection: DataSource, + private repo: Repository + ) { } + + async preFindList(filter: FindManyOptions, user: PcduserDto): Promise { + return true + } + + async findList(filter: FindManyOptions, user: PcduserDto): Promise { + if (!filter.where) filter.where = {}; + if (this.TXN_TYPE) filter.where[this.DETAIL_DATA_FORMAT[0].transactionTypeColumnName] = this.TXN_TYPE; + // if (!filter.where[this.DETAIL_DATA_FORMAT[0].transactionTypeColumnName]) + // return; + + if (!await this.preFindList(filter, user)) + throw new BadRequestException(`Unexpected Error Occured in findList`); + let result: T[] = await this.repo.find(filter); + + return await this.postFindList(filter, result); + } + + async postFindList(filter: FindManyOptions, result: T[]): Promise { + return result; + } + + async preFindOne(filter: FindManyOptions,): Promise { + return true + } + + async findOne(filter: FindOneOptions, id: string | number,): Promise { + if (!filter.where) filter.where = {}; + if (this.TXN_TYPE) filter.where[this.DETAIL_DATA_FORMAT[0].transactionTypeColumnName] = this.TXN_TYPE; + let orgFilter = Object.create(filter); + + filter.where[this.MAIN_KEY] = id; + + if (!await this.preFindOne(filter)) + throw new BadRequestException(`Unepected Error Occured in findOne`); + //branch right check(); + + + let result: T = await this.repo.findOne(filter); + + if (!result) + return result; + + result = await this.getDetailData(result, orgFilter, this.DETAIL_DATA_FORMAT); + + return await this.postFindOne(filter, result); + } + + async postFindOne(filter: FindManyOptions, result: T): Promise { + return result; + } + + async preDeleteOne(filter: FindManyOptions, id: string | number,): Promise { + return true; + } + + async deleteOne(filter: any, id: string | number,): Promise { + if (!filter || !filter.where) filter.where = {}; + if (this.TXN_TYPE) filter.where[this.DETAIL_DATA_FORMAT[0].transactionTypeColumnName] = this.TXN_TYPE; + filter.where[this.MAIN_KEY] = id; + + const delFilter = await this.getDeleteFilter(filter); + if (!delFilter[this.MAIN_KEY]) + throw new NotAcceptableException(`Please select a record`); + if (!await this.preDeleteOne(filter, id,)) + throw new BadRequestException(`Unepected Error Occured in deleteOne`); + const queryRunner = this.connection.createQueryRunner(); + await queryRunner.connect(); + try { + await queryRunner.startTransaction(); + await this.deleteDetailDataTabels(id, this.DETAIL_DATA_FORMAT, queryRunner); + const result = await queryRunner.manager.delete(this.repo.metadata.name, id); + await queryRunner.commitTransaction(); + return await this.postDeleteOne(filter, result); + } catch (err) { + if (queryRunner.isTransactionActive) + await queryRunner.rollbackTransaction(); + throw new InternalServerErrorException(`${err.message}`); + } finally { + await queryRunner.release(); + } + // const result = await this.repo.delete(delFilter); + + } + + async postDeleteOne(filter: FindManyOptions, result: any): Promise { + return result; + } + + async preCreateOne(body: T,user): Promise { + return true; + } + + async beforeCreateOne(body: T, queryRunner: QueryRunner): Promise { + return true; + } + + async createOne(body: T, user: PcduserDto): Promise { + //console.log('--- incoming = ', body); + + if (this.TXN_TYPE) body[this.DETAIL_DATA_FORMAT[0].transactionTypeColumnName] = this.TXN_TYPE; + if (!await this.preCreateOne(body,user)) + throw new BadRequestException(`Unexpected Error Occured in CreateOne`); + for (let eagerCol of await this.getEagerColumns()) { + delete body[eagerCol]; + } + const queryRunner = this.connection.createQueryRunner(); + await queryRunner.connect(); + try { + await queryRunner.startTransaction(); + + if (this.TXN_TYPE) body[this.DETAIL_DATA_FORMAT[0].transactionTypeColumnName] = this.TXN_TYPE; + // await this.checkAndSetVrNo(body, user, queryRunner); + + // for deleting deleted details from the angular + for (let row of this.DETAIL_DATA_FORMAT) { + body[row.detailName] = await this.deleteDetailData(body[row.detailName], row, queryRunner); + } + + + body["createdBy"] = 'SYSTEM'; + body["modifiedBy"] = 'SYSTEM'; + if (!await this.beforeCreateOne(body, queryRunner)) + throw new BadRequestException(`Unepected Error Occured in CreateOne`); + + const data = await queryRunner.manager.save(this.repo.metadata.name, body); + await this.insertDetailData(body, this.DETAIL_DATA_FORMAT, queryRunner, data); + + await this.afterCreateOne(body); + await queryRunner.commitTransaction(); + + + const filter: FindManyOptions = await this.getFilterWithPrimaryKey(body); + const result = await this.findOne(filter, data[this.MAIN_KEY]); + + return await this.postCreateOne(body, result); + + } catch (err) { + // since we have errors lets rollback changes we made + console.log('--- err --', err); + console.log('QueryFailedError', err.QueryFailedError); + console.log('*******err name*****', err.name); + console.log('-- message------', err.message); + console.log('-- code------', err.code); + + console.log('--- err.status --', err.status); + console.log("===is active===", queryRunner.isTransactionActive); + if (queryRunner.isTransactionActive) + await queryRunner.rollbackTransaction(); + console.log("heree===afterrollback"); + if (err.status && err.status == '401') throw new MethodNotAllowedException(`${err.message.message}`); + if (!(err.name == "QueryFailedError")) if (queryRunner.isTransactionActive) await queryRunner.rollbackTransaction(); + //console.log("====after rollback===="); + if (err.name == "QueryFailedError") { + if (err.precedingErrors && err.precedingErrors.length > 0 && err.precedingErrors[0].originalError) + throw new BadRequestException(`${err.precedingErrors[0].originalError}`); + if (err.originalError) + throw new BadRequestException(`${err.originalError}`); + } + if (err.status && err.status == 500) throw new HttpException(err.message.error, err.message.statusCode); + if (err.status) throw new HttpException(err.message, err.status); + + throw new InternalServerErrorException(`${err.message}`); + } + finally { + console.log('--- finally --- '); + await queryRunner.release(); + } + + } + + async afterCreateOne(body: T): Promise { + } + + async postCreateOne(body: T, result: T): Promise { + return result; + } + + async insertDetailData(body: T, detailData: TransactionDetailDto[], queryRunner: QueryRunner, insertedData: T): Promise { + + for (let row of detailData) { + await this.insertDetailData2ndLevel(body[row.detailName], row, queryRunner, insertedData, insertedData); + } + } + + async deleteDetailDataTabels(id: string | number, detailDataFormat: TransactionDetailDto[], queryRunner: QueryRunner): Promise { + for (let row of detailDataFormat) { + await this.deleteDetailTableData(id, row, queryRunner); + } + } + + async deleteDetailTableData(id: string | number, detailData: TransactionDetailDto, queryRunner: QueryRunner): Promise { + if (detailData.childDetail && detailData.childDetail.length > 0) { + for (let child of detailData.childDetail) { + await this.deleteDetailTableData(id, child, queryRunner); + } + } + if (id) { + let filter = {}; + if (detailData.foreignKeyColumnName) { + filter[detailData.foreignKeyColumnName] = id; + + } else { + filter[detailData.foreignKeyAssignmentColumnName.columnName] = id; + } + await queryRunner.manager.delete(detailData.repo.metadata.name, filter); + } + } + + async deleteDetailData(body: T[], detailData: TransactionDetailDto, queryRunner: QueryRunner): Promise { + if (detailData.childDetail && detailData.childDetail.length > 0) { + for (let child of detailData.childDetail) { + if (body && body.length > 0) { + for (let row of body) { + if (row["crud"] == "D") { + for (let detData of row[child.detailName]) { + detData["crud"] = "D"; + } + } + row[child.detailName] = await this.deleteDetailData(row[child.detailName], child, queryRunner); + } + } + } + } + if (body) { + await queryRunner.manager.remove(detailData.repo.metadata.name, body.filter((row: any) => row.crud == 'D')); + body = body.filter((row: any) => row["crud"] != 'D'); + return body; + } else { + return []; + } + } + + async insertDetailData2ndLevel(body: T[], detailData: TransactionDetailDto, queryRunner: QueryRunner, headerData: T, detailHeaderData: T): Promise { + + let deatilInsResult: any; + let eagerCols: any = await this.getEagerColumns(detailData.repo); + if (body) { + for (let row of body) { + for (let col of eagerCols) { + delete row[col]; + } + if (this.TXN_TYPE) row[this.DETAIL_DATA_FORMAT[0].transactionTypeColumnName] = this.TXN_TYPE; + if (detailData.foreignKeyColumnName) { + row[detailData.foreignKeyColumnName] = headerData[this.MAIN_KEY]; + } else { + + row[detailData.foreignKeyAssignmentColumnName.columnName] + = detailHeaderData[detailData.foreignKeyAssignmentColumnName.headerColumn]; + } + row["createdBy"] = 'SYSTEM'; + row["modifiedBy"] = 'SYSTEM'; + if (detailData.addtionalSettingOfRowsInInsertion && detailData.addtionalSettingOfRowsInInsertion.length > 0) { + for (let addRow of detailData.addtionalSettingOfRowsInInsertion) { + row[addRow.columnName] = detailHeaderData[addRow.headerColumn]; + } + } + + deatilInsResult = await queryRunner.manager.save(detailData.repo.metadata.name, row); + if (detailData.childDetail && detailData.childDetail.length > 0) { + for (let child of detailData.childDetail) { + if (body && body.length > 0) { + await this.insertDetailData2ndLevel(row[child.detailName], child, queryRunner, headerData, deatilInsResult); + } + } + } + } + } + + } + + async getDetailData(result: any, filter: FindManyOptions, detailData: TransactionDetailDto[]): Promise { + for (let row of detailData) { + result[row.detailName] = []; + let filterDetail: FindManyOptions = Object.assign({}, filter); + if (!filterDetail.where) filterDetail.where = {}; + for (let filterRow of row.filter) { + filterDetail.where[filterRow.columnName] = filterRow.headerColumn ? result[filterRow.headerColumn] : filterRow.value; + }; + if (row.orderByColumn) { + if (!filterDetail.order) filterDetail["order"] = {}; + filterDetail.order[row.orderByColumn.columnName] = row.orderByColumn.sort; + } + result[row.detailName] = await row.repo.find(filterDetail); + if (row.childDetail && row.childDetail.length > 0) { + for (let detailRows of result[row.detailName]) + detailRows = await this.getDetailData(detailRows, filter, row.childDetail); + } + }; + + return result; + } + + /*-- To get the filter using primary key --*/ + async getFilterWithPrimaryKey(body: T): Promise { + const filter: FindManyOptions = { where: {} }; + const PRIMARY_KEYS = await this.getPrimaryKeys(); + await PRIMARY_KEYS.forEach((column) => { + filter.where[column] = body[column]; + }); + return filter; + } + + /*-- To get the filter for delete --*/ + async getDeleteFilter(whereFilter: FindManyOptions): Promise { + const filter: FindManyOptions = {}; + const PRIMARY_KEYS = await this.getPrimaryKeys(); + await PRIMARY_KEYS.forEach((column) => { + filter[column] = whereFilter.where[column]; + }); + return filter; + } + + /*-- To get the Primary Keys of the entity --*/ + async getPrimaryKeys(): Promise { + const PRIMARY_KEYS: string[] = []; + await this.repo.metadata.primaryColumns.forEach((row) => { + PRIMARY_KEYS.push(row.propertyName); + }); + return PRIMARY_KEYS; + } + + async getEagerColumns(repoDetail?: any): Promise { + /* + For getting Eager true columns having Many to One relations. + We need to remove the eager columns before insertions or updations or it will not allow to save data (But save message will show, but data not updated) + */ + const COLUMNS: string[] = []; + for (let columnProperty of (repoDetail ? repoDetail.metadata.eagerRelations : this.repo.metadata.eagerRelations)) { //AJ + COLUMNS.push(columnProperty.propertyName); + } + return COLUMNS; + } + + +} \ No newline at end of file diff --git a/src/framework/custom/pcd-dto.custom.ts b/src/framework/custom/pcd-dto.custom.ts new file mode 100644 index 0000000..22fb870 --- /dev/null +++ b/src/framework/custom/pcd-dto.custom.ts @@ -0,0 +1,14 @@ +export class PcdBaseDto { + + createdBy: string; + + createdDate: Date; + + modifiedBy: string; + + modifiedDate: Date; + + versionNo: number; + + sessionNo: number; +} \ No newline at end of file diff --git a/src/framework/custom/pcd-entity.custom.ts b/src/framework/custom/pcd-entity.custom.ts new file mode 100644 index 0000000..8b88308 --- /dev/null +++ b/src/framework/custom/pcd-entity.custom.ts @@ -0,0 +1,63 @@ +import { CreateDateColumn, Column, UpdateDateColumn, VersionColumn, BaseEntity, Entity } from "typeorm"; + +export abstract class PcdBaseEntity extends BaseEntity { + + @Column({ + name: "created_by", + type: "varchar", + length: 12, + default:() => "'SYSTEM'", + }) + createdBy: string; + + // @Column({ + // name: "created_country", + // type: "numeric", + // nullable: true + // }) + // createdCountry: string; + + @CreateDateColumn({ + name: "created_date", + default:() => "CURRENT_TIMESTAMP", + }) + createdDate: Date; + + @Column({ + name: "modified_by", + type: "varchar", + length: 12, + default:() => "'SYSTEM'", + }) + modifiedBy: string; + + // @Column({ + // name: "modified_country", + // type: "numeric", + // nullable: true + // }) + // modifiedCountry: string; + + @UpdateDateColumn({ + name: "modified_date", + default:() => "CURRENT_TIMESTAMP", + }) + modifiedDate: Date; + + @VersionColumn({ + name: "version_no", + type: "number", + nullable: true + }) + versionNo: number + + @VersionColumn({ + name: "session_no", + type: "number", + nullable: true + }) + sessionNo: number + + + +} \ No newline at end of file diff --git a/src/framework/custom/pcd-view-entity.custom.ts b/src/framework/custom/pcd-view-entity.custom.ts new file mode 100644 index 0000000..182a9ba --- /dev/null +++ b/src/framework/custom/pcd-view-entity.custom.ts @@ -0,0 +1,15 @@ +import { BaseEntity, Column } from "typeorm"; + +export class PcdViewEntity extends BaseEntity { + + @Column("string",{ + name:"CREATED_BY" + }) + createdBy:string; + + @Column("date",{ + name:"CREATED_DATE" + }) + createdDate:Date; + +} \ No newline at end of file diff --git a/src/framework/custom/transaction-detail.dto.ts b/src/framework/custom/transaction-detail.dto.ts new file mode 100644 index 0000000..72a5c62 --- /dev/null +++ b/src/framework/custom/transaction-detail.dto.ts @@ -0,0 +1,23 @@ +import { Repository } from "typeorm"; + +export class TransactionDetailDto { + + detailName: string; + + foreignKeyColumnName?: string; + + foreignKeyAssignmentColumnName?: {columnName:string,headerColumn:string}; + + repo: Repository; + + filter: { columnName: string, value?: any, headerColumn?: string }[]; + + childDetail: TransactionDetailDto[]; + + addtionalSettingOfRowsInInsertion?: { columnName: string, value?: any, headerColumn?: string }[]; + + transactionTypeColumnName?:string; + + orderByColumn?: {columnName : string, sort : "DESC" | "ASC" }; + +} diff --git a/src/framework/interface/pcd-form-grid.interface.ts b/src/framework/interface/pcd-form-grid.interface.ts new file mode 100644 index 0000000..9c862fd --- /dev/null +++ b/src/framework/interface/pcd-form-grid.interface.ts @@ -0,0 +1,16 @@ +import { FindManyOptions } from "typeorm"; +import { PcduserDto } from "src/auth/dto/pcd-user.dto"; + +export interface PcdFormGridInterface { + + findAll(filter: FindManyOptions, user: PcduserDto): Promise; + + findOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise; + + createOne(body: any, user: PcduserDto): Promise + + updateOne(body: any, id: string | number, user: PcduserDto): Promise; + + deleteOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise; + +} \ No newline at end of file diff --git a/src/framework/interface/pcd-transaction.interface.ts b/src/framework/interface/pcd-transaction.interface.ts new file mode 100644 index 0000000..2d67bf1 --- /dev/null +++ b/src/framework/interface/pcd-transaction.interface.ts @@ -0,0 +1,8 @@ +import { PcduserDto,} from "src/auth/dto/pcd-user.dto"; +import { FindManyOptions } from "typeorm"; + +export interface PcdtTransactionInterface { + + findList(filter: FindManyOptions, user: PcduserDto): Promise; + +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..8c348b9 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,25 @@ +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app.module'; +import * as config from 'config'; +import { Logger } from '@nestjs/common'; +import * as bodyParser from 'body-parser'; +import { urlencoded, json } from 'express'; + + +async function bootstrap() { + + const serverConfig = config.get('server'); + // const whiteIp = config.get('whiteIp') + const logger = new Logger('bootstrap'); + const app = await NestFactory.create(AppModule, { cors: true }); + const port = process.env.PORT || serverConfig.port; // for logging and config + app.setGlobalPrefix('api/v1'); + app.enableCors(); + app.use(json({ limit: '50mb' })); + app.use(urlencoded({ extended: true, limit: '50mb' })); + await app.listen(port); + + logger.log(`Application listing on port ${port}`) // for logging +} +// Cluster.register(4, bootstrap); +bootstrap() diff --git a/src/payment-gateway/payment-gateway.controller.ts b/src/payment-gateway/payment-gateway.controller.ts new file mode 100644 index 0000000..94f6567 --- /dev/null +++ b/src/payment-gateway/payment-gateway.controller.ts @@ -0,0 +1,323 @@ +import { Body, Controller, Get, Param, Post, Query, Req, Res, UseGuards } from '@nestjs/common'; +import { FreeChargePaymentGatewayService, PaymentGatewayService, phonepeGatewayService } from './payment-gateway.service'; +import * as config from 'config'; +import { AuthGuard } from '@nestjs/passport'; +import { GetUser } from 'src/auth/dto/get-user.decorator'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { PurchaseDto } from 'src/dto/purchase.dto'; +import { FindManyOptions } from 'typeorm'; +import { PaymentMasterRepository } from 'src/tables/payment-master/payment-master.repository'; + +@Controller('payment-gateway') +export class PaymentGatewayController { + constructor( + private paymentGatewayService: PaymentGatewayService, + private paymentMasterRepo : PaymentMasterRepository + ) { } + + @Post() + @UseGuards(AuthGuard()) + createPayment( + @Req() req, + @Res() res, + @GetUser() user: PcduserDto + ): void { + // console.log('=============',user); + + try { + const paymentBody: PurchaseDto = req.body; + paymentBody.amount = req.body.amount; + paymentBody.email = req.body.email; + paymentBody['user'] = user.userId; + paymentBody.mobile = req.body.mobile; + paymentBody.application = `${req.body.application}ESC${user.userId}`; + paymentBody.type = req.body.type; + this.paymentGatewayService.makePayment(req.body, (error, result) => { + if (error) { + res.status(error.code).send(error) + //res.send (error); + } else { + res.send(result); + } + }); + } catch (e) { + console.log("Exception in creating User Data . ", e); + } + } + + @Post('public') + createPaymentPublic( + @Req() req, + @Res() res, + ): void { + // console.log('=============',user); + + try { + const paymentBody: PurchaseDto = req.body; + paymentBody.amount = req.body.amount; + paymentBody.email = req.body.email; + paymentBody['user'] = 'system'; + paymentBody.mobile = req.body.mobile; + paymentBody.application = req.body.application; + paymentBody.type = req.body.type; + paymentBody.menuId = 'PUBLIC'; + this.paymentGatewayService.makePayment(req.body, (error, result) => { + if (error) { + res.status(error.code).send(error) + //res.send (error); + } else { + res.send(result); + } + }); + } catch (e) { + console.log("Exception in creating User Data . ", e); + } + } + + @Post('success') + async paymentSuccess( + @Req() req, + @Res() res, + ): Promise { + console.log("==req====", req.body); + try { + const paymentSuccessBody = req.body; + console.log(paymentSuccessBody); + const userId = paymentSuccessBody.lastname.split('ESC')[1]; + const tenderId = paymentSuccessBody.lastname.split('ESC')[0]; + let user = await this.paymentMasterRepo.findOne({where:{ userId: userId , tenderId:tenderId}}); + console.log(user); + + this.paymentGatewayService.paymentSuccess(paymentSuccessBody, (error, result) => { + const prodInfo = paymentSuccessBody.productinfo.split('ESC'); + console.log(prodInfo, '#####'); + console.log('*************', config.get('payment-gateway')); + + if (error) { + let redirectUrl + redirectUrl = config.get('url').url + config.get('payment-gateway').failureRedirectUrl + `/${req.body.lastname.split('ESC')[0]}/f`; + user.status = 'F' + this.paymentMasterRepo.save(user); + console.log("==redirectUrl====", redirectUrl); + res.redirect(redirectUrl); + // res.send(error); + } else { + let redirectUrl + redirectUrl = config.get('url').url + config.get('payment-gateway').successRedirectUrl + `/${req.body.lastname.split('ESC')[0]}/s`; + user.status = 'S' + this.paymentMasterRepo.save(user); + console.log("==redirectUrl====", redirectUrl); + res.redirect(redirectUrl); + } + }); + + } catch (e) { + console.log("Exception in creating User Data . ", e); + } + } + + @Post('failure') + async paymentFailure( + @Req() req, + @Res() res, + ): Promise { + console.log(req.body, 'request body'); + try { + const paymentFailureBody = req.body; + const userId = paymentFailureBody.lastname.split('ESC')[1]; + const tenderId = paymentFailureBody.lastname.split('ESC')[0]; + let user = await this.paymentMasterRepo.findOne({where:{ userId: userId , tenderId:tenderId}}); + console.log(user); + this.paymentGatewayService.paymentFailure(paymentFailureBody, (error, result) => { + console.log(paymentFailureBody); + console.log(config.get('payment-gateway')); + + + + if (error) { + res.send(error); + user.status = 'F' + this.paymentMasterRepo.save(user); + } else { + // Redirect to payment failure page + let redirectUrl + redirectUrl = config.get('url').url + config.get('payment-gateway').failureRedirectUrl + `${req.body.lastname.split('ESC')[0]}/f`; + user.status = 'F' + this.paymentMasterRepo.save(user); + res.redirect(redirectUrl); + } + }); + } catch (e) { + console.log("Exception in creating User Data . ", e); + } + } +} + +// @Controller('payment-gateway-fc') +// export class FreeChargePaymentGatewayController { +// constructor( +// private freeChargePaymentGatewayService: FreeChargePaymentGatewayService +// ) { } + +// @Post('status') +// async checkPaymentStatus( +// @Body() body: any, +// @GetUser() user: PcduserDto +// ): Promise { +// console.log("===dd===", body); +// return await this.freeChargePaymentGatewayService.checkPaymentStatus(body, user); +// } + +// @Post('refund') +// async refundPayment( +// @Body() body: any, +// @GetUser() user: PcduserDto +// ): Promise { +// console.log("===dd===", body); +// return await this.freeChargePaymentGatewayService.refundPayment(body, user); +// } + + +// @Post() +// @UseGuards(AuthGuard()) +// createPayment( +// @Req() req, +// @Res() res, +// @GetUser() user: PcduserDto +// ): void { +// // console.log('=============',user); + +// try { +// const paymentBody: PurchaseDto = req.body; +// paymentBody.amount = req.body.amount; +// paymentBody.email = req.body.email; +// paymentBody['user'] = user.userId; +// paymentBody.mobile = req.body.mobile; +// paymentBody.application = req.body.application; +// paymentBody.type = req.body.type; +// this.freeChargePaymentGatewayService.makePayment(paymentBody, (error, result) => { +// if (error) { +// // console.log(error,'err here'); + +// res.status(error.status).send() +// //res.send (error); +// } else { +// res.send(result); +// } +// }); +// } catch (e) { +// console.log("Exception in creating User Data . ", e); +// } +// } + + +// @Post('success') +// paymentSuccess( +// @Req() req, +// @Res() res, +// ): void { +// console.log("==req====", req.body); +// try { + +// console.log(req.body); +// if (req.body.statusCode == "SPG-0000") { +// const paymentSuccessBody = req.body; +// this.freeChargePaymentGatewayService.paymentSuccess(paymentSuccessBody, (error, result) => { +// if (error) { +// console.log(error, 'error test'); + +// let redirectUrl +// if (paymentSuccessBody.productinfo == 'F') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').successRedirectUrl + `/${paymentSuccessBody.lastname}?payment=Y`; +// } else if (paymentSuccessBody.productinfo == 'S') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').failureRedirectUrlStudent + `?id=${paymentSuccessBody.lastname}&status=Y`; +// } else if (paymentSuccessBody.productinfo == 'A') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').failureRedirectUrlAcceptance + `/${paymentSuccessBody.lastname}?status=N`; +// } else if (paymentSuccessBody.productinfo == 'I') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').failureRedirectUrlStudentInternal + `?rollNo=${paymentSuccessBody.lastname}&status=N`; +// } + + +// res.redirect(redirectUrl); +// // res.send(error); +// } else { +// console.log('success test', paymentSuccessBody.productinfo); + +// let redirectUrl +// if (paymentSuccessBody.productinfo == 'F') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').successRedirectUrl + `/${paymentSuccessBody.lastname}?payment=Y`; +// } else if (paymentSuccessBody.productinfo == 'S') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').successRedirectUrlStudent + `?id=${paymentSuccessBody.lastname}&status=Y`; +// } else if (paymentSuccessBody.productinfo == 'A') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').successRedirectUrlAcceptance + `/${paymentSuccessBody.lastname}?status=Y`; +// } else if (paymentSuccessBody.productinfo == 'I') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').successRedirectUrlStudentInternal + `?rollNo=${paymentSuccessBody.lastname}&studentId=${paymentSuccessBody.studentId}&status=Y`; +// } +// console.log(redirectUrl, 'red'); +// res.redirect(redirectUrl); +// } +// }); +// } +// else if (req.body.statusCode == "SPG-0001") { +// const paymentFailureBody = req.body; +// this.freeChargePaymentGatewayService.paymentFailure(paymentFailureBody, (error, result) => { +// if (error) { +// res.send(error); +// } else { +// // Redirect to payment failure page +// let redirectUrl +// if (paymentFailureBody.productinfo.split('ESC')[1] == 'F') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').successRedirectUrl + `/${paymentFailureBody.lastname}?payment=N`; +// } else if (paymentFailureBody.productinfo.split('ESC')[1] == 'S') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').failureRedirectUrlStudent + `?id=${paymentFailureBody.lastname}&status=N`; +// } else if (paymentFailureBody.productinfo.split('ESC')[1] == 'A') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').failureRedirectUrlAcceptance + `/${paymentFailureBody.lastname}?status=N`; +// } else if (paymentFailureBody.productinfo.split('ESC')[1] == 'I') { +// redirectUrl = config.get('url').url + config.get('payment-gateway').failureRedirectUrlStudentInternal + `?rollNo=${paymentFailureBody.lastname}&status=N`; +// } + +// res.redirect(redirectUrl); +// } +// }); +// } +// } catch (e) { +// console.log("Exception in creating User Data . ", e); +// } + // } + + +// } + + + +@Controller('phonepe-payment-gateway') +export class phonepePaymentGatewayController { + constructor( + private phonepeGatewayService: phonepeGatewayService + ) { } + + @Post() + @UseGuards(AuthGuard()) + async createOrder( + @Body() body:{ name:string,mobile:number,amount:number,type:string,tenderId:number,emdFeeType?:string + }, + @GetUser() user : PcduserDto + ){ + let result = await this.phonepeGatewayService.createOrder(body,user) + return result + } + + @Post('payment-status/:userId/:tenderId/:type') + async paymentStatus( + @Req() req, + @Res() res, + @Param('userId') userId:number, + @Param('tenderId') tenderId:number, + @Param('type') type:number + ){ + let result = await this.phonepeGatewayService.paymentStatus(req,res,tenderId,userId,type) + + return result + } + + } \ No newline at end of file diff --git a/src/payment-gateway/payment-gateway.module.ts b/src/payment-gateway/payment-gateway.module.ts new file mode 100644 index 0000000..205bcfa --- /dev/null +++ b/src/payment-gateway/payment-gateway.module.ts @@ -0,0 +1,43 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { AuthService } from 'src/auth/auth.service'; +import { CryptoService } from 'src/auth/crypto.service'; +import { PcduserRepository } from 'src/auth/pcduser.repository'; +import { EmailModule } from 'src/email/email.module'; +import { PaymentStatusRepository } from 'src/tables/payment-status/payment-status.repository'; +import { HttpModule } from '@nestjs/axios'; + +import { PaymentGatewayController, phonepePaymentGatewayController } from './payment-gateway.controller'; +import { PaymentGatewayService, phonepeGatewayService } from './payment-gateway.service'; +import { PaymentMasterRepository } from 'src/tables/payment-master/payment-master.repository'; +import { PhonepeTransactionListRepository } from 'src/tables/phonepe-transaction-list/phonepe-transaction-list.repository'; +import { PcdotpRepository } from 'src/auth/pcdotp.repository'; +import { categoryRepository } from 'src/tables/userCategory-master/category.repository'; +import { TenderMasterRepository } from 'src/tables/tender-master/tender-master.repository'; +import { userSubCategoryMasterRepo } from 'src/tables/user-subcategory-master/user-subcategory-master.repository'; + +@Module({ + imports: [ + + TypeOrmModule.forFeature([ + PaymentStatusRepository, + PaymentMasterRepository, + PhonepeTransactionListRepository + + ]), AuthModule, + HttpModule.register({ + timeout: 5000, + maxRedirects: 5, + }), + + EmailModule, + ], + controllers: [PaymentGatewayController,phonepePaymentGatewayController], + providers: [PaymentGatewayService,phonepeGatewayService,AuthService, + CryptoService,PaymentStatusRepository,PaymentMasterRepository, + PhonepeTransactionListRepository,PcduserRepository,PcdotpRepository,categoryRepository, + TenderMasterRepository,userSubCategoryMasterRepo + ] +}) +export class PaymentGatewayModule { } diff --git a/src/payment-gateway/payment-gateway.service.ts b/src/payment-gateway/payment-gateway.service.ts new file mode 100644 index 0000000..95d4ecc --- /dev/null +++ b/src/payment-gateway/payment-gateway.service.ts @@ -0,0 +1,859 @@ +import { BadRequestException, HttpException, Injectable, InternalServerErrorException, Logger, MethodNotAllowedException, Req, Res } from '@nestjs/common'; +import { PaymentDto } from '../dto/payment.dto'; +import { AuthService } from 'src/auth/auth.service'; +import { Connection, FindManyOptions, getConnection } from 'typeorm'; +import { InjectRepository } from '@nestjs/typeorm'; +import * as bcrypt from 'bcrypt'; +//import { generate } from 'generate-password'; +import * as config from 'config'; +import { CryptoService } from 'src/auth/crypto.service'; +import { PcduserRepository } from 'src/auth/pcduser.repository'; +import { PaymentStatusRepository } from 'src/tables/payment-status/payment-status.repository'; +import { PurchaseDto } from 'src/dto/purchase.dto'; +import { PaymentStatusDto } from 'src/dto/payment-status.dto'; +import { convertDate } from 'src/pipe/pcd-date.pipe'; +var crypto = require('crypto') + +import { PayuTransactionListDto } from 'src/dto/payu-transaction-list.dto'; +import { PayuTransactionListRepository } from 'src/tables/payu-transaction-list/payu-transaction-list.repository'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { PaymentMasterDto } from 'src/dto/payment-master.dto'; +import { Console } from 'console'; +import { PaymentMasterRepository } from 'src/tables/payment-master/payment-master.repository'; +import { HttpService } from '@nestjs/axios'; +import { phonepeTransactionDto } from 'src/dto/phonepeTransaction.dto'; +import { PhonepeTransactionListRepository } from 'src/tables/phonepe-transaction-list/phonepe-transaction-list.repository'; +import { TenderMasterRepository } from 'src/tables/tender-master/tender-master.repository'; + + + +const payUMoney = require("payumoney_nodejs"); +const querystring = require('querystring'); + +const paymentGatewayConf = config.get('payment-gateway'); +const phonepeGatewayConf = config.get('phonepe-gateway') +const paymentGatewayMethod: "DHOFAR" | "PAYU" = paymentGatewayConf.method; + +@Injectable() +export class PaymentGatewayService { + + private logger = new Logger('PaymentGatewayService'); // for logging + + + constructor( + private readonly http: HttpService, + // private authService: AuthService, + private paymentStatusRepo: PaymentStatusRepository, + private paymentMasterRepo: PaymentMasterRepository, + + private crypto: CryptoService, + + ) { + // Set you MERCHANT_KEY, MERCHANT_SALT_KEY, PAYUMONEY_AUTHORIZATION_HEADER + // for both Production and Sandox Account + payUMoney.setProdKeys(paymentGatewayConf.key, paymentGatewayConf.salt, "ylb6+TCDC20wlyTooZbYM9wDw4abjaOVV9KiHFzGPgw="); + payUMoney.setSandboxKeys(paymentGatewayConf.key, paymentGatewayConf.salt, "ylb6+TCDC20wlyTooZbYM9wDw4abjaOVV9KiHFzGPgw="); + payUMoney.isProdMode(true); + } + + public async makePayment(paymentBody: PurchaseDto, callback: (error: any, response: any) => void) { + // let total = 0; + // let tax = 0; + // let totalAmount = 0; + // let minAmount = paymentBody.amount; + // key : "crvbe4" + // salt : "wIVuIkieIBBrSYtXP3aVw5uFH7eFe2nM" + + let date = new Date() + let paymentStatus = new PaymentStatusDto() + paymentStatus.createdBy = paymentBody["user"]; + paymentStatus.modifiedBy = paymentBody["user"]; + paymentStatus.email = paymentBody.email; + paymentStatus.type = paymentBody.type; + paymentStatus.status = 'U'; + paymentStatus.paymentOption = 'P'; //F - FreeCharge | P - PayU + + let paymentModel = new PaymentDto(); + paymentModel.txnid = Date.now(); + paymentStatus.txnid = paymentModel.txnid; + paymentModel.firstname = 'Admin'; + paymentModel.lastname = paymentBody.application.toString(); + paymentModel.email = paymentBody.email; + paymentModel.service_provider = 'payu_paisa'; + paymentModel.furl = config.get('payment-gateway').furl; + paymentModel.surl = config.get('payment-gateway').surl; + paymentModel.amount = 1; + + let paymentMaster = new PaymentMasterDto(); + paymentMaster.userId = paymentModel.lastname.split('ESC')[1]; + paymentMaster.tenderId = parseInt(paymentModel.lastname.split('ESC')[0]); + paymentMaster.transId = paymentStatus.txnid; + paymentMaster.status = 'P'; + console.log('paymentmasterDto======', paymentMaster); + + const paymentMas = this.paymentMasterRepo.save(paymentMaster); + + + // if (paymentBody.type == 'F') { + // let application = await this.sisAdmissionFormRepository.findOne(paymentBody.application); + // if (!application) + // throw new BadRequestException('application not generated') + // paymentStatus.paymentDate = new Date(); + // paymentStatus.amount = application.receiptAmount; + // paymentStatus.application = application.id; + // paymentModel.phone = parseInt(application.motherPhoneNo); + // if (paymentGatewayConf.testing == true) + // paymentModel.amount = 1; + // else + // paymentModel.amount = application.receiptAmount; + // } + // if (paymentBody.type == 'S') { + // let payment = await this.sisFeePaymentOnlineRepository.findOne(paymentBody.application); + // if (!payment) + // throw new BadRequestException('payment not generated') + // paymentStatus.paymentDate = new Date(); + // paymentStatus.amount = payment.paidAmount; + // paymentStatus.paymentId = payment.id; + // paymentModel.phone = payment.contactPhone; + // if (paymentGatewayConf.testing == true) + // paymentModel.amount = 1; + // else + // paymentModel.amount = payment.paidAmount; + + // } + // if (paymentBody.type == 'I') { + // let payment = await this.sisFeePaymentOnlineRepository.findOne(paymentBody.application); + // if (!payment) + // throw new BadRequestException('payment not generated') + // paymentStatus.paymentDate = new Date(); + // paymentStatus.amount = payment.paidAmount; + // paymentStatus.paymentId = payment.id; + // paymentModel.phone = payment.contactPhone; + // if (paymentGatewayConf.testing == true) + // paymentModel.amount = 1; + // else + // paymentModel.amount = payment.paidAmount; + + // } + // if (paymentBody.type == 'A') { + // let application = await this.sisAdmissionFormRepository.findOne(paymentBody.application); + // let courseFee = await this.sisFeeRepository.findOne({ where: { id: application.acceptance } }) + // if (!application) + // throw new BadRequestException('payment not generated') + // let date = new Date() + // paymentStatus.paymentDate = new Date(); + // paymentStatus.amount = parseInt(courseFee.feeCharge); + // paymentStatus.application = application.id; + // paymentStatus.identifier = 'A'; + // paymentModel.phone = parseInt(application.motherPhoneNo); + // if (paymentGatewayConf.testing == true) + // paymentModel.amount = 1; + // else + // paymentModel.amount = parseInt(courseFee.feeCharge); + + // } + const pay = await this.paymentStatusRepo.save(paymentStatus); + paymentModel.productinfo = `${pay.id}ESC${paymentBody.type}`; + console.log(paymentModel); + + { + payUMoney.pay(paymentModel, (error: any, response: any) => { + if (error) { + console.error("makePayment error : " + error); + callback(error, null); + } else { + console.log("Payment Redirection link " + response + '===' + error); + callback(error, { url: response }); + } + }); + } + } + + public async paymentSuccess(paymentBody: any, callback: (error: any, response: any) => void) { + // console.log("===payment body===", paymentBody); + let code; + let paymentSuccessBody; + let receiptNo; + let receiptNoPrefix; + + paymentSuccessBody = paymentBody; + code = paymentSuccessBody.txnid; + console.log(paymentSuccessBody, 'successbody'); + + let paymentStatus = await this.paymentStatusRepo.findOne({ where: { "id": paymentSuccessBody.productinfo.split('ESC')[0] } }); + paymentStatus.status = 'S'; + await this.paymentStatusRepo.save(paymentStatus); + + // const queryRunner = getConnection().createQueryRunner(); + // await queryRunner.connect(); + // await queryRunner.startTransaction(); + // try { + // let productData + // // if (paymentStatus.type == 'F' || paymentStatus.type == 'A') { + // // productData = await this.sisAdmissionFormRepository.findOne({ where: { id: paymentStatus.application }, select: ['id', 'sessionId'] }) + // // } else { + // // productData = await this.sisFeePaymentOnlineRepository.findOne({ where: { id: paymentStatus.paymentId }, select: ['id', 'sessionId'] }) + // // } + + // // const session = await this.sisSessionRepository.findOne({ where: { id: productData.sessionId } }); + // // receiptNoPrefix = session.sessionCode; + // // receiptNo = parseInt(session.receiptSeq.toString()) + 1; + + // // await queryRunner.manager.query(`update sis_session set receipt_seq = ${receiptNo} where id = ${session.id}`); + // // if (paymentStatus.type == 'F') + // // await queryRunner.manager.query(`update sis_admission_form set payment_stat ='S',receipt_no_prefix='${receiptNoPrefix}',receipt_no = '${receiptNo}' where id = ${paymentStatus.application}`) + // // if (paymentStatus.type == 'S') { + // // await queryRunner.manager.query(`update sis_fee_payment_online set payment_stat ='S',txnid = '${code}',receipt_no_prefix='${receiptNoPrefix}',receipt_no = ${receiptNo} where id = ${paymentStatus.paymentId}`) + // // } + // // if (paymentStatus.type == 'I') { + // // await queryRunner.manager.query(`update sis_fee_payment_online set payment_stat ='S',txnid = '${code}',receipt_no_prefix='${receiptNoPrefix}',receipt_no = ${receiptNo} where id = ${paymentStatus.paymentId}`) + // // const data = await this.sisFeePaymentOnlineRepository.findOne({ where: { id: paymentStatus.paymentId }, select: ['id', 'studentId'] }); + // // const student = await this.sisStudentRepository.findOne({ where: { id: data.studentId }, select: ['id', 'rollNo', 'sessionId'] }); + // // paymentBody.lastname = student.rollNo; + // // paymentBody['studentId'] = student.id; + // // paymentBody['sessionId'] = student.sessionId; + + // // } + // // if (paymentStatus.type == 'A') { + // // await queryRunner.manager.query(`update sis_admission_form set acceptance_fee_stat ='S',acceptance_receipt_no_prefix='${receiptNoPrefix}',acceptance_receipt_no = '${receiptNo}' where id = ${paymentStatus.application}`) + // // } + // queryRunner.commitTransaction() + + + callback(null, { status: "Payment Success", id: code }); + // } catch (error) { + // queryRunner.rollbackTransaction() + // } finally { + // queryRunner.release() + // } + + } + + public async paymentFailure(paymentBody: any, callback: (error: any, response: any) => void) { + let paymentFailureBody; + let code; + console.log("Payment Failure"); + paymentFailureBody = paymentBody; + + + let paymentStatus = await this.paymentStatusRepo.findOne({ where: { "txnid": paymentFailureBody.txnid } }); + paymentStatus.status = 'F'; + await this.paymentStatusRepo.save(paymentStatus); + + code = paymentFailureBody.txnid; + + // await this.authService.updateHeader(code, 2, paymentFailureBody); + callback(null, { status: "Payment Failed" }); + } + + async insertPaymentStatus() { + + } + + // PAYU SECTION END DONT ADD PAYU RELATED CODE BELOW + + + +} +@Injectable() +export class FreeChargePaymentGatewayService { + + constructor( + private readonly http: HttpService, + private paymentStatusRepo: PaymentStatusRepository, + private crypto: CryptoService, + private PayuTransactionListRepository: PayuTransactionListRepository + ) { } + + async getUrl() { + if (config.get('payment-gateway-freecharge').production) { + return config.get('payment-gateway-freecharge').prodUrl; + } else { + return config.get('payment-gateway-freecharge').sandUrl; + } + } + + async makePayment(paymentBody: PurchaseDto, callback: (error: any, response: any) => void) { + let date = new Date() + + let paymentStatus = new PaymentStatusDto() + paymentStatus.createdBy = paymentBody["user"]; + paymentStatus.modifiedBy = paymentBody["user"]; + paymentStatus.email = paymentBody.email; + paymentStatus.type = paymentBody.type; + paymentStatus.status = 'U'; + paymentStatus.paymentOption = 'F'; //F - FreeCharge | P - PayU + + + let paymentJson = { + merchantId: config.get('payment-gateway-freecharge').merchantId, + callbackUrl: config.get('payment-gateway-freecharge').callBackUrl, + merchantTxnId: null, + merchantTxnAmount: paymentBody.amount, + currency: config.get('payment-gateway-freecharge').currency, + customerEmailId: paymentBody.email, + customerMobileNo: paymentBody.mobile, + timestamp: date.getTime(), + udf1: null + } + paymentStatus.txnid = paymentJson.timestamp; + paymentJson.merchantTxnId = paymentJson.timestamp; + + // if (paymentBody.type == 'F') { + // let application = await this.sisAdmissionFormRepository.findOne(paymentBody.application); + // if (!application) + // throw new BadRequestException('application not generated') + // paymentStatus.paymentDate = new Date(); + // paymentStatus.amount = application.receiptAmount; + // paymentStatus.application = application.id; + // paymentJson.customerMobileNo = application.motherPhoneNo; + // if (paymentGatewayConf.testing == true) + // paymentJson.merchantTxnAmount = 1; + // else + // paymentJson.merchantTxnAmount = application.receiptAmount; + // } + // if (paymentBody.type == 'S') { + // let payment = await this.sisFeePaymentOnlineRepository.findOne(paymentBody.application); + // if (!payment) + // throw new BadRequestException('payment not generated') + // paymentStatus.paymentDate = new Date(); + // paymentStatus.amount = payment.paidAmount; + // paymentStatus.paymentId = payment.id; + // paymentJson.customerMobileNo = payment.contactPhone.toString(); + // if (paymentGatewayConf.testing == true) + // paymentJson.merchantTxnAmount = 1; + // else + // paymentJson.merchantTxnAmount = payment.paidAmount; + + // } + // if (paymentBody.type == 'I') { + // let payment = await this.sisFeePaymentOnlineRepository.findOne(paymentBody.application); + // if (!payment) + // throw new BadRequestException('payment not generated') + // paymentStatus.paymentDate = new Date(); + // paymentStatus.amount = payment.paidAmount; + // paymentStatus.paymentId = payment.id; + // paymentJson.merchantTxnAmount = payment.contactPhone; + // if (paymentGatewayConf.testing == true) + // paymentJson.merchantTxnAmount = 1; + // else + // paymentJson.merchantTxnAmount = payment.paidAmount; + + // } + // if (paymentBody.type == 'A') { + // let application = await this.sisAdmissionFormRepository.findOne(paymentBody.application); + // let courseFee = await this.sisFeeRepository.findOne({ where: { id: application.acceptance } }) + // if (!application) + // throw new BadRequestException('payment not generated') + // let date = new Date() + // paymentStatus.paymentDate = new Date(); + // paymentStatus.amount = parseInt(courseFee.feeCharge); + // paymentStatus.application = application.id; + // paymentStatus.identifier = 'A'; + // paymentJson.customerMobileNo = application.motherPhoneNo; + // if (paymentGatewayConf.testing == true) + // paymentJson.merchantTxnAmount = 1; + // else + // paymentJson.merchantTxnAmount = parseInt(courseFee.feeCharge); + + // } + const pay = await this.paymentStatusRepo.save(paymentStatus); + paymentJson.udf1 = `${pay.id}ESC${paymentBody.type}`; + + const ordered = Object.keys(paymentJson).sort().reduce( + (obj, key) => { + obj[key] = paymentJson[key]; + return obj; + }, + {} + ); + + console.log(ordered) + + let string = '' + + for (const [key, value] of Object.entries(ordered)) { + if (value) + string = string + value + } + string = string + config.get('payment-gateway-freecharge').key + console.log(string); + + const hash = crypto.createHash('sha256').update(string).digest('hex'); + + console.log(hash); + paymentJson['signature'] = hash + callback(null, { paymentBody: paymentJson, url: `${await this.getUrl()}/payment/v1/checkout` }) + } + + public async paymentSuccess(paymentBody: any, callback: (error: any, response: any) => void) { + // console.log("===payment body===", paymentBody); + let code; + let paymentSuccessBody; + let receiptNo; + let receiptNoPrefix; + + paymentSuccessBody = paymentBody; + + console.log(paymentSuccessBody, 'successbody'); + + + let paymentStatus = await this.paymentStatusRepo.findOne({ where: { txnid: paymentBody.merchantTxnId } }); + await this.insertPaymentRecord(paymentStatus, paymentSuccessBody); + if (paymentStatus.application) { + paymentSuccessBody.lastname = paymentStatus.application; + } else if (paymentStatus.paymentId) { + paymentSuccessBody.lastname = paymentStatus.paymentId + } + code = paymentStatus.txnid; + paymentStatus.status = 'S'; + paymentStatus.txnrefid = paymentSuccessBody.txnReferenceId; + paymentSuccessBody.productinfo = paymentStatus.type; + await this.paymentStatusRepo.save(paymentStatus); + + const queryRunner = getConnection().createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); + try { + let productData + // if (paymentStatus.type == 'F' || paymentStatus.type == 'A') { + // productData = await this.sisAdmissionFormRepository.findOne({ where: { id: paymentStatus.application }, select: ['id', 'sessionId'] }) + // } else { + // productData = await this.sisFeePaymentOnlineRepository.findOne({ where: { id: paymentStatus.paymentId }, select: ['id', 'sessionId'] }) + // } + + // const session = await this.sisSessionRepository.findOne({ where: { id: productData.sessionId } }); + // receiptNoPrefix = session.sessionCode; + // receiptNo = parseInt(session.receiptSeq.toString()) + 1; + + // await queryRunner.manager.query(`update sis_session set receipt_seq = ${receiptNo} where id = ${session.id}`); + // if (paymentStatus.type == 'F') + // await queryRunner.manager.query(`update sis_admission_form set payment_stat ='S',receipt_no_prefix='${receiptNoPrefix}',receipt_no = '${receiptNo}' where id = ${paymentStatus.application}`) + // if (paymentStatus.type == 'S') { + // await queryRunner.manager.query(`update sis_fee_payment_online set payment_stat ='S',txnid = '${code}',receipt_no_prefix='${receiptNoPrefix}',receipt_no = ${receiptNo} where id = ${paymentStatus.paymentId}`) + // } + // if (paymentStatus.type == 'I') { + // await queryRunner.manager.query(`update sis_fee_payment_online set payment_stat ='S',txnid = '${code}',receipt_no_prefix='${receiptNoPrefix}',receipt_no = ${receiptNo} where id = ${paymentStatus.paymentId}`) + // const data = await this.sisFeePaymentOnlineRepository.findOne({ where: { id: paymentStatus.paymentId }, select: ['id', 'studentId'] }); + // const student = await this.sisStudentRepository.findOne({ where: { id: data.studentId }, select: ['id', 'rollNo', 'sessionId'] }); + // paymentBody.lastname = student.rollNo; + // paymentBody['studentId'] = student.id; + // paymentBody['sessionId'] = student.sessionId; + + // } + if (paymentStatus.type == 'A') { + await queryRunner.manager.query(`update sis_admission_form set acceptance_fee_stat ='S',acceptance_receipt_no_prefix='${receiptNoPrefix}',acceptance_receipt_no = '${receiptNo}' where id = ${paymentStatus.application}`) + } + queryRunner.commitTransaction() + + + callback(null, { status: "Payment Success", id: code }); + } catch (error) { + console.log(error); + + queryRunner.rollbackTransaction() + } finally { + queryRunner.release() + } + + } + + async insertPaymentRecord(paymentStatus: PaymentStatusDto, paymentSuccessBody: any) { + let PayuTransaction = new PayuTransactionListDto(); + PayuTransaction.addedon = paymentStatus.paymentDate; + PayuTransaction.amount = paymentSuccessBody.amount; + PayuTransaction.txnid = paymentSuccessBody.merchantTxnId; + PayuTransaction.status = 'success'; + PayuTransaction.gateway = 'FreeCharge'; + PayuTransaction.transaction_fee = paymentSuccessBody.amount; + PayuTransaction.mer_service_fee = paymentSuccessBody.handlingFee; + PayuTransaction.mer_service_tax = paymentSuccessBody.taxAmount; + PayuTransaction.id = paymentSuccessBody.txnReferenceId; + await this.PayuTransactionListRepository.save(PayuTransaction) + } + + + async checkPaymentStatus(body: any, user: PcduserDto) { + let paymentBody = { + "merchantId": `${config.get('payment-gateway-freecharge').merchantId}`, + "merchantTxnId": `${body.merchantTxnId}` + } + let string = '' + for (const [key, value] of Object.entries(paymentBody)) { + if (value) + string = string + value + } + string = string + config.get('payment-gateway-freecharge').key + console.log(string); + + const hash = crypto.createHash('sha256').update(string).digest('hex'); + paymentBody['signature'] = hash; + return this.http.post(`${await this.getUrl()}/payment/v1/txn/status`, paymentBody).toPromise().then((res) => { + console.log("===res====", res.data); + return res.data; + }, (err) => { + console.log("===errr====", err); + return err; + }); + } + + async refundPayment(body: any, user: PcduserDto) { + let date = new Date() + let paymentBody = { + "merchantId": `${config.get('payment-gateway-freecharge').merchantId}`, + "merchantRefundTxnId": date.getTime(), + "txnReferenceId": body.txnReferenceId, + "refundAmount": body.amount, + "currency": "INR" + } + const ordered = Object.keys(paymentBody).sort().reduce( + (obj, key) => { + obj[key] = paymentBody[key]; + return obj; + }, + {} + ); + let string = '' + for (const [key, value] of Object.entries(ordered)) { + if (value) + string = string + value + } + string = string + config.get('payment-gateway-freecharge').key; + const hash = crypto.createHash('sha256').update(string).digest('hex'); + paymentBody['signature'] = hash; + return this.http.post(`${await this.getUrl()}/payment/v1/refund`, paymentBody).toPromise().then((res) => { + console.log("===res====", res.data); + return res.data; + }, (err) => { + console.log("===errr====", err); + return err; + }); + } + + public async paymentFailure(paymentBody: any, callback: (error: any, response: any) => void) { + let paymentFailureBody; + let code; + + paymentFailureBody = paymentBody; + let paymentStatus = await this.paymentStatusRepo.findOne({ where: { "txnid": paymentFailureBody.merchantTxnId } }); + paymentFailureBody.productinfo = paymentStatus.type; + if (paymentStatus.application) { + paymentFailureBody.lastname = paymentStatus.application; + } else if (paymentStatus.paymentId) { + paymentFailureBody.lastname = paymentStatus.paymentId + } + + paymentStatus.status = 'F'; + await this.paymentStatusRepo.save(paymentStatus); + + code = paymentFailureBody.merchantTxnId; + + // await this.authService.updateHeader(code, 2, paymentFailureBody); + callback(null, { status: "Payment Failed" }); + } + + + + /////////////////////// PHONEPE INTEGRATION ////////////////////////////////// + + + + +} + + + +@Injectable() +export class phonepeGatewayService { + + constructor( + private readonly http: HttpService, + private paymentStatusRepo: PaymentStatusRepository, + private paymentMasterRepo: PaymentMasterRepository, + private phonepetxnRepo: PhonepeTransactionListRepository, + private crypto: CryptoService, + private authservice: AuthService, + private pcdUserRepo: PcduserRepository, + private tenderMasterRepo: TenderMasterRepository + + ) { } + + //merchantId:'PGTESTPAYUAT' + //key: '695d0547-3728-4b1c-825d-99647913361' + // keyIndex: 1 + + + async createOrder(body, user) { + console.log(body); + console.log(phonepeGatewayConf); + + let currentDate = new Date(); + let year = currentDate.getFullYear(); + let month = (currentDate.getMonth() + 1).toString().padStart(2, '0'); // Adding 1 because months are zero-based + let day = currentDate.getDate().toString().padStart(2, '0'); + let formattedDate = `${year}-${month}-${day}`; + let TxnId = Date.now().toString() + + let redirectUrl + + if (body.type == 'T') { + redirectUrl = phonepeGatewayConf.redirectUrlT + } else if (body.type == 'E') { + redirectUrl = phonepeGatewayConf.redirectUrlE + '/' + body.tenderId + } + + let callbackUrl = phonepeGatewayConf.callbackUrl + '/' + user.userId + '/' + body.tenderId + '/' + body.type + console.log("redirectUrl======,", callbackUrl); + let amount + if (phonepeGatewayConf.testing == true) { + amount = 100 + } else { + amount = body.amount * 100 + } + + const data = { + merchantId: phonepeGatewayConf.merchantId, + merchantTransactionId: TxnId, + merchantUserId: body.name, + amount: amount, + redirectUrl: redirectUrl, + redirectMode: "REDIRECT", + mobileNumber: body.mobile, + callbackUrl: callbackUrl, + paymentInstrument: { + type: "PAY_PAGE" + } + } + + console.log(data); + + const payload = JSON.stringify(data); + const payloadMain = Buffer.from(payload).toString('base64'); + let key = phonepeGatewayConf.salt + let index = phonepeGatewayConf.indexKey + // console.log("payloadMain========", payloadMain); + + const string = payloadMain + '/pg/v1/pay' + key + const sha256 = crypto.createHash('sha256').update(string).digest('hex') + + const checkSum = sha256 + '###' + index + // console.log("checkSum=========", checkSum); + + let url = phonepeGatewayConf.url + let response = '' + const decodedString = Buffer.from(response, 'base64').toString('utf-8'); + console.log("decodedString", decodedString); + + + const axios = require('axios'); + const options = { + method: 'POST', + url: url, + headers: { + accept: 'application/json', + 'Content-Type': 'application/json', + 'X-VERIFY': checkSum + }, + data: { + request: payloadMain + } + }; + let res = await axios + .request(options) + .then(function (response) { + console.log(response.data); + + + return response.data + }) + .catch(function (error) { + console.error(error); + + }); + let paymentStatus = new PaymentStatusDto + paymentStatus.amount = body.amount; + paymentStatus.txnid = parseInt(TxnId); + paymentStatus.mobile = user.mobileNumber; + paymentStatus.email = user.email; + paymentStatus.status = 'U'; + paymentStatus.paymentOption = 'P'; + paymentStatus.type = body.type; + paymentStatus.userId = user.userId + paymentStatus.tenderId = body.tenderId + paymentStatus.paymentDate = new Date(formattedDate); + console.log(paymentStatus); + await this.paymentStatusRepo.save(paymentStatus) + // this.paymentStatus(body.tenderId,user.userId,body.type) + return res + + } + // + async paymentStatus(req, res, tenderId, userId, type) { + // console.log("inside payment Status",res.req.body); + let keyIndex = phonepeGatewayConf.indexKey + let key = phonepeGatewayConf.salt + let response = res.req.body.response + const encoded = Buffer.from(response, 'base64').toString('utf-8'); + // console.log("decodedString",encoded); + const decodedString = JSON.parse(encoded); + let txnId = decodedString.data.merchantTransactionId + let merchantId = decodedString.data.merchantId + console.log("res=========", txnId, merchantId); + + // console.log("paymentStstus===",res.body); + let key1 = { + "keyIndex": keyIndex, + "key": key + } + + + + const string = '/pg/v1/status/' + merchantId + '/' + txnId + key + const sha256 = crypto.createHash('sha256').update(string).digest('hex') + + const checkSum = sha256 + '###' + keyIndex + console.log("checkSum=========", checkSum); + + let url = phonepeGatewayConf.statusUrl + '/' + merchantId + '/' + txnId + + const axios = require('axios'); + const options = { + method: 'get', + url: url, + headers: { + accept: 'application/json', + 'Content-Type': 'application/json', + 'X-VERIFY': checkSum, + 'X-MERCHANT-ID': merchantId + }, + + }; + let result = await axios + .request(options) + .then(function (response) { + console.log(response.data); + return response.data + }) + .catch(function (error) { + console.error(error); + }); + + + if (result.code == 'PAYMENT_SUCCESS') { + return this.paymentSuccess(result, tenderId, userId, type) + } else { + return this.paymentFailed(result, tenderId, userId) + } + } + async paymentSuccess(res, tenderId, userId, type) { + + let phonepeTrans = new phonepeTransactionDto + phonepeTrans.success = res.success + phonepeTrans.message = res.message + phonepeTrans.code = res.code + phonepeTrans.merchantId = res.data.merchantId + phonepeTrans.merchantTransactionId = res.data.merchantTransactionId + phonepeTrans.transactionId = res.data.transactionId + phonepeTrans.amount = res.data.amount / 100 + phonepeTrans.state = res.data.state + phonepeTrans.paymentType = res.data.paymentInstrument.type + phonepeTrans.txnDate = await this.newDate() + phonepeTrans.responseCode = res.data.responseCode + await this.phonepetxnRepo.save(phonepeTrans) + + let pamentStatus = await this.paymentStatusRepo.findOne({ where: { txnid: parseInt(res.data.merchantTransactionId) } }) + if (pamentStatus) { + pamentStatus.status = 'S' + await this.paymentStatusRepo.save(pamentStatus) + } + console.log("type=====", type); + + if (type == 'T') { + let paymentMaster = new PaymentMasterDto + paymentMaster.transId = parseInt(res.data.merchantTransactionId) + paymentMaster.userId = userId + paymentMaster.tenderId = tenderId + paymentMaster.notificationViewed = 'N' + paymentMaster.status = 'S' + console.log(paymentMaster); + + await this.paymentMasterRepo.save(paymentMaster) + }else if(type == 'E'){ + let paymentMaster = await this.paymentMasterRepo.findOne({where:{tenderId : tenderId , userId : userId}}) + if(paymentMaster){ + paymentMaster.emdFeetxnId = parseInt(res.data.merchantTransactionId) + paymentMaster.emdFeeType = 'PhonePe' + paymentMaster.emdFeeStatus = res.code + await this.paymentMasterRepo.save(paymentMaster) + } + + } + await this.sendPaymentEmail(userId, tenderId) + return { data: "Payment Success" } + + } + + async paymentFailed(res, tenderId, userId) { + + let phonepeTrans = new phonepeTransactionDto + phonepeTrans.success = res.success + phonepeTrans.message = res.message + phonepeTrans.code = res.code + phonepeTrans.merchantId = res.data.merchantId + phonepeTrans.merchantTransactionId = res.data.merchantTransactionId + phonepeTrans.transactionId = res.data.transactionId + phonepeTrans.amount = res.data.amount / 100 + phonepeTrans.state = res.data.state + phonepeTrans.paymentType = res.data.paymentInstrument.type ?? null + phonepeTrans.responseCode = res.data.responseCode ?? null + phonepeTrans.txnDate = await this.newDate() + + await this.phonepetxnRepo.save(phonepeTrans) + let pamentStatus = await this.paymentStatusRepo.findOne({ where: { txnid: parseInt(res.data.merchantTransactionId) } }) + if (pamentStatus) { + pamentStatus.status = 'F' + await this.paymentStatusRepo.save(pamentStatus) + } + + return { data: "Payment Failed" } + } + + async newDate() { + let currentDate = new Date(); + let year = currentDate.getFullYear(); + let month = (currentDate.getMonth() + 1).toString().padStart(2, '0'); + let day = currentDate.getDate().toString().padStart(2, '0'); + let formattedDate = `${year}-${month}-${day}`; + return new Date(formattedDate) + } + + async sendPaymentEmail(userId, tenderId) { + let user = await this.pcdUserRepo.findOne({ where: { userId: userId } }) + let tender = await this.tenderMasterRepo.findOne({ where: { id: tenderId } }) + let bidopenDAte = await this.formattedNewDate(tender.bidOpenDate) + + let body ={ + email : user.email, + custName : user.userName, + tenderName : tender.title, + bidOpenDate : bidopenDAte.toString() + } + console.log("mailbody=========",body); + + await this.authservice.sendOtp(body,'CP') + } + + async formattedNewDate(date) { + let currentDate = date + let year = currentDate.getFullYear(); + let month = (currentDate.getMonth() + 1).toString().padStart(2, '0'); + let day = currentDate.getDate().toString().padStart(2, '0'); + let formattedDate = `${day}/${month}/${year}`; + return new Date(formattedDate) + } + +} + + + + diff --git a/src/pipe/pcd-date.pipe.ts b/src/pipe/pcd-date.pipe.ts new file mode 100644 index 0000000..952dd50 --- /dev/null +++ b/src/pipe/pcd-date.pipe.ts @@ -0,0 +1,58 @@ +export function convertDate(date: Date, format?: string): Date { + if (!date || date.toString() == "" || date.toString() == "null") + return null; + + date = new Date(date); + if (!format) + format = "yyyy-MM-dd"; + let day = ('0' + date.getDate()).slice(-2); + let month = ('0' + (date.getMonth() + 1)).slice(-2); + let year = date.getFullYear(); + let hours = ('0' + date.getHours() || '00').slice(-2); + let minutes = ('0' + date.getMinutes() || '00').slice(-2); + let seconds = ('0' + date.getSeconds() || '00').slice(-2); + let stringDt = format; + if (format.includes("yyyy")) stringDt = stringDt.replace("yyyy", year.toString()); + if (format.includes("MM")) stringDt = stringDt.replace("MM", month.toString()); + if (format.includes("dd")) stringDt = stringDt.replace("dd", day.toString()); + if (format.includes("hh")) stringDt = stringDt.replace("hh", hours.toString()); + if (format.includes("mm")) stringDt = stringDt.replace("mm", minutes.toString()); + if (format.includes("ss")) stringDt = stringDt.replace("ss", seconds.toString()); + + let convDate = new Date(stringDt); + + return convDate; +} + +export function convertDateString(date: Date, format?: string): string { + if (!date || date.toString() == "null") + return null; + + date = new Date(date); + + if (!format) + format = "yyyy-MM-dd"; + let day = ('0' + date.getDate()).slice(-2); + let month = ('0' + (date.getMonth() + 1)).slice(-2); + let year = date.getFullYear(); + let hours = ('0' + date.getHours() || '00').slice(-2); + let minutes = ('0' + date.getMinutes() || '00').slice(-2); + let seconds = ('0' + date.getSeconds() || '00').slice(-2); + + let stringDt = format; + if (format.includes("yyyy")) stringDt = stringDt.replace("yyyy", year.toString()); + if (format.includes("MM")) stringDt = stringDt.replace("MM", month.toString()); + if (format.includes("dd")) stringDt = stringDt.replace("dd", day.toString()); + if (format.includes("hh")) stringDt = stringDt.replace("hh", hours.toString()); + if (format.includes("mm")) stringDt = stringDt.replace("mm", minutes.toString()); + if (format.includes("ss")) stringDt = stringDt.replace("ss", seconds.toString()); + if (format.includes("MON")) stringDt = stringDt.replace("MON", shortMonth[parseInt(month.toString()) - 1]); + if (format.includes("MONTH")) stringDt = stringDt.replace("MONTH", month[parseInt(month.toString()) - 1]); + + + return stringDt; +} + +const month = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"]; + +const shortMonth = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"]; \ No newline at end of file diff --git a/src/pipe/pcd-validate.pipe.ts b/src/pipe/pcd-validate.pipe.ts new file mode 100644 index 0000000..748e558 --- /dev/null +++ b/src/pipe/pcd-validate.pipe.ts @@ -0,0 +1,21 @@ +import { Injectable, ArgumentMetadata, BadRequestException, ValidationPipe, UnprocessableEntityException } from '@nestjs/common'; + +@Injectable() +export class IctValidateInputPipe extends ValidationPipe { + public async transform(value, metadata: ArgumentMetadata) { + try { + return await super.transform(value, metadata); + } catch (e) { + if (e instanceof BadRequestException) { + // throw new UnprocessableEntityException(this.handleError(e.message)); //commented after migration + let err: Object = e.getResponse(); + console.log("====err1====",err["message"]); + throw new UnprocessableEntityException(err["message"]); + } + } + } + + private handleError(errors) { + return errors.map(error => error.constraints); + } +} \ No newline at end of file diff --git a/src/tables/category/category.controller.ts b/src/tables/category/category.controller.ts new file mode 100644 index 0000000..6ea9c9c --- /dev/null +++ b/src/tables/category/category.controller.ts @@ -0,0 +1,17 @@ +import { Controller ,UseGuards} from '@nestjs/common'; +import { basicCategoryDto } from 'src/dto/basic-category.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { basicCategoryService } from './category.service'; +import { AuthGuard } from '@nestjs/passport'; + +@UseGuards(AuthGuard()) +@Controller('basic-category') +export class basicCategoryController extends PcdFormGridController { + + constructor( + private productCategoryService: basicCategoryService + ) { + super(productCategoryService); + } + +} diff --git a/src/tables/category/category.entity.ts b/src/tables/category/category.entity.ts new file mode 100644 index 0000000..132bab5 --- /dev/null +++ b/src/tables/category/category.entity.ts @@ -0,0 +1,24 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; +import { Column, Entity, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; + +@Entity("category") +export class Category extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"category", + type:"varchar", + nullable:true + }) + productCategory:string + + + + + @OneToMany(() => TenderMaster, (tenderMaster) => tenderMaster.tenderCategoryD ) + tenderMaster:TenderMaster[] +} \ No newline at end of file diff --git a/src/tables/category/category.module.ts b/src/tables/category/category.module.ts new file mode 100644 index 0000000..d8b54c8 --- /dev/null +++ b/src/tables/category/category.module.ts @@ -0,0 +1,18 @@ +import { Module } from '@nestjs/common'; +import { basicCategoryController } from './category.controller'; +import { basicCategoryService } from './category.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { basicCategoryRepository } from './category.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { Category } from './category.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Category]), + AuthModule + ], + controllers: [basicCategoryController], + providers: [basicCategoryService,basicCategoryRepository] +}) +export class basicCategoryModule {} + \ No newline at end of file diff --git a/src/tables/category/category.repository.ts b/src/tables/category/category.repository.ts new file mode 100644 index 0000000..18b2361 --- /dev/null +++ b/src/tables/category/category.repository.ts @@ -0,0 +1,11 @@ +import { DataSource, EntityRepository, Repository } from "typeorm"; +import { Category } from "./category.entity"; +import { Inject, Injectable } from "@nestjs/common"; +@Injectable() +export class basicCategoryRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(Category,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/category/category.service.ts b/src/tables/category/category.service.ts new file mode 100644 index 0000000..5b80504 --- /dev/null +++ b/src/tables/category/category.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { basicCategoryDto } from 'src/dto/basic-category.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { basicCategoryRepository } from './category.repository'; + +@Injectable() +export class basicCategoryService extends PcdFormGridService{ + + constructor( + @InjectRepository(basicCategoryRepository) + private basicCategoryRepository: basicCategoryRepository, + ) { + super(basicCategoryRepository); + } + +} diff --git a/src/tables/closed-tender-users/closed-tender-users.controller.ts b/src/tables/closed-tender-users/closed-tender-users.controller.ts new file mode 100644 index 0000000..30d2187 --- /dev/null +++ b/src/tables/closed-tender-users/closed-tender-users.controller.ts @@ -0,0 +1,28 @@ +import { Body, Controller, Post, UseGuards } from '@nestjs/common'; +import { closedTenderUsersDto } from 'src/dto/closed-tender-users.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { ClosedTenderUsersService } from './closed-tender-users.service'; +import { GetUser } from 'src/auth/dto/get-user.decorator'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { AuthGuard } from '@nestjs/passport'; + +@UseGuards(AuthGuard()) +@Controller('closed-tender-users') +export class ClosedTenderUsersController extends PcdFormGridController { + + constructor( + private ClosedTenderUsersService: ClosedTenderUsersService + ) { + super(ClosedTenderUsersService); + } + + @Post('users') + async closedTenderUsers( + @GetUser() user:PcduserDto, + @Body() body:any + ) { + return await this.ClosedTenderUsersService.closedTenderUsers(user,body) + } + +} + diff --git a/src/tables/closed-tender-users/closed-tender-users.entity.ts b/src/tables/closed-tender-users/closed-tender-users.entity.ts new file mode 100644 index 0000000..1370ab3 --- /dev/null +++ b/src/tables/closed-tender-users/closed-tender-users.entity.ts @@ -0,0 +1,36 @@ +import { Pcduser } from "src/auth/pcduser.entity"; +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { TenderMaster } from "../tender-master/tender-master.entity"; + +@Entity('closed-tender-users') +export class closedTenderUsers extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"tenderId", + type:"numeric", + nullable:true + }) + tenderId:number + + + @Column({ + name:"userId", + type:"numeric", + nullable:true + }) + userId:number + + @ManyToOne(() => Pcduser, (Pcduser) => Pcduser.closedTenderUsers, { eager: true }) + @JoinColumn([{ name: "userId", referencedColumnName: "userId" }]) + userD: Pcduser + + @ManyToOne(() => TenderMaster, (tenderMaster) => tenderMaster.closedTenderUsers, { eager: true }) + @JoinColumn([{ name: "tenderId", referencedColumnName: "id" }]) + tenderD: TenderMaster + +} \ No newline at end of file diff --git a/src/tables/closed-tender-users/closed-tender-users.module.ts b/src/tables/closed-tender-users/closed-tender-users.module.ts new file mode 100644 index 0000000..19ef43f --- /dev/null +++ b/src/tables/closed-tender-users/closed-tender-users.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { ClosedTenderUsersService } from './closed-tender-users.service'; +import { ClosedTenderUsersController } from './closed-tender-users.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { closedTenderUsers } from './closed-tender-users.entity'; +import { closedTenderUsersRepository } from './closed-tender-users.repository'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([closedTenderUsers]), + AuthModule + ], + providers: [ClosedTenderUsersService,closedTenderUsersRepository], + controllers: [ClosedTenderUsersController] +}) +export class ClosedTenderUsersModule {} diff --git a/src/tables/closed-tender-users/closed-tender-users.repository.ts b/src/tables/closed-tender-users/closed-tender-users.repository.ts new file mode 100644 index 0000000..b2c3b6e --- /dev/null +++ b/src/tables/closed-tender-users/closed-tender-users.repository.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { closedTenderUsers } from "./closed-tender-users.entity"; + +@Injectable() +export class closedTenderUsersRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(closedTenderUsers,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/closed-tender-users/closed-tender-users.service.ts b/src/tables/closed-tender-users/closed-tender-users.service.ts new file mode 100644 index 0000000..d1cc84c --- /dev/null +++ b/src/tables/closed-tender-users/closed-tender-users.service.ts @@ -0,0 +1,42 @@ +import { BadRequestException, Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { closedTenderUsersDto } from 'src/dto/closed-tender-users.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { closedTenderUsersRepository } from './closed-tender-users.repository'; + +@Injectable() +export class ClosedTenderUsersService extends PcdFormGridService{ + + constructor( + @InjectRepository(closedTenderUsersRepository) + private closedTenderUsersRepository: closedTenderUsersRepository, + ) { + super(closedTenderUsersRepository); + } + + + async closedTenderUsers(user, body) { + console.log("body", body[0].tenderId ); + + if (user.secuLevel == 'User') { + throw new BadRequestException('Saving data is restricted due to the absence of the necessary authorization or privilege.') + } + try { + await this.closedTenderUsersRepository.delete({ tenderId: body[0].tenderId }); + } catch (error) { + console.error("Error deleting data:", error); + } + for (let i of body) { + console.log(i); + + let closedUser = new closedTenderUsersDto + closedUser.userId = parseInt(i.userId) + closedUser.tenderId = i.tenderId + console.log("closedUser", closedUser); + + await this.closedTenderUsersRepository.save(closedUser) + } + return { msg: "Data Saved successfully" } + } + +} diff --git a/src/tables/common/common.controller.ts b/src/tables/common/common.controller.ts new file mode 100644 index 0000000..890b42a --- /dev/null +++ b/src/tables/common/common.controller.ts @@ -0,0 +1,16 @@ +import { Controller } from '@nestjs/common'; +import { CommonDto } from 'src/dto/common.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { CommonService } from './common.service'; + +@Controller('common') +export class CommonController extends PcdFormGridController{ + + constructor( + private commonService: CommonService + ) { + super(commonService); + } + +} + diff --git a/src/tables/common/common.entity.ts b/src/tables/common/common.entity.ts new file mode 100644 index 0000000..c3dc970 --- /dev/null +++ b/src/tables/common/common.entity.ts @@ -0,0 +1,21 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, EntityRepository, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('common') +export class Common extends PcdBaseEntity{ + + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:'marquee', + type:"varchar", + length:1000, + nullable:true + }) + marquee:string + +} \ No newline at end of file diff --git a/src/tables/common/common.module.ts b/src/tables/common/common.module.ts new file mode 100644 index 0000000..64ddc1f --- /dev/null +++ b/src/tables/common/common.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { CommonController } from './common.controller'; +import { CommonService } from './common.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { commonRepository } from './common.repository'; +import { Common } from './common.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Common]), + ], + controllers: [CommonController], + providers: [CommonService,commonRepository] +}) +export class CommonModule {} diff --git a/src/tables/common/common.repository.ts b/src/tables/common/common.repository.ts new file mode 100644 index 0000000..d759fe0 --- /dev/null +++ b/src/tables/common/common.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, Repository } from "typeorm"; +import { Common } from "./common.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class commonRepository extends Repository{ + constructor( + private datasource:DataSource + ){ + super(Common,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/common/common.service.ts b/src/tables/common/common.service.ts new file mode 100644 index 0000000..ae293b4 --- /dev/null +++ b/src/tables/common/common.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { Common } from './common.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { commonRepository } from './common.repository'; + +@Injectable() +export class CommonService extends PcdFormGridService{ + + constructor( + @InjectRepository(commonRepository) + private commonRepository: commonRepository, + ) { + super(commonRepository); + } + +} + diff --git a/src/tables/covers-lov/covers-lov.controller.ts b/src/tables/covers-lov/covers-lov.controller.ts new file mode 100644 index 0000000..041d343 --- /dev/null +++ b/src/tables/covers-lov/covers-lov.controller.ts @@ -0,0 +1,15 @@ +import { Controller } from '@nestjs/common'; +import { coverTypeDto } from 'src/dto/cover-type.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { CoversLovService } from './covers-lov.service'; + +@Controller('covers-lov') +export class CoversLovController extends PcdFormGridController{ + + constructor( + private coversLovService: CoversLovService + ) { + super(coversLovService); + } + +} diff --git a/src/tables/covers-lov/covers-lov.entity.ts b/src/tables/covers-lov/covers-lov.entity.ts new file mode 100644 index 0000000..177c27d --- /dev/null +++ b/src/tables/covers-lov/covers-lov.entity.ts @@ -0,0 +1,25 @@ +import { PcdBaseDto } from "src/framework/custom/pcd-dto.custom"; +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { CoverDoc } from "../covers-master/covers-master.entity"; + +@Entity('covers-lov') +export class CoversLov extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"covertype", + type:"varchar", + length:500, + nullable:true + }) + coverType:string + + @OneToMany(() => CoverDoc, (coverDoc) => coverDoc.coverTypeD ) + coverDoc:CoverDoc[] + +} diff --git a/src/tables/covers-lov/covers-lov.module.ts b/src/tables/covers-lov/covers-lov.module.ts new file mode 100644 index 0000000..4e602c7 --- /dev/null +++ b/src/tables/covers-lov/covers-lov.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; +import { CoversLovController } from './covers-lov.controller'; +import { CoversLovService } from './covers-lov.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { CoversLovRepository } from './covers-lov.repository'; +import { CoversLov } from './covers-lov.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([CoversLov]), + ], + controllers: [CoversLovController], + providers: [CoversLovService,CoversLovRepository] +}) +export class CoversLovModule {} diff --git a/src/tables/covers-lov/covers-lov.repository.ts b/src/tables/covers-lov/covers-lov.repository.ts new file mode 100644 index 0000000..16d7e2e --- /dev/null +++ b/src/tables/covers-lov/covers-lov.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, EntityRepository, Repository } from "typeorm"; +import { CoversLov } from "./covers-lov.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class CoversLovRepository extends Repository{ + constructor( + private datasource:DataSource + ){ + super(CoversLov ,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/covers-lov/covers-lov.service.ts b/src/tables/covers-lov/covers-lov.service.ts new file mode 100644 index 0000000..4d27518 --- /dev/null +++ b/src/tables/covers-lov/covers-lov.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { CoversLov } from './covers-lov.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { CoversLovRepository } from './covers-lov.repository'; + +@Injectable() +export class CoversLovService extends PcdFormGridService{ + + constructor( + @InjectRepository(CoversLovRepository) + private coversLovRepository: CoversLovRepository, + ) { + super(coversLovRepository); + } + +} diff --git a/src/tables/covers-master/covers-master.controller.ts b/src/tables/covers-master/covers-master.controller.ts new file mode 100644 index 0000000..fb396e9 --- /dev/null +++ b/src/tables/covers-master/covers-master.controller.ts @@ -0,0 +1,16 @@ +import { Controller } from '@nestjs/common'; +import { CoverMasterDto } from 'src/dto/cover-master.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { CoversMasterService } from './covers-master.service'; + +@Controller('covers-master') +export class CoversMasterController extends PcdFormGridController{ + + constructor( + private coversMasterService: CoversMasterService + ) { + super(coversMasterService); + } + +} + diff --git a/src/tables/covers-master/covers-master.entity.ts b/src/tables/covers-master/covers-master.entity.ts new file mode 100644 index 0000000..ae906fb --- /dev/null +++ b/src/tables/covers-master/covers-master.entity.ts @@ -0,0 +1,56 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { CoversLov } from "../covers-lov/covers-lov.entity"; +import { FileFormat } from "../file-format-lov/file-format-lov.entity"; + +@Entity('cover-doc-master') +export class CoverDoc extends PcdBaseEntity { + + @PrimaryGeneratedColumn({ + name: "id" + }) + id: number + @Column({ + name: "tender_id", + type: "numeric", + //length:500, + nullable: true + }) + tenderId: number + @Column({ + name: "cover_type", + type: "numeric", + + nullable: true + }) + coverType: string + @Column({ + name: "desc", + type: "varchar", + length: 500, + nullable: true + }) + Description: string + + @Column({ + name: "file_format", + type: "numeric", + + nullable: true + }) + fileFormat: string + + @ManyToOne(() => TenderMaster, (tenderMaster) => tenderMaster.coverDoc) + @JoinColumn([{ name: "tender_id", referencedColumnName: "id" }]) + tenderIdD: TenderMaster + + @ManyToOne(() => CoversLov, (coversLov) => coversLov.coverType, { eager: true }) + @JoinColumn([{ name: "cover_type", referencedColumnName: "id" }]) + coverTypeD: CoversLov + + @ManyToOne(() => FileFormat, (fileFormat) => fileFormat.fileFormat, { eager: true }) + @JoinColumn([{ name: "file_format", referencedColumnName: "id" }]) + fileFormatD: FileFormat + +} \ No newline at end of file diff --git a/src/tables/covers-master/covers-master.module.ts b/src/tables/covers-master/covers-master.module.ts new file mode 100644 index 0000000..3feb1e8 --- /dev/null +++ b/src/tables/covers-master/covers-master.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { CoversMasterService } from './covers-master.service'; +import { CoversMasterController } from './covers-master.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { CoverMasterRepository } from './covers-master.repository'; +import { CoverDoc } from './covers-master.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([CoverDoc]), + AuthModule + ], + providers: [CoversMasterService,CoverMasterRepository], + controllers: [CoversMasterController] +}) +export class CoversMasterModule {} diff --git a/src/tables/covers-master/covers-master.repository.ts b/src/tables/covers-master/covers-master.repository.ts new file mode 100644 index 0000000..68bd9dd --- /dev/null +++ b/src/tables/covers-master/covers-master.repository.ts @@ -0,0 +1,11 @@ + import { DataSource, Repository } from "typeorm"; + import { CoverDoc } from "./covers-master.entity"; + import { Injectable } from "@nestjs/common"; + + + @Injectable() + export class CoverMasterRepository extends Repository{ + constructor(private datasource : DataSource){ + super(CoverDoc, datasource.createEntityManager()); + } + } \ No newline at end of file diff --git a/src/tables/covers-master/covers-master.service.ts b/src/tables/covers-master/covers-master.service.ts new file mode 100644 index 0000000..afee31f --- /dev/null +++ b/src/tables/covers-master/covers-master.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { CoverMasterDto } from 'src/dto/cover-master.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { CoverMasterRepository } from './covers-master.repository'; + +@Injectable() +export class CoversMasterService extends PcdFormGridService{ + + constructor( + @InjectRepository(CoverMasterRepository) + private coverMasterRepository: CoverMasterRepository, + ) { + super(coverMasterRepository); + } + +} diff --git a/src/tables/document-type/document-type.controller.ts b/src/tables/document-type/document-type.controller.ts new file mode 100644 index 0000000..99005bc --- /dev/null +++ b/src/tables/document-type/document-type.controller.ts @@ -0,0 +1,18 @@ +import { Controller,UseGuards } from '@nestjs/common'; +import { DocumentTypeDto } from 'src/dto/document-type.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { DocumentTypeService } from './document-type.service'; +import { AuthGuard } from '@nestjs/passport'; + + +@UseGuards(AuthGuard()) +@Controller('document-type') +export class DocumentTypeController extends PcdFormGridController{ + + constructor( + private documentTypeService: DocumentTypeService + ) { + super(documentTypeService); + } + +} diff --git a/src/tables/document-type/document-type.entity.ts b/src/tables/document-type/document-type.entity.ts new file mode 100644 index 0000000..502bc63 --- /dev/null +++ b/src/tables/document-type/document-type.entity.ts @@ -0,0 +1,31 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { TenderDoc } from "../tender-documents/tender-doc.entity"; + +@Entity('document-type') +export class DocumentType extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"document-type", + type:"varchar", + length:500, + nullable:true + }) + documentType:string + + + @Column({ + name:"doc_category", + type:"varchar", + nullable:true + }) + docCategory:string + + + @OneToMany(() => TenderDoc, (tenderDoc) => tenderDoc.documentTypeD ) + tenderDoc:TenderDoc[] +} \ No newline at end of file diff --git a/src/tables/document-type/document-type.module.ts b/src/tables/document-type/document-type.module.ts new file mode 100644 index 0000000..8685359 --- /dev/null +++ b/src/tables/document-type/document-type.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { DocumentTypeController } from './document-type.controller'; +import { DocumentTypeService } from './document-type.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { DocumentTypeRepository } from './document-type.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { DocumentType } from './document-type.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([DocumentType]), + AuthModule + ], + controllers: [DocumentTypeController], + providers: [DocumentTypeService,DocumentTypeRepository] +}) +export class DocumentTypeModule {} diff --git a/src/tables/document-type/document-type.repository.ts b/src/tables/document-type/document-type.repository.ts new file mode 100644 index 0000000..53cca81 --- /dev/null +++ b/src/tables/document-type/document-type.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, EntityRepository, Repository } from "typeorm"; +import { DocumentType } from "./document-type.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class DocumentTypeRepository extends Repository{ + constructor( + private datasource : DataSource + ){ +super(DocumentType,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/document-type/document-type.service.ts b/src/tables/document-type/document-type.service.ts new file mode 100644 index 0000000..f686198 --- /dev/null +++ b/src/tables/document-type/document-type.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { DocumentTypeDto } from 'src/dto/document-type.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { DocumentTypeRepository } from './document-type.repository'; + +@Injectable() +export class DocumentTypeService extends PcdFormGridService{ + + constructor( + @InjectRepository(DocumentTypeRepository) + private documentTypeRepository: DocumentTypeRepository, + ) { + super(documentTypeRepository); + } + +} \ No newline at end of file diff --git a/src/tables/emd-fee-type/emd-fee-type.controller.ts b/src/tables/emd-fee-type/emd-fee-type.controller.ts new file mode 100644 index 0000000..31b6ebc --- /dev/null +++ b/src/tables/emd-fee-type/emd-fee-type.controller.ts @@ -0,0 +1,18 @@ +import { Controller,UseGuards } from '@nestjs/common'; +import { EmdFeeTypeDto } from 'src/dto/emd-fee-type.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { EmdFeeTypeService } from './emd-fee-type.service'; +import { AuthGuard } from '@nestjs/passport'; + + +@UseGuards(AuthGuard()) +@Controller('emd-fee-type') +export class EmdFeeTypeController extends PcdFormGridController{ + + constructor( + private emdFeeTypeService: EmdFeeTypeService + ) { + super(emdFeeTypeService); + } + +} diff --git a/src/tables/emd-fee-type/emd-fee-type.entity.ts b/src/tables/emd-fee-type/emd-fee-type.entity.ts new file mode 100644 index 0000000..c279392 --- /dev/null +++ b/src/tables/emd-fee-type/emd-fee-type.entity.ts @@ -0,0 +1,24 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('emd_fee_type') +export class EmdFeeType extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:'emd_fee_type', + type:'varchar', + length:500, + nullable:true + }) + emdFeeType:string + + @OneToMany(() => TenderMaster, (tenderMaster) => tenderMaster.emdFeeTypeD ) + tenderMaster:TenderMaster[] + +} \ No newline at end of file diff --git a/src/tables/emd-fee-type/emd-fee-type.module.ts b/src/tables/emd-fee-type/emd-fee-type.module.ts new file mode 100644 index 0000000..5c32545 --- /dev/null +++ b/src/tables/emd-fee-type/emd-fee-type.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { EmdFeeTypeController } from './emd-fee-type.controller'; +import { EmdFeeTypeService } from './emd-fee-type.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { EmdFeeTypeRepository } from './emd-fee-type.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { EmdFeeType } from './emd-fee-type.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([EmdFeeType]), + AuthModule +], + controllers: [EmdFeeTypeController], + providers: [EmdFeeTypeService,EmdFeeTypeRepository] +}) +export class EmdFeeTypeModule {} diff --git a/src/tables/emd-fee-type/emd-fee-type.repository.ts b/src/tables/emd-fee-type/emd-fee-type.repository.ts new file mode 100644 index 0000000..58be8a6 --- /dev/null +++ b/src/tables/emd-fee-type/emd-fee-type.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, EntityRepository, Repository } from "typeorm"; +import { EmdFeeType } from "./emd-fee-type.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class EmdFeeTypeRepository extends Repository{ +constructor( + private datasource : DataSource +){ + super(EmdFeeType , datasource.createEntityManager()); +} +} diff --git a/src/tables/emd-fee-type/emd-fee-type.service.ts b/src/tables/emd-fee-type/emd-fee-type.service.ts new file mode 100644 index 0000000..ec0099d --- /dev/null +++ b/src/tables/emd-fee-type/emd-fee-type.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { EmdFeeTypeDto } from 'src/dto/emd-fee-type.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { EmdFeeTypeRepository } from './emd-fee-type.repository'; + +@Injectable() +export class EmdFeeTypeService extends PcdFormGridService{ + + constructor( + @InjectRepository(EmdFeeTypeRepository) + private emdFeeTypeRepository: EmdFeeTypeRepository, + ) { + super(emdFeeTypeRepository); + } + +} diff --git a/src/tables/file-format-lov/file-format-lov.controller.ts b/src/tables/file-format-lov/file-format-lov.controller.ts new file mode 100644 index 0000000..19dacaa --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.controller.ts @@ -0,0 +1,17 @@ +import { Controller } from '@nestjs/common'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { FileFormatRepository } from './file-format-lov.repository'; +import { FileFormatLovDto } from 'src/dto/file-format-lov.dto'; +import { FileFormatLovService } from './file-format-lov.service'; + +@Controller('file-format-lov') +export class FileFormatLovController extends PcdFormGridController{ + + constructor( + private fileFormatLovService: FileFormatLovService + ) { + super(fileFormatLovService); + } + +} + diff --git a/src/tables/file-format-lov/file-format-lov.entity.ts b/src/tables/file-format-lov/file-format-lov.entity.ts new file mode 100644 index 0000000..5ac3b93 --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.entity.ts @@ -0,0 +1,22 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { CoverDoc } from "../covers-master/covers-master.entity"; + +@Entity('file-format') +export class FileFormat extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"file_format", + type:"varchar", + length:500, + nullable:true + }) + fileFormat:string + + @OneToMany(() => CoverDoc, (coverDoc) => coverDoc.fileFormatD ) + coverDoc:CoverDoc[] +} \ No newline at end of file diff --git a/src/tables/file-format-lov/file-format-lov.module.ts b/src/tables/file-format-lov/file-format-lov.module.ts new file mode 100644 index 0000000..fd6eb86 --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { FileFormatLovService } from './file-format-lov.service'; +import { FileFormatLovController } from './file-format-lov.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { FileFormatRepository } from './file-format-lov.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { FileFormat } from './file-format-lov.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([FileFormat]), + + ], + providers: [FileFormatLovService,FileFormatRepository], + controllers: [FileFormatLovController] +}) +export class FileFormatLovModule {} diff --git a/src/tables/file-format-lov/file-format-lov.repository.ts b/src/tables/file-format-lov/file-format-lov.repository.ts new file mode 100644 index 0000000..204dd0a --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.repository.ts @@ -0,0 +1,13 @@ +import { DataSource, Repository } from "typeorm"; +import { FileFormat } from "./file-format-lov.entity"; +import { Inject, Injectable } from "@nestjs/common"; + +@Injectable() +export class FileFormatRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(FileFormat , datasource.createEntityManager()) + } + +} \ No newline at end of file diff --git a/src/tables/file-format-lov/file-format-lov.service.ts b/src/tables/file-format-lov/file-format-lov.service.ts new file mode 100644 index 0000000..9c5c01e --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { FileFormatLovDto } from 'src/dto/file-format-lov.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { FileFormatRepository } from './file-format-lov.repository'; + +@Injectable() +export class FileFormatLovService extends PcdFormGridService{ + + constructor( + @InjectRepository(FileFormatRepository) + private fileFormatRepository: FileFormatRepository, + ) { + super(fileFormatRepository); + } + +} + diff --git a/src/tables/form-of-contract/form-of-contract.controller.ts b/src/tables/form-of-contract/form-of-contract.controller.ts new file mode 100644 index 0000000..dfad871 --- /dev/null +++ b/src/tables/form-of-contract/form-of-contract.controller.ts @@ -0,0 +1,15 @@ +import { Controller ,UseGuards} from '@nestjs/common'; +import { FormOfContractDto } from 'src/dto/form-of-contract.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { FormOfContractService } from './form-of-contract.service'; +import { AuthGuard } from '@nestjs/passport'; + + +@UseGuards(AuthGuard()) +@Controller('form-of-contract') +export class FormOfContractController extends PcdFormGridController { + constructor( + private formOfContractService: FormOfContractService + ) { + super(formOfContractService); + }} diff --git a/src/tables/form-of-contract/form-of-contract.entity.ts b/src/tables/form-of-contract/form-of-contract.entity.ts new file mode 100644 index 0000000..8dcb7a5 --- /dev/null +++ b/src/tables/form-of-contract/form-of-contract.entity.ts @@ -0,0 +1,24 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; +import { Column, Entity, OneToMany, PrimaryColumn, PrimaryColumnCannotBeNullableError, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('form_of_contract') +export class FormOfContract extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"form_of_contract", + type:"varchar", + length:500, + nullable:true + }) + formOfContract:string + + + @OneToMany(() => TenderMaster, (tenderMaster) => tenderMaster.formOfContractD ) + tenderMaster:TenderMaster[] +} \ No newline at end of file diff --git a/src/tables/form-of-contract/form-of-contract.module.ts b/src/tables/form-of-contract/form-of-contract.module.ts new file mode 100644 index 0000000..464967e --- /dev/null +++ b/src/tables/form-of-contract/form-of-contract.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { FormOfContractController } from './form-of-contract.controller'; +import { FormOfContractService } from './form-of-contract.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { FormOfContractRepository } from './form-of-contract.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { FormOfContract } from './form-of-contract.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([FormOfContract]), + AuthModule + ], + controllers: [FormOfContractController], + providers: [FormOfContractService,FormOfContractRepository] +}) +export class FormOfContractModule {} diff --git a/src/tables/form-of-contract/form-of-contract.repository.ts b/src/tables/form-of-contract/form-of-contract.repository.ts new file mode 100644 index 0000000..70c932f --- /dev/null +++ b/src/tables/form-of-contract/form-of-contract.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, Repository } from "typeorm"; +import { FormOfContract } from "./form-of-contract.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class FormOfContractRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(FormOfContract , datasource.createEntityManager()) + } +} \ No newline at end of file diff --git a/src/tables/form-of-contract/form-of-contract.service.ts b/src/tables/form-of-contract/form-of-contract.service.ts new file mode 100644 index 0000000..c13f8f2 --- /dev/null +++ b/src/tables/form-of-contract/form-of-contract.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { FormOfContractDto } from 'src/dto/form-of-contract.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { FormOfContractRepository } from './form-of-contract.repository'; + +@Injectable() +export class FormOfContractService extends PcdFormGridService { + constructor( + @InjectRepository(FormOfContractRepository) + private formOfContractRepository: FormOfContractRepository, + ) { + super(formOfContractRepository); + } + +} diff --git a/src/tables/gallery/gallery.controller.ts b/src/tables/gallery/gallery.controller.ts new file mode 100644 index 0000000..7b8fa01 --- /dev/null +++ b/src/tables/gallery/gallery.controller.ts @@ -0,0 +1,30 @@ +import { Controller, Get, Param, Req, Res } from '@nestjs/common'; +import { galleryDto } from 'src/dto/gallery.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { galleryService } from './gallery.service'; + +@Controller('gallery') +export class galleryController extends PcdFormGridController { + constructor( + private galleryService: galleryService + ) { + super(galleryService); + } + + @Get('image/:filename') + getUserDocuments( + @Param('filename') filename: string, + // @Param('id') id: string, + @Res() res, + @Req() req, + + ) { + return res.sendFile(filename, { root: './uploads/Pictures/'}, function (err) { + if (err) { + console.log(err.status); + res.status(err.status).end(); + } + }) + } + +} diff --git a/src/tables/gallery/gallery.entity.ts b/src/tables/gallery/gallery.entity.ts new file mode 100644 index 0000000..f85cfcd --- /dev/null +++ b/src/tables/gallery/gallery.entity.ts @@ -0,0 +1,64 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { subGallery } from "../sub-gallery/sub-gallery.entity"; + +@Entity('gallery') +export class gallery extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"category", + type:"varchar", + length:1000, + nullable:true + }) + category : string + + + @Column({ + name:"image_url", + type:"varchar", + length:1000, + nullable:true + }) + imageUrl : string + + + @Column({ + name:"title", + type:"varchar", + length:1000, + nullable:true + }) + title: string + + + @Column({ + name:"description", + type:"varchar", + length:1000, + nullable:true + }) + description:string + + + @Column({ + name:"project_type", + type:"varchar", + length:100, + }) + projectType:string + + + @OneToMany(() => subGallery, (subGallery) => subGallery.galleryD ) + subGallery:subGallery[] +} + + + + + diff --git a/src/tables/gallery/gallery.module.ts b/src/tables/gallery/gallery.module.ts new file mode 100644 index 0000000..e4f374e --- /dev/null +++ b/src/tables/gallery/gallery.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { galleryController } from './gallery.controller'; +import { galleryService } from './gallery.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { gallery } from './gallery.entity'; +import { galleryRepository } from './gallery.repository'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([galleryRepository]), + AuthModule + ], + controllers: [galleryController], + providers: [galleryService] +}) +export class galleryModule {} diff --git a/src/tables/gallery/gallery.repository.ts b/src/tables/gallery/gallery.repository.ts new file mode 100644 index 0000000..ae2e71f --- /dev/null +++ b/src/tables/gallery/gallery.repository.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { gallery } from "./gallery.entity"; + +@Injectable() +export class galleryRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(gallery , datasource.createEntityManager()) + } +} \ No newline at end of file diff --git a/src/tables/gallery/gallery.service.ts b/src/tables/gallery/gallery.service.ts new file mode 100644 index 0000000..063a0bd --- /dev/null +++ b/src/tables/gallery/gallery.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { galleryDto } from 'src/dto/gallery.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { galleryRepository } from './gallery.repository'; + +@Injectable() +export class galleryService extends PcdFormGridService { + constructor( + @InjectRepository(galleryRepository) + private galleryRepository: galleryRepository, + ) { + super(galleryRepository); + } + +} diff --git a/src/tables/payment-master/payment-master.controller.ts b/src/tables/payment-master/payment-master.controller.ts new file mode 100644 index 0000000..29a58ca --- /dev/null +++ b/src/tables/payment-master/payment-master.controller.ts @@ -0,0 +1,75 @@ +import { Controller, Get, Param, Post,Body,UseGuards } from '@nestjs/common'; +import { PaymentMasterDto } from 'src/dto/payment-master.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { PaymentMasterService } from './payment-master.service'; +import { AuthGuard } from '@nestjs/passport'; +import { GetUser } from 'src/auth/dto/get-user.decorator'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; + +@Controller('payment-master') +export class PaymentMasterController extends PcdFormGridController { + + constructor( + private paymentMasterService: PaymentMasterService + ){ + super(paymentMasterService); + } + + @UseGuards(AuthGuard()) + @Get('bid-report/:id') + async bidReport( + @Param('id') tenderId: string, + @GetUser() user: PcduserDto + ){ + return this.paymentMasterService.bidReport(tenderId, user) + } + + @Get('bid-payment-check/:userId/:tenderId') + async bidPaymentCheck( + @Param('userId') userId: string, + @Param('tenderId') tenderId : string + ){ + return this.paymentMasterService.bidPaymentCheck(tenderId ,userId) + } + + @Post('finalBidAmt/:userId/:tenderId') + async finalBidAmt( + @Body() body: { bidAmount : number , type?:string , tenderFee?:boolean}, + @Param('userId') userId: string, + @Param('tenderId') tenderId : string, + ){ + return this.paymentMasterService.finalBidAmt(tenderId ,userId , body) + } + + @Post('paymentInfo') + async paymentInfo( + @Body() paymentMasterDto : PaymentMasterDto + ){ + return this.paymentMasterService.paymentInfo(paymentMasterDto) + } + + @Get('userBidPaymentCheck/:userId/:tenderId') + async userBidPaymentCheck( + @Param('userId') userId: string, + @Param('tenderId') tenderId : string + ){ + return this.paymentMasterService.userBidPaymentCheck(tenderId ,userId) + } + + @Post('updatePaymentStatus/:userId/:tenderId') + async AdminUpdatePaymentStatus( + @Param('userId') userId: string, + @Param('tenderId') tenderId : string, + @Body() body: { status : string }, + ){ + return this.paymentMasterService.AdminUpdatePaymentStatus(userId,tenderId,body) +} + +@Get('notifications/:id') +async notificationMsg( + @Param('id') userId: string +){ + return this.paymentMasterService.notificationMsg(userId) +} + +} diff --git a/src/tables/payment-master/payment-master.entity.ts b/src/tables/payment-master/payment-master.entity.ts new file mode 100644 index 0000000..e70a05a --- /dev/null +++ b/src/tables/payment-master/payment-master.entity.ts @@ -0,0 +1,97 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { TenderMaster } from "../tender-master/tender-master.entity"; +import { Pcduser } from "src/auth/pcduser.entity"; + +@Entity('payment-master') +export class PaymentMaster extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"user_id", + type:"varchar", + nullable:true, + }) + userId:string + + @Column({ + name:"tender_id", + type:"numeric", + nullable:true, + }) + tenderId:number + + @Column({ + name:"trans_id", + type:"numeric", + nullable:true, + }) + transId:number + + @Column({ + name:"status", + type:"varchar", + nullable:true, + length:2 + }) + status:string + + @Column({ + name:"final_bid_amt", + type:"numeric", + nullable:true, + }) + finalBidAmt:number + + @Column({ + name:'notification_viewed', + type:"varchar", + length:1, + nullable:true + }) + notificationViewed:string + + @Column({ + name:"message", + type:"varchar", + length:2000, + nullable : true + }) + message:string + + @Column({ + name:"emd_fee_status", + type:"varchar", + length:2000, + nullable : true + }) + emdFeeStatus:string + + @Column({ + name:"emd_fee_txnid", + type:"numeric", + // length:2000, + nullable : true + }) + emdFeetxnId:number + + @Column({ + name:"emd_fee_type", + type:"varchar", + length:2000, + nullable : true + }) + emdFeeType:string + + @ManyToOne(() => Pcduser, (pcduser) => pcduser.paymentMaster, { eager: true }) + @JoinColumn([{ name: "user_id", referencedColumnName: "userId" }]) + pcduserD: Pcduser + + @ManyToOne(() => TenderMaster, (tenderMaster) => tenderMaster.paymentMaster, ) + @JoinColumn([{ name: "tender_id", referencedColumnName: "id" }]) + tenderMasterD: TenderMaster + +} \ No newline at end of file diff --git a/src/tables/payment-master/payment-master.module.ts b/src/tables/payment-master/payment-master.module.ts new file mode 100644 index 0000000..ac1576a --- /dev/null +++ b/src/tables/payment-master/payment-master.module.ts @@ -0,0 +1,19 @@ +import { Module } from '@nestjs/common'; +import { PaymentMasterController } from './payment-master.controller'; +import { PaymentMasterService } from './payment-master.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { PaymentMasterRepository } from './payment-master.repository'; +import { PaymentMaster } from './payment-master.entity'; +import { tenderDocRepository } from '../tender-documents/tender-doc.repository'; +import { TenderDoc } from '../tender-documents/tender-doc.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([PaymentMaster,TenderDoc]), + AuthModule + ], + controllers: [PaymentMasterController], + providers: [PaymentMasterService,PaymentMasterRepository,tenderDocRepository] +}) +export class PaymentMasterModule {} diff --git a/src/tables/payment-master/payment-master.repository.ts b/src/tables/payment-master/payment-master.repository.ts new file mode 100644 index 0000000..a537904 --- /dev/null +++ b/src/tables/payment-master/payment-master.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, Repository } from "typeorm"; +import { PaymentMaster } from "./payment-master.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class PaymentMasterRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(PaymentMaster , datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/payment-master/payment-master.service.ts b/src/tables/payment-master/payment-master.service.ts new file mode 100644 index 0000000..15f9431 --- /dev/null +++ b/src/tables/payment-master/payment-master.service.ts @@ -0,0 +1,173 @@ +import { Injectable, BadRequestException, NotFoundException, UnauthorizedException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { PaymentMasterDto } from 'src/dto/payment-master.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { PaymentMasterRepository } from './payment-master.repository'; +import { response } from 'express'; +import { log } from 'console'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { tenderDocRepository } from '../tender-documents/tender-doc.repository'; + + +@Injectable() +export class PaymentMasterService extends PcdFormGridService{ + + constructor( + @InjectRepository(PaymentMasterRepository) + private paymentMasterRepository: PaymentMasterRepository, + private tenderdocRepo: tenderDocRepository + ) { + super(paymentMasterRepository); + } + + async bidReport(tenderId, user: PcduserDto) { + + if (user.secuLevel === 'SuperAdmin' || user.secuLevel === 'Admin') { + let id = tenderId.toString() + + let query = `SELECT + "PaymentMaster"."id" AS "id", + "PaymentMaster"."user_id" AS "userId", "PaymentMaster"."tender_id" AS "tenderId", + "PaymentMaster"."trans_id" AS "transId", "PaymentMaster"."status" AS "status", + "PaymentMaster"."final_bid_amt" AS "finalBidAmt", + "PaymentMaster_pcduserD"."user_name" AS "userName", + "PaymentMaster_pcduserD"."email" AS "email", + "PaymentMaster_pcduserD"."mobile_number" AS "mobileNumber", + "PaymentMaster"."emd_fee_status" AS "emdFeeStatus", + "PaymentMaster"."emd_fee_txnid" AS "emdFeeTxnId", + "PaymentMaster"."emd_fee_type" AS "emdFeeType" + FROM "payment-master" "PaymentMaster" + LEFT JOIN "pcduser" "PaymentMaster_pcduserD" ON + "PaymentMaster_pcduserD"."user_id"="PaymentMaster"."user_id" + WHERE "PaymentMaster"."tender_id"= ${id}` + let report = await this.paymentMasterRepository.query(query) + for (let r of report) { + let DD = await this.tenderdocRepo.findOne({ + where: { + tenderId: tenderId, userId: r.userId, documentCategory: "DD" + } + }) + r.DDFile = DD + } + let countStatusP = report.filter(item => item.status === 'P').length; + + return { report, countStatusP }; + } + else { + throw new UnauthorizedException('You have no right to View Report..') + } + + } + + async bidPaymentCheck(tenderId, userId) { + let query = `SELECT "PaymentMaster"."id" AS "id", + "PaymentMaster"."user_id" AS "userId", "PaymentMaster"."tender_id" AS "tenderId", + "PaymentMaster"."trans_id" AS "transId", "PaymentMaster"."status" AS "status", + "PaymentMaster_pcduserD"."user_name" AS "userName", + "PaymentMaster_pcduserD"."email" AS "email", + "PaymentMaster_pcduserD"."mobile_number" AS "mobileNumber" + FROM "payment-master" "PaymentMaster" LEFT JOIN "pcduser" "PaymentMaster_pcduserD" ON + "PaymentMaster_pcduserD"."user_id"="PaymentMaster"."user_id" WHERE "PaymentMaster"."tender_id"= ${tenderId} and "PaymentMaster"."user_id"= '${userId}' + and "PaymentMaster"."status"='S' ` + let report = await this.paymentMasterRepository.query(query) + + return report; + + } + + async finalBidAmt(tenderId, userId, body) { + console.log(body); + + let user = await this.paymentMasterRepository.findOne({ where: { tenderId: tenderId, userId: userId } }); + if (!user && body.tenderFee == true) { + throw new BadRequestException('User Details not found') + } + if (user) { + if (user.finalBidAmt == null) { + user.finalBidAmt = body.bidAmount; + console.log(body.type); + + if (body.type) + user.emdFeeType = body.type + + this.paymentMasterRepository.save(user) + return { data: "Final Bid Amount Successfully Saved" } + } else { + throw new BadRequestException('Bid Amount Already Exist') + } + } + if (!user && body.tenderFee == false) { + let user = new PaymentMasterDto() + user.userId = userId + user.tenderId = tenderId + user.finalBidAmt = body.bidAmount + user.status = 'S' + if (body.type) + user.emdFeeType = body.type + await this.paymentMasterRepository.save(user) + } + } + + async paymentInfo(paymentMasterDto) { + try { + console.log(paymentMasterDto); + const res = await this.paymentMasterRepository.save(paymentMasterDto); + return { data: "Payment Saved Successfully" }; + } catch (err) { + return { data: "Error while saving data" }; + } + } + + + async userBidPaymentCheck(tenderId, userId) { + let query = `SELECT "PaymentMaster"."id" AS "id", + "PaymentMaster"."user_id" AS "userId", "PaymentMaster"."tender_id" AS "tenderId", + "PaymentMaster"."trans_id" AS "transId", "PaymentMaster"."status" AS "status", + "PaymentMaster".emd_fee_type AS "emdFeeType", + "PaymentMaster".emd_fee_status AS "emdFeeStatus", "PaymentMaster".emd_fee_txnid AS "emdFeeTxnId", + "PaymentMaster_pcduserD"."user_name" AS "userName", + "PaymentMaster_pcduserD"."email" AS "email", + "PaymentMaster_pcduserD"."mobile_number" AS "mobileNumber" FROM "payment-master" "PaymentMaster" LEFT JOIN "pcduser" "PaymentMaster_pcduserD" ON + "PaymentMaster_pcduserD"."user_id"="PaymentMaster"."user_id" WHERE "PaymentMaster"."tender_id"= ${tenderId} and "PaymentMaster"."user_id"= '${userId}'` + + let report = await this.paymentMasterRepository.query(query) + if (report.length === 0) { + throw new NotFoundException("User Payment Not Found") + } + return report; + } + + async AdminUpdatePaymentStatus(userId, tenderId, body) { + try { + let user = await this.paymentMasterRepository.findOne({ where: { userId: userId, tenderId: tenderId } }) + console.log(user); + + user.status = body.status; + user.message = body.message; + user.notificationViewed = body.notificationViewed; + let result = await this.paymentMasterRepository.save(user); + return { data: "Payment Status Updated Successfully" } + } catch (err) { + console.log(err); + return { data: "Error in Payment Status Updation" } + } + } + + + async notificationMsg(id) { + + let query = `SELECT status , message ,tm.title "title" + FROM "payment-master" pm + LEFT JOIN tender_master tm ON tm.id = pm.tender_id + WHERE user_id = '${id}' + AND notification_viewed = 'N';` + + let users = await this.paymentMasterRepository.query(query); + + this.paymentMasterRepository.update({ notificationViewed: "N", userId: id }, { notificationViewed: "Y" }) + + return users + } + +} + diff --git a/src/tables/payment-mode/payment-mode.controller.ts b/src/tables/payment-mode/payment-mode.controller.ts new file mode 100644 index 0000000..c8243a4 --- /dev/null +++ b/src/tables/payment-mode/payment-mode.controller.ts @@ -0,0 +1,18 @@ +import { Controller,UseGuards } from '@nestjs/common'; +import { PaymentModeDto } from 'src/dto/payment-mode.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { PaymentModeService } from './payment-mode.service'; +import { AuthGuard } from '@nestjs/passport'; + + +@UseGuards(AuthGuard()) +@Controller('payment-mode') +export class PaymentModeController extends PcdFormGridController { + + constructor( + private paymentModeService: PaymentModeService + ) { + super(paymentModeService); + } + +} diff --git a/src/tables/payment-mode/payment-mode.entity.ts b/src/tables/payment-mode/payment-mode.entity.ts new file mode 100644 index 0000000..b6b1d25 --- /dev/null +++ b/src/tables/payment-mode/payment-mode.entity.ts @@ -0,0 +1,24 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('payment-mode') +export class PaymentMode extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"payment_mode", + type:"varchar", + nullable:true + }) + paymentMode:string + + @OneToMany(() => TenderMaster, (tenderMaster) => tenderMaster.paymentModeD ) + tenderMaster:TenderMaster[] + + +} \ No newline at end of file diff --git a/src/tables/payment-mode/payment-mode.module.ts b/src/tables/payment-mode/payment-mode.module.ts new file mode 100644 index 0000000..dc6580b --- /dev/null +++ b/src/tables/payment-mode/payment-mode.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { PaymentModeController } from './payment-mode.controller'; +import { PaymentModeService } from './payment-mode.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { PaymentModeRepository } from './payment-mode.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { PaymentMode } from './payment-mode.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([PaymentMode]), + AuthModule + ], + controllers: [PaymentModeController], + providers: [PaymentModeService,PaymentModeRepository] +}) +export class PaymentModeModule {} diff --git a/src/tables/payment-mode/payment-mode.repository.ts b/src/tables/payment-mode/payment-mode.repository.ts new file mode 100644 index 0000000..2d9532b --- /dev/null +++ b/src/tables/payment-mode/payment-mode.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, Repository } from "typeorm"; +import { PaymentMode } from "./payment-mode.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class PaymentModeRepository extends Repository{ + constructor( + private dataSource:DataSource + ){ + super(PaymentMode,dataSource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/payment-mode/payment-mode.service.ts b/src/tables/payment-mode/payment-mode.service.ts new file mode 100644 index 0000000..4351286 --- /dev/null +++ b/src/tables/payment-mode/payment-mode.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { PaymentModeDto } from 'src/dto/payment-mode.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { PaymentModeRepository } from './payment-mode.repository'; + +@Injectable() +export class PaymentModeService extends PcdFormGridService{ + + constructor( + @InjectRepository(PaymentModeRepository) + private paymentModeRepository: PaymentModeRepository, + ) { + super(paymentModeRepository); + } +} diff --git a/src/tables/payment-status/payment-status.controller.ts b/src/tables/payment-status/payment-status.controller.ts new file mode 100644 index 0000000..2ff254a --- /dev/null +++ b/src/tables/payment-status/payment-status.controller.ts @@ -0,0 +1,15 @@ +import { Controller, UseGuards } from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; +import { PaymentStatusDto } from 'src/dto/payment-status.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { PaymentStatusService } from './payment-status.service'; + +@UseGuards(AuthGuard()) +@Controller('payment-status') +export class PaymentStatusController extends PcdFormGridController{ + constructor( + private iservice: PaymentStatusService + ) { + super(iservice); + } +} \ No newline at end of file diff --git a/src/tables/payment-status/payment-status.entity.ts b/src/tables/payment-status/payment-status.entity.ts new file mode 100644 index 0000000..3c17080 --- /dev/null +++ b/src/tables/payment-status/payment-status.entity.ts @@ -0,0 +1,190 @@ +import { Pcduser } from "src/auth/pcduser.entity"; +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { TenderMaster } from "../tender-master/tender-master.entity"; + + +@Entity("payment_status") +export class PaymentStatus extends PcdBaseEntity { + @PrimaryGeneratedColumn({ + name: "id", + }) + id: number; + + @Column({ + name: "payment_date", + type: "date", + nullable: true + }) + paymentDate: Date; + + @Column({ + name: 'payment_option', + type: 'char', + length: 1, + nullable: true + }) + paymentOption: string; + + @Column({ + name: 'payment_card_details', + type: 'varchar', + length: 500, + nullable: true + }) + paymentCardDetails: string; + + @Column({ + name: 'status', + type: 'char', + length: 1, + nullable: true + }) + status: string; + + @Column({ + name: 'type', + type: 'char', + length: 1, + nullable: true + }) + type: string; + + @Column({ + name: 'email', + type: 'varchar', + length: 500, + nullable: true + }) + email: string; + + @Column({ + name: 'mobile', + type: 'varchar', + length: 100, + nullable: true + }) + mobile: string; + + @Column({ + name: 'application', + type: 'numeric', + nullable: true + }) + application: number; + + + // @ManyToOne(type => SisAdmissionForm, sisAdmissionForm => sisAdmissionForm.paymentStatus) + // @JoinColumn({ name: 'application', referencedColumnName: 'id' }) + // applicationD: SisAdmissionForm; + + @Column({ + name: 'payment_id', + type: 'numeric', + nullable: true + }) + paymentId: number; + + // @ManyToOne(type => SisFeePaymentOnline, sisFeePaymentOnline => sisFeePaymentOnline.paymentStatus) + // @JoinColumn({ name: 'payment_id', referencedColumnName: 'id' }) + // paymentIdD: SisFeePaymentOnline; + + @Column({ + name: 'billing_address_1', + type: 'varchar', + length: 100, + nullable: true + }) + billingAddress1: string; + + @Column({ + name: 'billing_address_2', + type: 'varchar', + length: 100, + nullable: true + }) + billingAddress2: string; + + @Column({ + name: 'billing_address_3', + type: 'varchar', + length: 100, + nullable: true + }) + billingAddress3: string; + + @Column({ + name: 'billing_address_4', + type: 'varchar', + length: 100, + nullable: true + }) + billingAddress4: string; + + @Column({ + name: 'amount', + type: 'numeric', + precision: 18, + scale: 3, + nullable: true + }) + amount: number; + + + @Column({ + name: 'remarks', + type: 'varchar', + length: 1000, + nullable: true + }) + remarks: string; + + + @Column({ + name: 'txnid', + type: 'numeric', + nullable: false + }) + txnid: number; + + @Column({ + name: 'txnrefid', + type: 'varchar', + nullable: true, + length: 100 + }) + txnrefid: string; + + @Column({ + name: 'retry_count', + type: 'numeric', + default: () => "(0)" + }) + retryCount: number; + + @Column({ + name:"user_id", + type:"varchar", + nullable:true, + }) + userId : string + + @Column({ + name:"tender_id", + type:"numeric", + nullable:true + }) + tenderId : number + + @Column("varchar", { name: "identifier", nullable: true, length: 1 }) + identifier: string; + + @ManyToOne(() => Pcduser, (pcduser) => pcduser.paymentStatusD, { eager: false }) + @JoinColumn([{ name: "userId", referencedColumnName: "userId" }]) + userD: Pcduser + + @ManyToOne(() => TenderMaster, (tenderMaster) => tenderMaster.paymentStatusD, { eager: false }) + @JoinColumn([{ name: "tenderId", referencedColumnName: "id" }]) + tenderMaster: Pcduser + +} \ No newline at end of file diff --git a/src/tables/payment-status/payment-status.module.ts b/src/tables/payment-status/payment-status.module.ts new file mode 100644 index 0000000..ec4766c --- /dev/null +++ b/src/tables/payment-status/payment-status.module.ts @@ -0,0 +1,19 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { PaymentStatusController } from './payment-status.controller'; +import { PaymentStatusRepository } from './payment-status.repository'; +import { PaymentStatusService } from './payment-status.service'; +import { PaymentStatus } from './payment-status.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([ + PaymentStatus + ]), + AuthModule + ], + controllers: [PaymentStatusController], + providers: [PaymentStatusService,PaymentStatusRepository] +}) +export class PaymentStatusModule { } diff --git a/src/tables/payment-status/payment-status.repository.ts b/src/tables/payment-status/payment-status.repository.ts new file mode 100644 index 0000000..ae9a189 --- /dev/null +++ b/src/tables/payment-status/payment-status.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, Repository } from "typeorm"; +import { PaymentStatus } from "./payment-status.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class PaymentStatusRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(PaymentStatus,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/payment-status/payment-status.service.ts b/src/tables/payment-status/payment-status.service.ts new file mode 100644 index 0000000..963bc7b --- /dev/null +++ b/src/tables/payment-status/payment-status.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { PaymentStatusDto } from 'src/dto/payment-status.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { PaymentStatusRepository } from './payment-status.repository'; + +@Injectable() +export class PaymentStatusService extends PcdFormGridService{ + MANDATORY_FEILDS: string[] = []; + DUPLICATE_CHK: string[] = []; + MAIN_KEY = 'id' + constructor( + @InjectRepository(PaymentStatusRepository) + private paymentStatusRepository: PaymentStatusRepository, + ) { + super(paymentStatusRepository); + } +} diff --git a/src/tables/payu-transaction-list/payu-transaction-list.controller.ts b/src/tables/payu-transaction-list/payu-transaction-list.controller.ts new file mode 100644 index 0000000..8e8532e --- /dev/null +++ b/src/tables/payu-transaction-list/payu-transaction-list.controller.ts @@ -0,0 +1,37 @@ +import { Body, Controller, Get, Post, Query, UseGuards } from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; +import { GetUser } from 'src/auth/dto/get-user.decorator'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { PayuTransactionListDto } from 'src/dto/payu-transaction-list.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { FindManyOptions } from 'typeorm'; +import { PayuTransactionListService } from './payu-transaction-list.service'; + +@UseGuards(AuthGuard()) +@Controller('payu-transaction-list') +export class PayuTransactionListController extends PcdFormGridController{ + constructor( + private PayuTransactionListservice: PayuTransactionListService + ) { + super(PayuTransactionListservice); + } + @Post('get-transaction') + getTransactionDetails( + @Body() body: PcduserDto, + @GetUser() user: PcduserDto): Promise { + + return this.PayuTransactionListservice.getTransactionDetails(body); + } + + @Get('date-filter') + dateFilter(@Query() filter: FindManyOptions) { + + return this.PayuTransactionListservice.dateFilter(filter) + } + + @Get('check-status') + checkPaymentStatus(): Promise { + + return this.PayuTransactionListservice.checkPaymentStatus(); + } +} diff --git a/src/tables/payu-transaction-list/payu-transaction-list.entity.ts b/src/tables/payu-transaction-list/payu-transaction-list.entity.ts new file mode 100644 index 0000000..7b0f6b1 --- /dev/null +++ b/src/tables/payu-transaction-list/payu-transaction-list.entity.ts @@ -0,0 +1,362 @@ +// import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from "typeorm" + +@Entity('payu_transaction') +export class PayuTransactionListEntity extends BaseEntity { + + @PrimaryGeneratedColumn({ + name: 'id', + }) + sisId: string; + + @Column({ + type: 'varchar', + name: 'payu_id', + }) + id: string + + @Column({ + type: 'varchar', + name: 'status', + nullable: true, + + + }) + status: string; + + @Column({ + type: 'varchar', + name: 'key', + nullable: true + }) + key: string + + @Column({ + type: 'varchar', + name: 'merchantname', + nullable: true + }) + merchantname: string + + @Column({ + type: 'varchar', + name: 'firstName', + nullable: true + }) + firstname: string + + @Column({ + type: 'varchar', + name: 'lastname', + nullable: true + }) + lastname: string + + @Column({ + type: 'varchar', + name: 'addedon', + nullable: true + }) + addedon: Date + + @Column({ + type: 'varchar', + name: 'bank_name', + nullable: true + }) + bank_name: string + + @Column({ + type: 'varchar', + name: 'payment_gateway', + nullable: true + }) + payment_gateway: string + + @Column({ + type: 'varchar', + name: 'phone', + nullable: true + }) + phone: string + + @Column({ + type: 'varchar', + name: 'email', + nullable: true + }) + email: string + + @Column({ + type: 'varchar', + name: 'transaction_fee', + nullable: true + }) + transaction_fee: number + + @Column({ + type: 'varchar', + name: 'amount', + nullable: true + }) + amount: string + + @Column({ + type: 'varchar', + name: 'discount', + nullable: true + }) + discount: string + + @Column({ + type: 'varchar', + name: 'additional_charges', + nullable: true + }) + additional_charges: string + + @Column({ + type: 'varchar', + name: 'productinfo', + nullable: true + }) + productinfo: string + + @Column({ + type: 'varchar', + name: 'error_code', + nullable: true + }) + error_code: string + + @Column({ + type: 'varchar', + name: 'bank_ref_no', + nullable: true + }) + bank_ref_no: string + + @Column({ + type: 'varchar', + name: 'ibibo_code', + nullable: true + }) + ibibo_code: string + + @Column({ + type: 'varchar', + name: 'mode', + nullable: true + }) + mode: string + + @Column({ + type: 'varchar', + name: 'ip', + nullable: true + }) + ip: string + + @Column({ + type: 'varchar', + name: 'card_no', + nullable: true + }) + card_no: string + + @Column({ + type: 'varchar', + name: 'cardtype', + nullable: true + }) + cardtype: string + + @Column({ + type: 'varchar', + name: 'offer_key', + nullable: true + }) + offer_key: string + + @Column({ + type: 'varchar', + name: 'field0', + nullable: true + }) + field0: string + + @Column({ + type: 'varchar', + name: 'field1', + nullable: true + }) + field1: string + + @Column({ + type: 'varchar', + name: 'field2', + nullable: true + }) + field2: string + + @Column({ + type: 'varchar', + name: 'field3', + nullable: true + }) + field3: string + + @Column({ + type: 'varchar', + name: 'field4', + nullable: true + }) + field4: string + + @Column({ + type: 'varchar', + name: 'field5', + nullable: true + }) + field5: string + + @Column({ + type: 'varchar', + name: 'field6', + nullable: true + }) + field6: string + + @Column({ + type: 'varchar', + name: 'field7', + nullable: true + }) + field7: string + + @Column({ + type: 'varchar', + name: 'field8', + nullable: true + }) + field8: string + + @Column({ + type: 'varchar', + name: 'field9', + nullable: true + }) + field9: string + + @Column({ + type: 'varchar', + name: 'udf1', + nullable: true + }) + udf1: string + + @Column({ + type: 'varchar', + name: 'udf2', + nullable: true + }) + udf2: string + + @Column({ + type: 'varchar', + name: 'udf3', + nullable: true + }) + udf3: string + + @Column({ + type: 'varchar', + name: 'udf4', + nullable: true + }) + udf4: string + + @Column({ + type: 'varchar', + name: 'udf5', + nullable: true + }) + udf5: string + + @Column({ + type: 'varchar', + name: 'address2', + nullable: true + }) + address2: string + + @Column({ + type: 'varchar', + name: 'city', + nullable: true + }) + city: string + + @Column({ + type: 'varchar', + name: 'zipcode', + nullable: true + }) + zipcode: string + + @Column({ + type: 'varchar', + name: 'pg_mid', + nullable: true + }) + pg_mid: string + + @Column({ + type: 'varchar', + name: 'issuing_bank', + nullable: true + }) + issuing_bank: string + + @Column({ + type: 'varchar', + name: 'offer_type', + nullable: true + }) + offer_type: string + + @Column({ + type: 'varchar', + name: 'failure_reason', + nullable: true + }) + failure_reason: string + + @Column({ + type: 'varchar', + name: 'mer_service_fee', + nullable: true + }) + mer_service_fee: string + + @Column({ + type: 'varchar', + name: 'mer_service_tax', + nullable: true + }) + mer_service_tax: string + + @Column({ + type: 'varchar', + name: 'txnid', + nullable: true + }) + txnid: string + + @Column({ + type: 'varchar', + name: 'gateway', + nullable: true + }) + gateway: string; +} \ No newline at end of file diff --git a/src/tables/payu-transaction-list/payu-transaction-list.module.ts b/src/tables/payu-transaction-list/payu-transaction-list.module.ts new file mode 100644 index 0000000..f38cbf4 --- /dev/null +++ b/src/tables/payu-transaction-list/payu-transaction-list.module.ts @@ -0,0 +1,22 @@ +import { Module } from '@nestjs/common'; +import { PayuTransactionListService } from './payu-transaction-list.service'; +import { PayuTransactionListController } from './payu-transaction-list.controller'; +import { PayuTransactionListRepository } from './payu-transaction-list.repository'; +import { PcduserRepository } from 'src/auth/pcduser.repository'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { HttpModule} from '@nestjs/axios'; +import { PayuTransactionListEntity } from './payu-transaction-list.entity'; +@Module({ + imports: [ + TypeOrmModule.forFeature([ + PayuTransactionListEntity + ]), + AuthModule, + HttpModule + ], + providers: [PayuTransactionListService,PayuTransactionListRepository], + controllers: [PayuTransactionListController], + exports: [PayuTransactionListService] +}) +export class PayuTransactionListModule { } diff --git a/src/tables/payu-transaction-list/payu-transaction-list.repository.ts b/src/tables/payu-transaction-list/payu-transaction-list.repository.ts new file mode 100644 index 0000000..c736f09 --- /dev/null +++ b/src/tables/payu-transaction-list/payu-transaction-list.repository.ts @@ -0,0 +1,13 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { DataSource, EntityRepository, Repository } from "typeorm"; +import { PayuTransactionListEntity } from "./payu-transaction-list.entity"; + +@Injectable() +export class PayuTransactionListRepository extends Repository{ + constructor( + private datasource:DataSource + ){ + super(PayuTransactionListEntity,datasource.createEntityManager()); + } + private logger = new Logger ("SisPayuTransactionListRepository"); +} \ No newline at end of file diff --git a/src/tables/payu-transaction-list/payu-transaction-list.service.ts b/src/tables/payu-transaction-list/payu-transaction-list.service.ts new file mode 100644 index 0000000..6fe575e --- /dev/null +++ b/src/tables/payu-transaction-list/payu-transaction-list.service.ts @@ -0,0 +1,131 @@ +import { Body, Injectable } from '@nestjs/common'; +import { Cron } from '@nestjs/schedule'; +import { InjectRepository } from '@nestjs/typeorm'; +import * as config from 'config'; +// import { sha512 } from 'js-sha512'; +import { of } from 'rxjs'; +import { PayuTransactionListDto } from 'src/dto/payu-transaction-list.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { convertDateString } from 'src/pipe/pcd-date.pipe'; +import { FindManyOptions, In } from 'typeorm'; +import { PayuTransactionListRepository } from './payu-transaction-list.repository'; +import { sha512 } from 'js-sha512'; +import { HttpService } from '@nestjs/axios'; + + +@Injectable() +export class PayuTransactionListService extends PcdFormGridService{ + constructor( + @InjectRepository(PayuTransactionListRepository) + private PayuTransactionListRepository: PayuTransactionListRepository, + private readonly http: HttpService + ) { + super(PayuTransactionListRepository); + } + @Cron('* 55 23 * * *') + async handleCron() { + let date = new Date(); + const DateString = convertDateString(date, "yyyy-MM-dd"); + + await this.getTransactionDetails({ var1: DateString, var2: DateString, isSave: true }); + + } + async getTransactionDetails(body: any) { + const command = "get_Transaction_Details" + const key = config.get('payment-gateway').key + const salt = config.get('payment-gateway').salt + const var1 = body.var1 + const var2 = body.var2 + const sha = key + '|' + command + '|' + var1 + '|' + salt + const hash = sha512(sha); + const url = 'https://info.payu.in/merchant/postservice?form=2' + + let postData = { + "key": key, + "salt": salt, + "var1": var1, + "var2": var2, + "hash": hash, + "command": command + + } + console.log(postData); + + let Data = new URLSearchParams(postData).toString(); + const data: any = await this.http.post(url, Data).toPromise().then((res) => { + console.log("===res====", res.data); + return res.data; + }, (err) => { + console.log("===errr====", err); + return err; + }); + // console.log(data.Transaction_details); + + if (body.isSave && data?.Transaction_details) { + console.log('cron started'); + + for (let row of data.Transaction_details) { + let existing = await this.PayuTransactionListRepository.findOne({ where: { id: row.id } }) + if (!existing) { + row.gateway = 'PayU' + await this.PayuTransactionListRepository.save(row); + }else{ + row.gateway = 'PayU' + await this.PayuTransactionListRepository.update( { id: row.id },row); + } + } + this.PayuTransactionListRepository.query(`DELETE FROM + sis_payu_transaction a + USING sis_payu_transaction b + WHERE + a.id > b.id + AND a.payu_id = b.payu_id`) + console.log('completed'); + + } + return data; + + } + //fromDate and toDate filter + async dateFilter(filter: FindManyOptions) { + console.log("dateFilter", filter) + const date = await this.PayuTransactionListRepository.query(`select * from sis_payu_transaction spt where spt.addedon between '${filter.where['fromDate']}' and '${filter.where['toDate']}'`) + return date; + } + + @Cron('0 */2 * * *') + async checkPaymentStatus() { + + const payments = await this.PayuTransactionListRepository.find({ where: { status: In(['initiated', 'in progress']) } }) + for (let row of payments) { + const command = "verify_payment" + const key = config.get('payment-gateway').key + const salt = config.get('payment-gateway').salt + const var1 = row.txnid; + const sha = key + '|' + command + '|' + var1 + '|' + salt + const hash = sha512(sha); + const url = 'https://info.payu.in/merchant/postservice?form=2' + + let postData = { + "key": key, + "salt": salt, + "var1": var1, + "hash": hash, + "command": command + + } + let Data = new URLSearchParams(postData).toString(); + const data: any = await this.http.post(url, Data).toPromise().then(async (res) => { + if (res.data.status = 1) { + if (res.data.transaction_details[var1].status) { + row.status = res.data.transaction_details[var1].status + this.PayuTransactionListRepository.save(row) + } + } + }) + } + + } + + +} diff --git a/src/tables/phonepe-transaction-list/phonepe-transaction-list.controller.ts b/src/tables/phonepe-transaction-list/phonepe-transaction-list.controller.ts new file mode 100644 index 0000000..eecbcaa --- /dev/null +++ b/src/tables/phonepe-transaction-list/phonepe-transaction-list.controller.ts @@ -0,0 +1,19 @@ +import { Controller, Get } from '@nestjs/common'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { PhonepeTransactionListService } from './phonepe-transaction-list.service'; +import { phonepeTransactionDto } from 'src/dto/phonepeTransaction.dto'; + +@Controller('phonepe-transaction-list') +export class PhonepeTransactionListController extends PcdFormGridController{ + constructor( + private phonepeTransactionListService: PhonepeTransactionListService + ) { + super(phonepeTransactionListService); + } + + @Get('failed-payment') + async statusCheck(){ + return await this.phonepeTransactionListService.phonepeFailedPayment() + } + +} diff --git a/src/tables/phonepe-transaction-list/phonepe-transaction-list.entity.ts b/src/tables/phonepe-transaction-list/phonepe-transaction-list.entity.ts new file mode 100644 index 0000000..0620dd9 --- /dev/null +++ b/src/tables/phonepe-transaction-list/phonepe-transaction-list.entity.ts @@ -0,0 +1,93 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('phonepe-transaction-list') +export class phonepeTransactionList { + @PrimaryGeneratedColumn({ + name: 'id', + }) + id: string; + + @Column({ + name: "merchantId", + type: "varchar", + nullable: true, + length: 1000 + }) + merchantId: string + + @Column({ + name: "merchantTransactionId", + type: "numeric", + nullable: true + }) + merchantTransactionId: number + + @Column({ + name: "transactionId", + type: "varchar", + nullable: true, + length: 1000 + }) + transactionId: string + + @Column({ + name:"amount", + type: "numeric", + nullable: true + }) +amount: number + +@Column({ + name: "code", + type: "varchar", + nullable: true, + length: 1000 +}) +code: string + +@Column({ + name: "message", + type: "varchar", + nullable: true, + length: 1000 +}) +message: string + +@Column({ + name: "state", + type: "varchar", + nullable: true, + length: 1000 +}) +state: string + +@Column({ + name: "responseCode", + type: "varchar", + nullable: true, + length: 1000 +}) +responseCode: string + +@Column({ + name: "paymentType", + type: "varchar", + nullable: true, + length: 1000 +}) +paymentType: string + +@Column({ + name: "success", + type: "boolean", +}) +success: boolean + +@Column({ + name:"txnDate", + type:"date", + nullable:true +}) +txnDate:Date +} diff --git a/src/tables/phonepe-transaction-list/phonepe-transaction-list.module.ts b/src/tables/phonepe-transaction-list/phonepe-transaction-list.module.ts new file mode 100644 index 0000000..00af550 --- /dev/null +++ b/src/tables/phonepe-transaction-list/phonepe-transaction-list.module.ts @@ -0,0 +1,22 @@ +import { Module } from '@nestjs/common'; +import { PhonepeTransactionListController } from './phonepe-transaction-list.controller'; +import { PhonepeTransactionListService } from './phonepe-transaction-list.service'; +import { phonepeTransactionList } from './phonepe-transaction-list.entity'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { PhonepeTransactionListRepository } from './phonepe-transaction-list.repository'; +import { PaymentStatusRepository } from '../payment-status/payment-status.repository'; +import { PaymentStatus } from '../payment-status/payment-status.entity'; +import { PaymentMasterRepository } from '../payment-master/payment-master.repository'; +import { PaymentMaster } from '../payment-master/payment-master.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([ + phonepeTransactionList,PaymentStatus,PaymentMaster + ]), AuthModule], + controllers: [PhonepeTransactionListController], + providers: [PhonepeTransactionListService,PhonepeTransactionListRepository, + PaymentStatusRepository,PaymentMasterRepository] +}) +export class PhonepeTransactionListModule {} diff --git a/src/tables/phonepe-transaction-list/phonepe-transaction-list.repository.ts b/src/tables/phonepe-transaction-list/phonepe-transaction-list.repository.ts new file mode 100644 index 0000000..c9f351e --- /dev/null +++ b/src/tables/phonepe-transaction-list/phonepe-transaction-list.repository.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { phonepeTransactionList } from "./phonepe-transaction-list.entity"; + +@Injectable() +export class PhonepeTransactionListRepository extends Repository{ + constructor( + private datasource:DataSource + ){ + super(phonepeTransactionList,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/phonepe-transaction-list/phonepe-transaction-list.service.ts b/src/tables/phonepe-transaction-list/phonepe-transaction-list.service.ts new file mode 100644 index 0000000..adac1f5 --- /dev/null +++ b/src/tables/phonepe-transaction-list/phonepe-transaction-list.service.ts @@ -0,0 +1,153 @@ +import { Get, Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { PhonepeTransactionListRepository } from './phonepe-transaction-list.repository'; +import { phonepeTransactionDto } from 'src/dto/phonepeTransaction.dto'; +import { PaymentStatusRepository } from '../payment-status/payment-status.repository'; +import { In } from 'typeorm'; +import * as config from 'config'; +import { PaymentMasterRepository } from '../payment-master/payment-master.repository'; +import { PaymentMasterDto } from 'src/dto/payment-master.dto'; +import { Cron } from '@nestjs/schedule'; +var crypto = require('crypto') + +const phonepeGatewayConf = config.get('phonepe-gateway') + +@Injectable() +export class PhonepeTransactionListService extends PcdFormGridService{ + constructor( + @InjectRepository(PhonepeTransactionListRepository) + private phonepeTransactionListRepository: PhonepeTransactionListRepository, + private paymentStatusRepo: PaymentStatusRepository, + private paymentMasterRepo: PaymentMasterRepository + ) { + super(phonepeTransactionListRepository); + } + + //@Cron('* * * * *') + @Cron('*/10 * * * *') + async handleCron() { + await this.phonepeFailedPayment() + console.log("Cron Payment Check"); + } + + + async phonepeFailedPayment() { + const currentDate = new Date(); + const formattedCurrentDate = formatDate(currentDate); + + let failedPayments = await this.paymentStatusRepo.find({ + where: { + status: In(['U', 'F']), paymentDate: new Date(formattedCurrentDate) + } + }) + + for (let payments of failedPayments) { + let txnId = payments.txnid + let merchantId = phonepeGatewayConf.merchantId + let keyIndex = phonepeGatewayConf.indexKey + let key = phonepeGatewayConf.salt + let key1 = { + "keyIndex": keyIndex, + "key": key + } + + + + const string = '/pg/v1/status/' + merchantId + '/' + txnId + key + const sha256 = crypto.createHash('sha256').update(string).digest('hex') + + const checkSum = sha256 + '###' + keyIndex + console.log("checkSum=========", checkSum); + + let url = phonepeGatewayConf.statusUrl + '/' + merchantId + '/' + txnId + + const axios = require('axios'); + const options = { + method: 'get', + url: url, + headers: { + accept: 'application/json', + 'Content-Type': 'application/json', + 'X-VERIFY': checkSum, + 'X-MERCHANT-ID': merchantId + }, + + }; + let result = await axios + .request(options) + .then(function (response) { + console.log(response.data); + return response.data + }) + .catch(function (error) { + console.error(error); + }); + + console.log('1234', result.data['state']); + + if (result.success == true && result.code == 'PAYMENT_SUCCESS') { + let phonepeTxnStatus = await this.phonepeTransactionListRepository.findOne({ + where: { + merchantTransactionId: txnId + } + }) + if(phonepeTxnStatus){ + phonepeTxnStatus.code = result.code + phonepeTxnStatus.message = result.message + phonepeTxnStatus.state = result.data['state'] + phonepeTxnStatus.responseCode = result.data['responseCode'] + phonepeTxnStatus.success = result.success + await this.phonepeTransactionListRepository.save(phonepeTxnStatus) + } + + + let paymentStatus = await this.paymentStatusRepo.findOne({ + where: { + txnid: txnId + } + }) + if(paymentStatus){ + paymentStatus.status = 'S' + await this.paymentStatusRepo.save(paymentStatus) + } + + + if (paymentStatus.type == 'T') { + let paymentMaster = new PaymentMasterDto + paymentMaster.transId = paymentStatus.txnid + paymentMaster.userId = paymentStatus.userId + paymentMaster.tenderId = paymentStatus.tenderId + paymentMaster.notificationViewed = 'N' + paymentMaster.status = 'S' + console.log(paymentMaster); + + await this.paymentMasterRepo.save(paymentMaster) + } else if (paymentStatus.type == 'E') { + let paymentMaster = await this.paymentMasterRepo.findOne({ where: { tenderId: paymentStatus.tenderId, userId: paymentStatus.userId } }) + if (paymentMaster) { + paymentMaster.emdFeetxnId = paymentStatus.txnid + paymentMaster.emdFeeType = 'PhonePe' + paymentMaster.emdFeeStatus = result.code + await this.paymentMasterRepo.save(paymentMaster) + } + + } + + + } + + } + + } + + +} + +function formatDate(date: Date): string { + const year = date.getFullYear(); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const day = date.getDate().toString().padStart(2, '0'); + + return `${year}-${month}-${day}`; +} \ No newline at end of file diff --git a/src/tables/report-authentication/report-authentication.controller.ts b/src/tables/report-authentication/report-authentication.controller.ts new file mode 100644 index 0000000..2c7e2bd --- /dev/null +++ b/src/tables/report-authentication/report-authentication.controller.ts @@ -0,0 +1,30 @@ +import { Controller, Post, Body, UseInterceptors, UploadedFile, UseGuards } from '@nestjs/common'; +import { reportAuthenticationDto } from 'src/dto/report-authentication.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { ReportAuthenticationService } from './report-authentication.service'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { AuthGuard } from '@nestjs/passport'; + + +@UseGuards(AuthGuard()) +@Controller('report-authentication') +export class ReportAuthenticationController extends PcdFormGridController { + + constructor( + private reportAuthenticationService: ReportAuthenticationService + ) { + super(reportAuthenticationService); + } + + + @Post('upload-certificate') + @UseInterceptors(FileInterceptor('certificate')) + async uploadCertificate( + @UploadedFile() certificate, + @Body() body: { adminUser: string } + ): Promise { + + return this.reportAuthenticationService.verifyAdmin(certificate, body.adminUser); + } + +} diff --git a/src/tables/report-authentication/report-authentication.entity.ts b/src/tables/report-authentication/report-authentication.entity.ts new file mode 100644 index 0000000..73f17af --- /dev/null +++ b/src/tables/report-authentication/report-authentication.entity.ts @@ -0,0 +1,26 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('report-authentication') +export class reportAuthenticationEntity extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:'admin_users', + type:"varchar", + length:50, + nullable:true + }) + adminUsers:string + + @Column({ + type: 'json', + nullable: true, + }) + key: number[]; + +} \ No newline at end of file diff --git a/src/tables/report-authentication/report-authentication.module.ts b/src/tables/report-authentication/report-authentication.module.ts new file mode 100644 index 0000000..14e10b4 --- /dev/null +++ b/src/tables/report-authentication/report-authentication.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { ReportAuthenticationController } from './report-authentication.controller'; +import { ReportAuthenticationService } from './report-authentication.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { reportAuthenticationEntity } from './report-authentication.entity'; +import { reportAuthenticationRepository } from './report-authentication.repository'; +import { AuthModule } from 'src/auth/auth.module'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([reportAuthenticationEntity]), + AuthModule + ], + controllers: [ReportAuthenticationController], + providers: [ReportAuthenticationService,reportAuthenticationRepository] +}) +export class ReportAuthenticationModule {} diff --git a/src/tables/report-authentication/report-authentication.repository.ts b/src/tables/report-authentication/report-authentication.repository.ts new file mode 100644 index 0000000..8c818d9 --- /dev/null +++ b/src/tables/report-authentication/report-authentication.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, Repository } from "typeorm"; +import { reportAuthenticationEntity } from "./report-authentication.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class reportAuthenticationRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(reportAuthenticationEntity,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/report-authentication/report-authentication.service.ts b/src/tables/report-authentication/report-authentication.service.ts new file mode 100644 index 0000000..819ee8c --- /dev/null +++ b/src/tables/report-authentication/report-authentication.service.ts @@ -0,0 +1,58 @@ +import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { reportAuthenticationDto } from 'src/dto/report-authentication.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { reportAuthenticationRepository } from './report-authentication.repository'; +import * as fs from 'fs'; +import * as forge from 'node-forge'; + + +@Injectable() +export class ReportAuthenticationService extends PcdFormGridService{ + + constructor( + @InjectRepository(reportAuthenticationRepository) + private reportAuthenticationRepository: reportAuthenticationRepository, + ) { + super(reportAuthenticationRepository); + } + + async verifyAdmin(certificate, adminUser) { + + const binaryData = certificate.buffer.toString('base64'); + const pemCert = `-----BEGIN CERTIFICATE-----\n${binaryData}\n-----END CERTIFICATE-----`; + const cert = forge.pki.certificateFromPem(pemCert); + let validFrom = cert.validity.notBefore + let validTo = cert.validity.notAfter + let date = new Date() + + const user = await this.reportAuthenticationRepository.findOne({ + where: { id: adminUser } + }); + + //Uncomment when we want to add a new public key + + // console.log(cert.publicKey.n.data); + // user.adminUsers = cert.publicKey.n.data; + // this.reportAuthenticationRepository.save(user); + + if (!user) { + throw new BadRequestException('Admin User not found'); + } + + let certKey = cert.publicKey.n.data.toString() + let userKey = user.key.toString() + + if (certKey !== userKey) { + throw new BadRequestException('Key Not Matching. Please Try Again'); + } else if (validTo < date) { + throw new UnauthorizedException("Digital Signature Expired") + } + else { + return { message: 'Authentication Successfully Completed'}; + } + } +} + + + diff --git a/src/tables/revised-tender/revised-tender.controller.ts b/src/tables/revised-tender/revised-tender.controller.ts new file mode 100644 index 0000000..876f7a4 --- /dev/null +++ b/src/tables/revised-tender/revised-tender.controller.ts @@ -0,0 +1,49 @@ +import { Body, Controller, Get, Param, Post, UseGuards } from '@nestjs/common'; +import { revisedTenderDto } from 'src/dto/revised-tender.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { RevisedTenderService } from './revised-tender.service'; +import { AuthGuard } from '@nestjs/passport'; +import { GetUser } from 'src/auth/dto/get-user.decorator'; +import { PcdBaseDto } from 'src/framework/custom/pcd-dto.custom'; + +@UseGuards(AuthGuard()) +@Controller('revised-tender') +export class RevisedTenderController extends PcdFormGridController { + + constructor( + private RevisedTenderService: RevisedTenderService + ) { + super(RevisedTenderService); + } + + @Get('users/:tenderId') + async getUsers( + @Param('tenderId') tenderId : number , + @GetUser() user : PcdBaseDto + ){ + return await this.RevisedTenderService.getUsers(tenderId,user) + } + + @Post() + async saveRevisedTender( + @Body() body:any + ){ + return await this.RevisedTenderService.saveRevisedTender(body) + } + + @Post('document-upload') + async documentUpload( + @Body() body:{tenderId : number , revisedDocument : string , requotedOrder : number}, + @GetUser() user : PcdBaseDto + ){ + return await this.RevisedTenderService.documentUpload(body , user) + } + + @Get('report/:tenderId') + async requotedReport( + @Param('tenderId') tenderId : number, + @GetUser() user : PcdBaseDto + ){ + return await this.RevisedTenderService.requotedReport(tenderId,user) + } +} diff --git a/src/tables/revised-tender/revised-tender.entity.ts b/src/tables/revised-tender/revised-tender.entity.ts new file mode 100644 index 0000000..6d1585c --- /dev/null +++ b/src/tables/revised-tender/revised-tender.entity.ts @@ -0,0 +1,49 @@ +import { Pcduser } from "src/auth/pcduser.entity"; +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { TenderMaster } from "../tender-master/tender-master.entity"; + +@Entity('revised_tender') +export class revisedTender extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"user_id", + type:"varchar", + nullable:false + }) + userId : string + + @Column({ + name:"tender_id", + type:"numeric", + nullable:false + }) + tenderId : number + + @Column({ + name:"revised_document", + type:"varchar", + nullable:true + }) + revisedDocument : string + + @Column({ + name:"requoted_order", + type:"numeric", + nullable:false + }) + requotedOrder : number + + @ManyToOne(() => Pcduser, (pcduser) => pcduser.revisedTenderD, { eager: true }) + @JoinColumn([{ name: "user_id", referencedColumnName: "userId" }]) + userD: Pcduser + + @ManyToOne(() => TenderMaster, (tenderMaster) => tenderMaster.revisedTenderD, { eager: true }) + @JoinColumn([{ name: "tender_id", referencedColumnName: "id" }]) + revisedTenderD: TenderMaster +} \ No newline at end of file diff --git a/src/tables/revised-tender/revised-tender.module.ts b/src/tables/revised-tender/revised-tender.module.ts new file mode 100644 index 0000000..3e2e984 --- /dev/null +++ b/src/tables/revised-tender/revised-tender.module.ts @@ -0,0 +1,29 @@ +import { Module } from '@nestjs/common'; +import { RevisedTenderController } from './revised-tender.controller'; +import { RevisedTenderService } from './revised-tender.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { reportAuthenticationEntity } from '../report-authentication/report-authentication.entity'; +import { AuthModule } from 'src/auth/auth.module'; +import { revisedTender } from './revised-tender.entity'; +import { revisedTenderRepository } from './revised-tender.repository'; +import { PcduserRepository } from 'src/auth/pcduser.repository'; +import { EmailService } from 'src/email/email.service'; +import { TenderMasterRepository } from '../tender-master/tender-master.repository'; +import { PaymentMasterRepository } from '../payment-master/payment-master.repository'; +import { tenderSubCategoryMasterRepository } from '../tender-subcategory-master/tender-subcategory-master.repository'; +import { tenderSubCategoryRepository } from '../tender-subcategory/tender-subcategory.repository'; +import { categoryRepository } from '../userCategory-master/category.repository'; +import { closedTenderUsersRepository } from '../closed-tender-users/closed-tender-users.repository'; +import { userSubCategoryMasterRepo } from '../user-subcategory-master/user-subcategory-master.repository'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([revisedTender]), + AuthModule + ], + controllers: [RevisedTenderController], + providers: [RevisedTenderService,revisedTenderRepository,PcduserRepository,EmailService,TenderMasterRepository, + PaymentMasterRepository,tenderSubCategoryMasterRepository,tenderSubCategoryRepository, + categoryRepository,closedTenderUsersRepository,userSubCategoryMasterRepo] +}) +export class RevisedTenderModule {} diff --git a/src/tables/revised-tender/revised-tender.repository.ts b/src/tables/revised-tender/revised-tender.repository.ts new file mode 100644 index 0000000..fe62424 --- /dev/null +++ b/src/tables/revised-tender/revised-tender.repository.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { revisedTender } from "./revised-tender.entity"; + +@Injectable() +export class revisedTenderRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(revisedTender,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/revised-tender/revised-tender.service.ts b/src/tables/revised-tender/revised-tender.service.ts new file mode 100644 index 0000000..00a4624 --- /dev/null +++ b/src/tables/revised-tender/revised-tender.service.ts @@ -0,0 +1,275 @@ +import { BadGatewayException, BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { revisedTenderDto } from 'src/dto/revised-tender.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { revisedTenderRepository } from './revised-tender.repository'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { PcduserRepository } from 'src/auth/pcduser.repository'; +import { EmailService } from 'src/email/email.service'; +import { TenderMasterRepository } from '../tender-master/tender-master.repository'; +import { log } from 'console'; +import { PaymentMasterRepository } from '../payment-master/payment-master.repository'; + +@Injectable() +export class RevisedTenderService extends PcdFormGridService{ + + constructor( + @InjectRepository(revisedTenderRepository) + private revisedTenderRepository: revisedTenderRepository, + private pcdUserRepo: PcduserRepository, + private emailService: EmailService, + private tenderMasterRepo: TenderMasterRepository, + private paymentmasterRepo: PaymentMasterRepository + ) { + super(revisedTenderRepository); + } + + async getUsers(tenderId, user) { + if (user.secuLevel === 'SuperAdmin' || user.secuLevel === 'Admin') { + + let revisedTender = await this.revisedTenderRepository.find({ + where: { + tenderId: tenderId + } + }) + + if (revisedTender && revisedTender.length > 0) { + let users = await this.paymentmasterRepo.query(` + SELECT * + FROM revised_tender rt + WHERE tender_id = ${tenderId} + ORDER BY rt.requoted_order DESC + `) + let finalQuotedUsers = await this.paymentmasterRepo.query(` + select + rt.user_id as "userId", + p.user_name as "userName" , + p.mobile_number as "mobile" , + p.email as "email" , rt.requoted_order as "requotedOrder" + FROM revised_tender rt + left join pcduser p on p.user_id = rt.user_id + WHERE requoted_order = ${users[0].requoted_order} + and tender_id = ${tenderId}`) + + return finalQuotedUsers + + } else { + let users = await this.paymentmasterRepo.query(` + select pm.user_id as "userId", + p.user_name as "userName" , + p.mobile_number as "mobile" , + p.email as "email", + 0 AS "requotedOrder" + from "payment-master" pm + left join pcduser p on p.user_id = pm.user_id + where pm.tender_id = '${tenderId}' + `) + return users + } + } else { + throw new UnauthorizedException('You have no right to Requoted users..') + } + } + + async saveRevisedTender(body) { + let email = [] + let requotedOrder = body[0].requotedOrder + for (let u of body) { + let revisedUserDto = new revisedTenderDto() + revisedUserDto.userId = u.userId + revisedUserDto.tenderId = u.tenderId + revisedUserDto.requotedOrder = u.requotedOrder + await this.revisedTenderRepository.save(revisedUserDto) + email.push(u.email) + } + let t = await this.tenderMasterRepo.findOne({ where: { id: body[0]['tenderId'] } }) + let date = new Date() + let deadLine = new Date(date.getTime() + 7 * 24 * 60 * 60 * 1000); // Adds one week + let dd = String(deadLine.getDate()).padStart(2, '0'); // Day + let mm = String(deadLine.getMonth() + 1).padStart(2, '0'); // Month (add 1 because January is 0) + let yy = deadLine.getFullYear().toString(); // Las + let formattedDate = `${dd}-${mm}-${yy}`; + console.log(formattedDate); + + let subject = `Notification to Retender` + let content = ` + + + + + OTP + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
 
+ + logo + +

Artnouveau Architects

+
 
+ + + + + + + + + + +
 
+ +

+ Dear Customer ,
+ We are pleasure to inform you that the tender process for the project ${t.title} has been reopened. We kindly request you to submit your revised proposals . + Please click here to upload your document. +

+ Once again, we appreciate your prompt payment and cooperation. We look forward to receiving your document submission.
+ Thank you for your participation.

+ For any inquiries or clarifications, please contact

+ +
+ +

+ +
+

Name:Subash

+

Email: subash@artnouveau.in

+

Phone: +91 94469 64558

+
+
+ +
+

Name:Boncy

+

Email: boncy@artnouveau.in

+

Phone: +91 85473 42848

+
+
+
+
+ Best regards,
+ Artnouveau Architects

+ + +
 
+
 
+

© www.artnouveau.in

+
 
+
+ + + + ` + + await this.emailService.sendMailManually(email, subject, content, content) + return { data: "Data Saved Successfully" } + + } + + + async documentUpload(body, user) { + let revisedTender = await this.revisedTenderRepository.findOne({ + where: { + userId: user.userId, + tenderId: body.tenderId, + requotedOrder : body.requotedOrder + } + }) + if (!revisedTender) { + throw new BadRequestException("No revised tenders are available for you.") + } + + if (revisedTender.revisedDocument && revisedTender.revisedDocument != '') { + throw new BadRequestException('Document Already Uploaded.') + } + + //To validate without time zone + let date = await this.dateFormat(revisedTender.createdDate); + let after7days = new Date(date); + after7days.setDate(after7days.getDate() + 7); + let today = await this.dateFormat(new Date()); + if (new Date(today) > after7days) { + throw new BadGatewayException('Link Expired. Contact Administrator') + } + + revisedTender.revisedDocument = body.revisedDocument + await this.revisedTenderRepository.save(revisedTender) + return { data: "Document Saved Successfully" } + } + + async dateFormat(date) { + let resdate = new Date(date) + let dd = String(resdate.getDate()).padStart(2, '0'); // Day + let mm = String(resdate.getMonth() + 1).padStart(2, '0'); // Month (add 1 because January is 0) + let yy = resdate.getFullYear().toString(); // Last two d + let formattedDate = `${yy}-${mm}-${dd}`; + return formattedDate + } + + async requotedReport(tenderId,user){ + if (user.secuLevel === 'SuperAdmin' || user.secuLevel === 'Admin') { + let report = await this.revisedTenderRepository.find({ + where:{ + tenderId : tenderId + },order:{ + requotedOrder : 'ASC' + } + }) + return report + }else { + throw new UnauthorizedException('You have no right to Requoted users..') + } + } + +} diff --git a/src/tables/sub-gallery/sub-gallery.controller.ts b/src/tables/sub-gallery/sub-gallery.controller.ts new file mode 100644 index 0000000..199b885 --- /dev/null +++ b/src/tables/sub-gallery/sub-gallery.controller.ts @@ -0,0 +1,46 @@ +import { Controller, Delete, NotFoundException, Param } from '@nestjs/common'; +import { subGalleryDto } from 'src/dto/sub-gallery.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { SubGalleryService } from './sub-gallery.service'; +import * as fs from 'fs'; +import { subGalleryRepository } from './sub-gallery.repository'; + +@Controller('sub-gallery') +export class SubGalleryController extends PcdFormGridController { + constructor( + private subGalleryService: SubGalleryService, + private subgalleryRepo : subGalleryRepository + ) { + super(subGalleryService); + } + + @Delete('image/:id/:filename') + async deletePicture( + @Param('id') id : number, + @Param('filename') filename : string, + // @Param('id') id:string + ): Promise { + const filePath = './uploads/Pictures/'+ filename; + console.log("filepath===",filePath); + try { + console.log("deleted=====",filename); + + await fs.promises.unlink(filePath); + // console.log('helloo'); + + // const filter = { docName: filename }; + const deletedEntry = await this.subgalleryRepo.findOne({where:{imageUrl: filename ,galleryId:id}}); + // console.log(deletedEntry); + + if (deletedEntry) { + await this.subgalleryRepo.remove(deletedEntry); + console.log('Entry deleted successfully.'); + } + return { message: 'File and entry deleted successfully.' }; + } catch (err) { + throw new NotFoundException('File or entry not found.'); + } + } + +} + diff --git a/src/tables/sub-gallery/sub-gallery.entity.ts b/src/tables/sub-gallery/sub-gallery.entity.ts new file mode 100644 index 0000000..be7218e --- /dev/null +++ b/src/tables/sub-gallery/sub-gallery.entity.ts @@ -0,0 +1,34 @@ +import { ColdObservable } from "rxjs/internal/testing/ColdObservable"; +import { PcdBaseDto } from "src/framework/custom/pcd-dto.custom"; +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { gallery } from "../gallery/gallery.entity"; + +@Entity('sub-gallery') +export class subGallery extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"gallery_id", + type:"numeric", + nullable:false, + }) + galleryId : number + + @Column({ + name:"image_url", + type:"varchar", + nullable:true, + length:1000 + }) + imageUrl : string + + @ManyToOne(() => gallery, (gallery) => gallery.subGallery, { eager: true }) + @JoinColumn([{ name: "gallery_id", referencedColumnName: "id" }]) + galleryD: gallery + +} + diff --git a/src/tables/sub-gallery/sub-gallery.module.ts b/src/tables/sub-gallery/sub-gallery.module.ts new file mode 100644 index 0000000..295fa40 --- /dev/null +++ b/src/tables/sub-gallery/sub-gallery.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; +import { SubGalleryController } from './sub-gallery.controller'; +import { SubGalleryService } from './sub-gallery.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { subGalleryRepository } from './sub-gallery.repository'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([subGalleryRepository]), + AuthModule + ], + controllers: [SubGalleryController], + providers: [SubGalleryService,subGalleryRepository] +}) +export class SubGalleryModule {} diff --git a/src/tables/sub-gallery/sub-gallery.repository.ts b/src/tables/sub-gallery/sub-gallery.repository.ts new file mode 100644 index 0000000..7bb9463 --- /dev/null +++ b/src/tables/sub-gallery/sub-gallery.repository.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { subGallery } from "./sub-gallery.entity"; + +@Injectable() +export class subGalleryRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(subGallery , datasource.createEntityManager()) + } +} \ No newline at end of file diff --git a/src/tables/sub-gallery/sub-gallery.service.ts b/src/tables/sub-gallery/sub-gallery.service.ts new file mode 100644 index 0000000..016313d --- /dev/null +++ b/src/tables/sub-gallery/sub-gallery.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { subGalleryDto } from 'src/dto/sub-gallery.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { subGalleryRepository } from './sub-gallery.repository'; + +@Injectable() +export class SubGalleryService extends PcdFormGridService { + constructor( + @InjectRepository(subGalleryRepository) + private subGalleryRepository: subGalleryRepository, + ) { + super(subGalleryRepository); + } + + + +} diff --git a/src/tables/tender-category/tender-category.controller.ts b/src/tables/tender-category/tender-category.controller.ts new file mode 100644 index 0000000..9db5021 --- /dev/null +++ b/src/tables/tender-category/tender-category.controller.ts @@ -0,0 +1,34 @@ +import { Controller ,Get,UseGuards} from '@nestjs/common'; +import { TenderCategoryDto } from 'src/dto/tender-category.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { TenderCategoryService } from './tender-category.service'; +import { AuthGuard } from '@nestjs/passport'; +import { TenderCategoryRepository } from './tender-category.repository'; + +@UseGuards(AuthGuard()) +@Controller('tender-category') +export class TenderCategoryController extends PcdFormGridController{ + + constructor( + private tenderCategoryService: TenderCategoryService + ) { + super(tenderCategoryService); + } + +} + +@Controller('category') +export class CategoryController extends PcdFormGridController{ + + constructor( + private tenderCategoryService: TenderCategoryService, + ) { + super(tenderCategoryService); + } + + @Get() + async getCategory(){ + return await this.tenderCategoryService.getCategory() + } + +} \ No newline at end of file diff --git a/src/tables/tender-category/tender-category.entity.ts b/src/tables/tender-category/tender-category.entity.ts new file mode 100644 index 0000000..8bccd83 --- /dev/null +++ b/src/tables/tender-category/tender-category.entity.ts @@ -0,0 +1,45 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { category } from "../userCategory-master/category.entity"; +import { tenderSubCategory } from "../tender-subcategory/tender-subcategory.entity"; +import { userSubcategoryMaster } from "../user-subcategory-master/user-subcategory-master.entity"; + +@Entity('tender_category') +export class TenderCategory extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"tender_category", + type:"varchar", + nullable:true + }) + tenderCategory:string + + @Column({ + name:'active', + type:"boolean", + default: true, + // nullable:true + }) + active:boolean + + + @OneToMany(() => TenderMaster, (tenderMaster) => tenderMaster.productCategoryD ) + tenderMaster:TenderMaster[] + + + @OneToMany(() => category, (category) => category.categoryD ) + category:category[] + + @OneToMany(() => tenderSubCategory, (tenderSubCategory) => tenderSubCategory.tenderCategoryD ) + tenderSubCategory:TenderCategory[] + + @OneToMany(() => userSubcategoryMaster, (userSubcategoryMaster) => userSubcategoryMaster.categoryD) + userSubcategoryMaster: userSubcategoryMaster[] + +} \ No newline at end of file diff --git a/src/tables/tender-category/tender-category.module.ts b/src/tables/tender-category/tender-category.module.ts new file mode 100644 index 0000000..7c30c10 --- /dev/null +++ b/src/tables/tender-category/tender-category.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { CategoryController, TenderCategoryController } from './tender-category.controller'; +import { TenderCategoryService } from './tender-category.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { TenderCategoryRepository } from './tender-category.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { TenderCategory } from './tender-category.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([TenderCategory]), + AuthModule + ], + controllers: [TenderCategoryController,CategoryController], + providers: [TenderCategoryService,TenderCategoryRepository] +}) +export class TenderCategoryModule {} diff --git a/src/tables/tender-category/tender-category.repository.ts b/src/tables/tender-category/tender-category.repository.ts new file mode 100644 index 0000000..2a3734a --- /dev/null +++ b/src/tables/tender-category/tender-category.repository.ts @@ -0,0 +1,12 @@ +import { DataSource, EntityRepository, Repository } from "typeorm"; +import { TenderCategory } from "./tender-category.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class TenderCategoryRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(TenderCategory,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/tender-category/tender-category.service.ts b/src/tables/tender-category/tender-category.service.ts new file mode 100644 index 0000000..12fe000 --- /dev/null +++ b/src/tables/tender-category/tender-category.service.ts @@ -0,0 +1,72 @@ +import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { TenderCategoryDto } from 'src/dto/tender-category.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { TenderCategoryRepository } from './tender-category.repository'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { FindManyOptions } from 'typeorm'; + +@Injectable() +export class TenderCategoryService extends PcdFormGridService{ + + constructor( + @InjectRepository(TenderCategoryRepository) + private tenderCategoryRepository: TenderCategoryRepository, + ) { + super(tenderCategoryRepository); + } + + async preCreateOne(body: TenderCategoryDto, user: PcduserDto): Promise { + if (user.secuLevel != 'SuperAdmin' && user.secuLevel != 'Admin') { + throw new UnauthorizedException("You don't have the right to create new Category") + } + return true + + } + + async preDeleteOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise { + if (user.secuLevel != 'SuperAdmin' && user.secuLevel != 'Admin') { + throw new UnauthorizedException("You don't have the right to create new Category") + } + + return true + } + + async preUpdateOne(body: TenderCategoryDto, id: string | number, user: PcduserDto): Promise { + if (user.secuLevel != 'SuperAdmin' && user.secuLevel != 'Admin') { + throw new UnauthorizedException("You don't have the right to create new Category") + } + + return true + } + + async getCategory() { + // console.log("hello123"); + + // let category = await this.tenderCategoryRepository.find({where:{active:true}}) + // console.log(category); + + // return category + + + try { + const categories = await this.tenderCategoryRepository.find({ + where: { active: true }, + relations: ['tenderSubCategory'], + }); + + // Filter out subcategories that are not active + const categoriesWithActiveSubcategories = categories.map(category => { + category.tenderSubCategory = category.tenderSubCategory.filter(subcategory => subcategory.active); + return category; + }); + + return categoriesWithActiveSubcategories; + } catch (error) { + console.error('Error fetching active categories with subcategories', error); + return []; + } + } +} + + diff --git a/src/tables/tender-documents/tender-doc.controller.ts b/src/tables/tender-documents/tender-doc.controller.ts new file mode 100644 index 0000000..ae0c711 --- /dev/null +++ b/src/tables/tender-documents/tender-doc.controller.ts @@ -0,0 +1,33 @@ +import { Controller ,UseGuards,Get,Param,Post} from '@nestjs/common'; +import { TenderDocumentDto } from 'src/dto/tender-document.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { TenderDocService } from './tender-doc.service'; +import { AuthGuard } from '@nestjs/passport'; + + +@Controller('tender-doc') +export class TenderDocController extends PcdFormGridController{ + + constructor( + private tenderDocService: TenderDocService + ) { + super(tenderDocService); + } + + @Get("userDocCheck/:userId/:tenderId") + async userDocCheck( + @Param('userId') userId:string, + @Param('tenderId') tenderId : string + ){ + return this.tenderDocService.userDocCheck(userId,tenderId) + } + + @Get("dd/:userId/:tenderId") + async userDdCheck( + @Param('userId') userId:string, + @Param('tenderId') tenderId : string + ){ + return this.tenderDocService.userDdCheck(userId,tenderId) + } + +} diff --git a/src/tables/tender-documents/tender-doc.entity.ts b/src/tables/tender-documents/tender-doc.entity.ts new file mode 100644 index 0000000..56737bc --- /dev/null +++ b/src/tables/tender-documents/tender-doc.entity.ts @@ -0,0 +1,72 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { DocumentType } from "../document-type/document-type.entity"; +import { Pcduser } from "src/auth/pcduser.entity"; + +@Entity("tender-doc") +export class TenderDoc extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + @Column({ + name:"tender_id", + type:"numeric", + nullable:true + }) + tenderId:number + @Column({ + name:"doc_name", + type:"varchar", + length:1500, + nullable:true + }) + docName:string + @Column({ + name:"doc_type", + type:"varchar", + nullable:true + }) + docType:string + @Column({ + name:"description", + type:"varchar", + length:1500, + nullable:true + }) + description:string + + @Column({ + name:"document_size", + type:"numeric", + nullable:true + }) + documentSize:number; + + @Column({ + name:"doc_category", + type:"varchar", + nullable:true + }) + documentCategory:string + + @Column({ + name:"user_id", + type:'varchar', + nullable:true + }) + userId:number; + + @ManyToOne(() => TenderMaster,(tenderMaster)=> tenderMaster.TenderDoc) + @JoinColumn([{ name: "tender_id", referencedColumnName: "id" }]) + tenderIdD:TenderMaster + + @ManyToOne(() => DocumentType,(documentType)=> documentType.tenderDoc,{eager:true}) + @JoinColumn([{ name: "doc_type", referencedColumnName: "id" }]) + documentTypeD:DocumentType + + @ManyToOne(() => Pcduser,(Pcduser)=> Pcduser.tenderDoc,{eager:true}) + @JoinColumn([{ name: "user_id", referencedColumnName: "userId" }]) + userD:DocumentType +} \ No newline at end of file diff --git a/src/tables/tender-documents/tender-doc.module.ts b/src/tables/tender-documents/tender-doc.module.ts new file mode 100644 index 0000000..7a565f7 --- /dev/null +++ b/src/tables/tender-documents/tender-doc.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; +import { TenderDocService } from './tender-doc.service'; +import { TenderDocController } from './tender-doc.controller'; +import { tenderDocRepository } from './tender-doc.repository'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { TenderDoc } from './tender-doc.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([TenderDoc]), + ], + providers: [TenderDocService,tenderDocRepository], + controllers: [TenderDocController] +}) +export class TenderDocModule {} diff --git a/src/tables/tender-documents/tender-doc.repository.ts b/src/tables/tender-documents/tender-doc.repository.ts new file mode 100644 index 0000000..2dd08d9 --- /dev/null +++ b/src/tables/tender-documents/tender-doc.repository.ts @@ -0,0 +1,9 @@ +import { DataSource, Repository } from "typeorm"; +import { TenderDoc } from "./tender-doc.entity"; +import { Injectable } from "@nestjs/common"; +@Injectable() +export class tenderDocRepository extends Repository{ + constructor(private dataSource: DataSource) { + super(TenderDoc, dataSource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/tender-documents/tender-doc.service.ts b/src/tables/tender-documents/tender-doc.service.ts new file mode 100644 index 0000000..dfad09e --- /dev/null +++ b/src/tables/tender-documents/tender-doc.service.ts @@ -0,0 +1,32 @@ +import { Injectable ,BadRequestException} from '@nestjs/common'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { tenderDocRepository } from './tender-doc.repository'; +import { InjectRepository } from '@nestjs/typeorm'; +import { TenderDocumentDto } from 'src/dto/tender-document.dto'; +import { log } from 'console'; + +@Injectable() +export class TenderDocService extends PcdFormGridService{ + + constructor( + @InjectRepository(tenderDocRepository) + private tenderDocRepository: tenderDocRepository, + ) { + super(tenderDocRepository); + } + + async userDocCheck(userId,tenderId){ + let query = `select * from "tender-doc" td where td.user_id = '${userId}' and td.tender_id ='${tenderId}' and doc_category ='USERD' ` + let userDoc =await this.tenderDocRepository.query(query) + return userDoc + + } + + async userDdCheck(userId,tenderId){ + let query = `select * from "tender-doc" td where td.user_id = '${userId}' and td.tender_id ='${tenderId}' and doc_category ='DD' ` + let userDoc =await this.tenderDocRepository.query(query) + return userDoc + + } + +} diff --git a/src/tables/tender-master/tender-details.controller.ts b/src/tables/tender-master/tender-details.controller.ts new file mode 100644 index 0000000..85524de --- /dev/null +++ b/src/tables/tender-master/tender-details.controller.ts @@ -0,0 +1,18 @@ +import { Controller,Get, Param,UseGuards} from '@nestjs/common'; +import { TenderDetailsService } from './tender-details.service'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; + +import { TenderDetailDto } from 'src/dto/tender-master.dto'; + + + +@Controller('tender-details') +export class TenderDetailsController extends PcdFormGridController { + + constructor( + private tenderDetailsService: TenderDetailsService + ) { + super(tenderDetailsService); + } + +} diff --git a/src/tables/tender-master/tender-details.module.ts b/src/tables/tender-master/tender-details.module.ts new file mode 100644 index 0000000..b6f6770 --- /dev/null +++ b/src/tables/tender-master/tender-details.module.ts @@ -0,0 +1,19 @@ +import { Module } from '@nestjs/common'; +import { TenderDetailsController } from './tender-details.controller'; +import { TenderDetailsService } from './tender-details.service'; +import { TenderMasterRepository } from './tender-master.repository'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { TenderMaster } from './tender-master.entity'; + + +@Module({ + imports: [ + + TypeOrmModule.forFeature([ + TenderMasterRepository + ]) + ], + controllers: [TenderDetailsController], + providers: [TenderDetailsService] +}) +export class TenderDetailsModule {} diff --git a/src/tables/tender-master/tender-details.service.ts b/src/tables/tender-master/tender-details.service.ts new file mode 100644 index 0000000..4ee5de5 --- /dev/null +++ b/src/tables/tender-master/tender-details.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@nestjs/common'; +import { TenderMasterRepository } from './tender-master.repository'; +import { TenderTypeRepository } from 'src/tables/tender-type/tender-type.repository'; +import { TenderCategoryRepository } from 'src/tables/tender-category/tender-category.repository'; +import { FormOfContractRepository } from 'src/tables/form-of-contract/form-of-contract.repository'; +import { basicCategoryRepository } from 'src/tables/category/category.repository'; +import { PaymentModeRepository } from 'src/tables/payment-mode/payment-mode.repository'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { TenderDetailDto } from 'src/dto/tender-master.dto'; +import { InjectRepository } from '@nestjs/typeorm'; + +@Injectable() +export class TenderDetailsService extends PcdFormGridService{ + + constructor( + @InjectRepository(TenderMasterRepository) + private tenderMasterRepository: TenderMasterRepository, + ) { + super(tenderMasterRepository); + } + +} diff --git a/src/tables/tender-master/tender-master.entity.ts b/src/tables/tender-master/tender-master.entity.ts new file mode 100644 index 0000000..b81822e --- /dev/null +++ b/src/tables/tender-master/tender-master.entity.ts @@ -0,0 +1,441 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { EmdFeeType } from "src/tables/emd-fee-type/emd-fee-type.entity"; +import { FormOfContract } from "src/tables/form-of-contract/form-of-contract.entity"; +import { PaymentMode } from "src/tables/payment-mode/payment-mode.entity"; +import { Category } from "src/tables/category/category.entity"; +import { TenderCategory } from "src/tables/tender-category/tender-category.entity"; +import { TenderType } from "src/tables/tender-type/tender-type.entity"; +import { TenderDoc } from "src/tables/tender-documents/tender-doc.entity"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { CoverDoc } from "../covers-master/covers-master.entity"; +import { PaymentMaster } from "../payment-master/payment-master.entity"; +import { tenderSubCategoryMaster } from "../tender-subcategory-master/tender-subcategory-master.entity"; +import { closedTenderUsers } from "../closed-tender-users/closed-tender-users.entity"; +import { PaymentStatus } from "../payment-status/payment-status.entity"; +import { revisedTender } from "../revised-tender/revised-tender.entity"; + +@Entity('tender_master') +export class TenderMaster extends PcdBaseEntity { + @PrimaryGeneratedColumn({ + name: 'id' + }) + id: number + @Column({ + name: 'org_chain', + type: 'varchar', + length: 500, + nullable: true + }) + orgChain: string + @Column({ + name: 'tender_ref_no', + type: "varchar", + length: 500, + nullable: true + }) + tenderRefNo: string + @Column({ + name: "tender_id", + type: 'varchar', + length: 510, + nullable: true + }) + tenderId: string + @Column({ + name: "allow_tech_eval", + type: "char", + length: 1, + nullable: true + }) + allowTechEval: string + + @Column({ + name: "payment_mode", + type: 'numeric', + nullable: true + }) + paymentMode: number + @Column({ + name: 'allow_withdraw', + type: 'char', + length: 1, + nullable: true + }) + allowWithdraw: string + @Column({ + name: 'no_of_covers', + type: 'int', + nullable: true, + default: () => "(0)" + }) + noOfCovers: string + @Column({ + name: 'itemwise_tech_eval', + type: 'char', + length: 1, + nullable: true + }) + itemwiseTechEval: string + @Column({ + name: 'allow_two_stage', + type: 'char', + length: 1, + nullable: true + }) + allowTwoStageBid: string + + @Column({ + name: 'tender_fee', + type: 'int', + nullable: true + + }) + tenderFee: string + @Column({ + name: 'fee_pay_to', + type: "varchar", + length: 100, + default: () => "'Nil'" + }) + feePayableTo: string + @Column({ + name: 'fee_pay_at', + type: "varchar", + length: 100, + default: () => "'Nil'" + }) + feePayableAt: string + @Column({ + name: "t_fee_Exemption", + type: "char", + length: 1, + nullable: true + }) + tenderFeeExemption: string + @Column({ + name: 'emd_amt', + type: 'int', + nullable: true + }) + emdAmt: string + @Column({ + name: "emd_payable_to", + type: "varchar", + length: 100, + default: () => "'Nil'", + nullable:true + }) + emdPayableTo: string + @Column({ + name: "allow_emd_bg_st", + type: "char", + length: 1, + nullable: true + }) + allowEmdBgOrSt: string + @Column({ + name: "emd_percentage", + type: "int", + nullable: true + }) + emdPercentage: string + @Column({ + name: "emd_payable_at", + type: "varchar", + length: 100, + default: () => "'Nil'" + }) + emdPayableAt: string + @Column({ + name: "title", + type: 'varchar', + length: 500, + nullable: true + }) + title: string + @Column({ + name: "work_desc", + type: 'varchar', + length: 500, + nullable: true + }) + workDesc: string + @Column({ + name: "nda_pre_quali", + type: "varchar", + length: 500, + nullable: true + }) + ndaPreQualification: string + @Column({ + name: "remarks", + type: "varchar", + length: 500, + default: () => "'NA'" + }) + remarks: string + @Column({ + name: "tender_value", + type: "int", + nullable: true + }) + tenderValue: string + @Column({ + name: "contract_type", + type: "varchar", + length: 200, + nullable: true + }) + contractType: string + @Column({ + name: "location", + type: "varchar", + length: 200, + nullable: true + }) + location: string + @Column({ + name: "pre_bid_meet_add", + type: "varchar", + length: 500, + nullable: true + }) + preBidMeetAdd: string + @Column({ + name: "allow_nda_tender", + type: "char", + length: 1, + nullable: true + }) + allowNdaTender: string + @Column({ + name: "product_cat", + type: "numeric", + nullable: true + }) + productCategory: number + @Column({ + name: "bid_validity", + type: 'int', + nullable: true + }) + bidValidity: string + @Column({ + name: "pincode", + type: "int", + nullable: true + }) + pincode: string + @Column({ + name: "pre_bid_date", + type: "timestamp", + nullable: true + }) + preBidDate: Date + @Column({ + name: "allow_prefer_bidder", + type: "char", + length: 1, + nullable: true + }) + allowPreferencialBidder: string + @Column({ + name: "sub_category", + type: "varchar", + length: 500, + nullable: true + }) + subCategory: string + @Column({ + name: "period_of_work", + type: "varchar", + nullable: true + }) + periodOfWork: string + @Column({ + name: "pre_meet_place", + type: "varchar", + length: 500, + nullable: true + }) + preBidMeetPlace: string + @Column({ + name: "bid_open_place", + type: "varchar", + length: 500, + nullable: true + }) + bidOpeningPlace: string + @Column({ + name: "publish_date", + type: "timestamp", + nullable: true + }) + publishDate: Date + @Column({ + name: "sale_start_date", + type: "timestamp", + nullable: true + }) + saleStartDate: Date + @Column({ + name: "clarification_start_d", + type: "timestamp", + nullable: true + }) + clarificationStartDate: Date + @Column({ + name: "bid_sub_start_date", + type: "timestamp", + nullable: true + }) + bidSubStartDate: Date + @Column({ + name: "bid_open_date", + type: "timestamp", + nullable: true + }) + bidOpenDate: Date + @Column({ + name: "sale_end_date", + type: "timestamp", + nullable: true + }) + saleEndDate: Date + @Column({ + name: "clarification_end_d", + type: "timestamp", + nullable: true + }) + clarificationEndDate: Date + @Column({ + name: "bid_sub_end_date", + type: "timestamp", + nullable: true + }) + bidSubEndDate: Date + @Column({ + name: "tender_inv_name", + type: "varchar", + length: 100, + nullable: true + }) + tenderInvName: string + @Column({ + name: "tender_inv_address", + type: "varchar", + length: 500, + nullable: true + }) + tenderInvAddess: string + @Column({ + name: "tender_type", + type: "numeric", + nullable: true + }) + tenderType: number + @Column({ + name: "tender_category", + type: "numeric", + nullable: true + }) + tenderCategory: number + @Column({ + name: "form_of_contract", + type: "numeric", + nullable: true + }) + formOfContract: number + + @Column({ + name: "emd_fee_type", + type: "varchar", + nullable: true + }) + emdFeeType: string + + @Column({ + name: "emd_fee_applied", + type: "boolean", + nullable: true, + default: true + }) + emdFeeApplied: boolean | null + + @Column({ + name: "activeyn", + type: "varchar", + length: 1, + nullable: true + }) + activeYn: string + + @Column({ + name:"send_report", + type:"varchar", + length:1, + nullable:true + }) + sendReport:string + + @Column({ + name:"bid_open_address", + type:"varchar", + nullable:true + }) + bidOpenAddress:string + + @OneToMany(() => tenderSubCategoryMaster, (tenderSubCategoryMaster) => tenderSubCategoryMaster.tenderD ) + tenderSubCategoryMaster:tenderSubCategoryMaster[] + + @OneToMany(() => CoverDoc, (coverDoc) => coverDoc.tenderIdD) + coverDoc: CoverDoc[] + + @OneToMany(() => closedTenderUsers, (closedTenderUsers) => closedTenderUsers.tenderD) + closedTenderUsers: closedTenderUsers[] + + // @OneToMany(() => paymentInstrument, (paymentInstrument) => paymentInstrument.tenderIdD) + // paymentInstrument: paymentInstrument[] + + + @OneToMany(() => PaymentMaster, (paymentMaster) => paymentMaster.tenderMasterD) + paymentMaster: PaymentMaster[] + + @OneToMany(() => TenderDoc, (TenderDoc) => TenderDoc.tenderIdD) + TenderDoc: TenderDoc[] + + + @OneToMany(() => PaymentStatus, (PaymentStatus) => PaymentStatus.tenderMaster ) + paymentStatusD:PaymentStatus[] + + @OneToMany(() => revisedTender, (revisedTender) => revisedTender.revisedTenderD ) + revisedTenderD:revisedTender[] + + + @ManyToOne(() => TenderType, (tenderType) => tenderType.tenderMaster, { eager: true }) + @JoinColumn([{ name: "tender_type", referencedColumnName: "id" }]) + tenderTypeD: TenderType + + @ManyToOne(() => Category, (Category) => Category.tenderMaster, { eager: true }) + @JoinColumn([{ name: "tender_category", referencedColumnName: "id" }]) + tenderCategoryD: Category + + + @ManyToOne(() => PaymentMode, (paymentMode) => paymentMode.tenderMaster, { eager: true }) + @JoinColumn([{ name: "payment_mode", referencedColumnName: "id" }]) + paymentModeD: PaymentMode + + @ManyToOne(() => FormOfContract, (formOfContract) => formOfContract.tenderMaster, { eager: true }) + @JoinColumn([{ name: "form_of_contract", referencedColumnName: "id" }]) + formOfContractD: FormOfContract + + @ManyToOne(() => TenderCategory, (tenderCategory) => tenderCategory.tenderMaster, { eager: true }) + @JoinColumn([{ name: "product_cat", referencedColumnName: "id" }]) + productCategoryD: TenderCategory + + @ManyToOne(() => EmdFeeType, (EmdFeeType) => EmdFeeType.tenderMaster, { eager: true }) + @JoinColumn([{ name: "emd_fee_type", referencedColumnName: "id" }]) + emdFeeTypeD: Category + +} + diff --git a/src/tables/tender-master/tender-master.repository.ts b/src/tables/tender-master/tender-master.repository.ts new file mode 100644 index 0000000..3081d4f --- /dev/null +++ b/src/tables/tender-master/tender-master.repository.ts @@ -0,0 +1,10 @@ +import { DataSource, Repository } from "typeorm"; +import { TenderMaster } from "./tender-master.entity"; +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class TenderMasterRepository extends Repository{ + constructor(private dataSource: DataSource) { + super(TenderMaster, dataSource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/tender-subcategory-master/tender-subcategory-master.controller.ts b/src/tables/tender-subcategory-master/tender-subcategory-master.controller.ts new file mode 100644 index 0000000..2738467 --- /dev/null +++ b/src/tables/tender-subcategory-master/tender-subcategory-master.controller.ts @@ -0,0 +1,16 @@ +import { Controller } from '@nestjs/common'; +import { tenderSubcategoryMasterDto } from 'src/dto/tender-subcategory-master.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { TenderSubcategoryMasterService } from './tender-subcategory-master.service'; + +@Controller('tender-subcategory-master') +export class TenderSubcategoryMasterController extends PcdFormGridController { + + constructor( + private TenderSubcategoryMasterService: TenderSubcategoryMasterService + ) { + super(TenderSubcategoryMasterService); + } + +} + diff --git a/src/tables/tender-subcategory-master/tender-subcategory-master.entity.ts b/src/tables/tender-subcategory-master/tender-subcategory-master.entity.ts new file mode 100644 index 0000000..5d85ba1 --- /dev/null +++ b/src/tables/tender-subcategory-master/tender-subcategory-master.entity.ts @@ -0,0 +1,35 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { TenderMaster } from "../tender-master/tender-master.entity"; +import { tenderSubCategory } from "../tender-subcategory/tender-subcategory.entity"; + +@Entity('tender-subcategory-master') +export class tenderSubCategoryMaster extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"tender_id", + type:"numeric", + nullable:false + }) + tenderId : number + + @Column({ + name:"subcategory_id", + type:"numeric", + nullable:false + }) + subCategoryId : number + + @ManyToOne(() => TenderMaster, (TenderMaster) => TenderMaster.tenderSubCategoryMaster, { eager: true }) + @JoinColumn([{ name: "tender_id", referencedColumnName: "id" }]) + tenderD: TenderMaster + + @ManyToOne(() => tenderSubCategory, (tenderSubCategory) => tenderSubCategory.tenderSubCategoryMaster, { eager: true }) + @JoinColumn([{ name: "subcategory_id", referencedColumnName: "id" }]) + tendersubCategoryD: tenderSubCategory +} \ No newline at end of file diff --git a/src/tables/tender-subcategory-master/tender-subcategory-master.module.ts b/src/tables/tender-subcategory-master/tender-subcategory-master.module.ts new file mode 100644 index 0000000..bd0c497 --- /dev/null +++ b/src/tables/tender-subcategory-master/tender-subcategory-master.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { TenderSubcategoryMasterController } from './tender-subcategory-master.controller'; +import { TenderSubcategoryMasterService } from './tender-subcategory-master.service'; +import { tenderSubCategoryMasterRepository } from './tender-subcategory-master.repository'; + +@Module({ + controllers: [TenderSubcategoryMasterController], + providers: [TenderSubcategoryMasterService,tenderSubCategoryMasterRepository] +}) +export class TenderSubcategoryMasterModule {} diff --git a/src/tables/tender-subcategory-master/tender-subcategory-master.repository.ts b/src/tables/tender-subcategory-master/tender-subcategory-master.repository.ts new file mode 100644 index 0000000..595784f --- /dev/null +++ b/src/tables/tender-subcategory-master/tender-subcategory-master.repository.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { tenderSubCategoryMaster } from "./tender-subcategory-master.entity"; + +@Injectable() +export class tenderSubCategoryMasterRepository extends Repository{ + constructor(private dataSource: DataSource) { + super(tenderSubCategoryMaster, dataSource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/tender-subcategory-master/tender-subcategory-master.service.ts b/src/tables/tender-subcategory-master/tender-subcategory-master.service.ts new file mode 100644 index 0000000..570608e --- /dev/null +++ b/src/tables/tender-subcategory-master/tender-subcategory-master.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { tenderSubcategoryMasterDto } from 'src/dto/tender-subcategory-master.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { tenderSubCategoryMasterRepository } from './tender-subcategory-master.repository'; + +@Injectable() +export class TenderSubcategoryMasterService extends PcdFormGridService{ + + constructor( + @InjectRepository(tenderSubCategoryMasterRepository) + private tenderSubCategoryMasterRepository: tenderSubCategoryMasterRepository, + ) { + super(tenderSubCategoryMasterRepository); + } + +} diff --git a/src/tables/tender-subcategory/tender-subcategory.controller.ts b/src/tables/tender-subcategory/tender-subcategory.controller.ts new file mode 100644 index 0000000..5c84b60 --- /dev/null +++ b/src/tables/tender-subcategory/tender-subcategory.controller.ts @@ -0,0 +1,23 @@ +import { Controller, Get, Param } from '@nestjs/common'; +import { tenderSubCategoryDto } from 'src/dto/tender-subcategory.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { TenderSubcategoryService } from './tender-subcategory.service'; + +@Controller('tender-subcategory') +export class TenderSubcategoryController extends PcdFormGridController { + + constructor( + private tenderSubcategoryService: TenderSubcategoryService + ) { + super(tenderSubcategoryService); + } + + @Get('/:id') + async getSubCategory( + @Param('id') id : string + ){ + return await this.tenderSubcategoryService.getSubCategory(id) + } + + +} diff --git a/src/tables/tender-subcategory/tender-subcategory.entity.ts b/src/tables/tender-subcategory/tender-subcategory.entity.ts new file mode 100644 index 0000000..c3ea8e0 --- /dev/null +++ b/src/tables/tender-subcategory/tender-subcategory.entity.ts @@ -0,0 +1,47 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { TenderCategory } from "../tender-category/tender-category.entity"; +import { tenderSubCategoryMaster } from "../tender-subcategory-master/tender-subcategory-master.entity"; +import { userSubcategoryMaster } from "../user-subcategory-master/user-subcategory-master.entity"; + +@Entity('tender_subcategory') +export class tenderSubCategory extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"tender_category", + type:"numeric", + nullable:true + }) + tenderCategory:number + + + @Column({ + name:"tender_subcategory", + type:"varchar", + nullable:false, + length:1000 + }) + tenderSubCategory:string + + @Column({ + name:'active', + type:"boolean", + default: true, + }) + active:boolean + + @OneToMany(() => tenderSubCategoryMaster, (tenderSubCategoryMaster) => tenderSubCategoryMaster.tendersubCategoryD) + tenderSubCategoryMaster: tenderSubCategoryMaster[] + + @ManyToOne(() => TenderCategory, (TenderCategory) => TenderCategory.tenderSubCategory, { eager: true }) + @JoinColumn([{ name: "tender_category", referencedColumnName: "id" }]) + tenderCategoryD: TenderCategory + + @OneToMany(() => userSubcategoryMaster, (userSubcategoryMaster) => userSubcategoryMaster.tenderSubCategoryD) + userSubcategoryMaster: userSubcategoryMaster[] +} \ No newline at end of file diff --git a/src/tables/tender-subcategory/tender-subcategory.module.ts b/src/tables/tender-subcategory/tender-subcategory.module.ts new file mode 100644 index 0000000..427ee25 --- /dev/null +++ b/src/tables/tender-subcategory/tender-subcategory.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { TenderSubcategoryController } from './tender-subcategory.controller'; +import { TenderSubcategoryService } from './tender-subcategory.service'; +import { tenderSubCategoryRepository } from './tender-subcategory.repository'; + +@Module({ + controllers: [TenderSubcategoryController], + providers: [TenderSubcategoryService,tenderSubCategoryRepository] +}) +export class TenderSubcategoryModule {} diff --git a/src/tables/tender-subcategory/tender-subcategory.repository.ts b/src/tables/tender-subcategory/tender-subcategory.repository.ts new file mode 100644 index 0000000..120f6c8 --- /dev/null +++ b/src/tables/tender-subcategory/tender-subcategory.repository.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { tenderSubCategory } from "./tender-subcategory.entity"; + +@Injectable() +export class tenderSubCategoryRepository extends Repository{ + constructor(private dataSource: DataSource) { + super(tenderSubCategory, dataSource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/tender-subcategory/tender-subcategory.service.ts b/src/tables/tender-subcategory/tender-subcategory.service.ts new file mode 100644 index 0000000..36358a4 --- /dev/null +++ b/src/tables/tender-subcategory/tender-subcategory.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { tenderSubCategoryRepository } from './tender-subcategory.repository'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { tenderSubCategoryDto } from 'src/dto/tender-subcategory.dto'; + +@Injectable() +export class TenderSubcategoryService extends PcdFormGridService{ + + constructor( + @InjectRepository(tenderSubCategoryRepository) + private tenderSubCategoryRepository: tenderSubCategoryRepository, + ) { + super(tenderSubCategoryRepository); + } + + async getSubCategory(id){ + return await this.tenderSubCategoryRepository.find({ + where:{ + tenderCategory : id + } + }) + } + +} diff --git a/src/tables/tender-type/tender-type.controller.ts b/src/tables/tender-type/tender-type.controller.ts new file mode 100644 index 0000000..e5fa9cd --- /dev/null +++ b/src/tables/tender-type/tender-type.controller.ts @@ -0,0 +1,18 @@ +import { Controller, UseGuards } from '@nestjs/common'; +import { TenderTypeDto } from 'src/dto/tender-type.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { TenderTypeService } from './tender-type.service'; +import { AuthGuard } from '@nestjs/passport'; + + +@UseGuards(AuthGuard()) +@Controller('tender-type') +export class TenderTypeController extends PcdFormGridController{ + + constructor( + private tenderTypeService: TenderTypeService + ) { + super(tenderTypeService); + } + +} diff --git a/src/tables/tender-type/tender-type.entity.ts b/src/tables/tender-type/tender-type.entity.ts new file mode 100644 index 0000000..50ec6f5 --- /dev/null +++ b/src/tables/tender-type/tender-type.entity.ts @@ -0,0 +1,24 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('tender-type') +export class TenderType extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"tender_type", + type:"varchar", + nullable:true + }) + tenderType:string + + + + @OneToMany(() => TenderMaster, (tenderMaster) => tenderMaster.tenderTypeD ) + tenderMaster:TenderMaster[] +} \ No newline at end of file diff --git a/src/tables/tender-type/tender-type.module.ts b/src/tables/tender-type/tender-type.module.ts new file mode 100644 index 0000000..c9c9eeb --- /dev/null +++ b/src/tables/tender-type/tender-type.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { TenderTypeController } from './tender-type.controller'; +import { TenderTypeService } from './tender-type.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { TenderTypeRepository } from './tender-type.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { TenderType } from './tender-type.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([TenderType]), + AuthModule + ], + controllers: [TenderTypeController], + providers: [TenderTypeService,TenderTypeRepository] +}) +export class TenderTypeModule {} diff --git a/src/tables/tender-type/tender-type.repository.ts b/src/tables/tender-type/tender-type.repository.ts new file mode 100644 index 0000000..5601917 --- /dev/null +++ b/src/tables/tender-type/tender-type.repository.ts @@ -0,0 +1,11 @@ +import { DataSource, EntityRepository, Repository } from "typeorm"; +import { TenderType } from "./tender-type.entity"; +import { Injectable } from "@nestjs/common"; +@Injectable() +export class TenderTypeRepository extends Repository{ + constructor( + private datasource : DataSource + ){ + super(TenderType,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/tender-type/tender-type.service.ts b/src/tables/tender-type/tender-type.service.ts new file mode 100644 index 0000000..b20f6f8 --- /dev/null +++ b/src/tables/tender-type/tender-type.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { TenderTypeDto } from 'src/dto/tender-type.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { TenderTypeRepository } from './tender-type.repository'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; + +@Injectable() +export class TenderTypeService extends PcdFormGridService{ + + constructor( + @InjectRepository(TenderTypeRepository) + private tenderTypeRepository: TenderTypeRepository, + ) { + super(tenderTypeRepository); + } + +} diff --git a/src/tables/user-subcategory-master/user-subcategory-master.controller.ts b/src/tables/user-subcategory-master/user-subcategory-master.controller.ts new file mode 100644 index 0000000..85a6c9d --- /dev/null +++ b/src/tables/user-subcategory-master/user-subcategory-master.controller.ts @@ -0,0 +1,11 @@ +import { Controller } from '@nestjs/common'; +import { userSubCategoryDto } from 'src/dto/user-subcategory-master.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { UserSubcategoryMasterService } from './user-subcategory-master.service'; + +@Controller('user-subcategory-master') +export class UserSubcategoryMasterController extends PcdFormGridController{ + constructor(private usersubCategoryService: UserSubcategoryMasterService) { + super(usersubCategoryService) + } +} \ No newline at end of file diff --git a/src/tables/user-subcategory-master/user-subcategory-master.entity.ts b/src/tables/user-subcategory-master/user-subcategory-master.entity.ts new file mode 100644 index 0000000..6e64c10 --- /dev/null +++ b/src/tables/user-subcategory-master/user-subcategory-master.entity.ts @@ -0,0 +1,51 @@ +import { Pcduser } from "src/auth/pcduser.entity"; +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { tenderSubCategory } from "../tender-subcategory/tender-subcategory.entity"; +import { TenderCategory } from "../tender-category/tender-category.entity"; + +@Entity('user_subcategory_master') +export class userSubcategoryMaster extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:string + + @Column({ + name:'category', + type:"numeric", + // length:1000, + nullable:true + }) + Category:number + + @Column({ + name:'sub_category', + type:"numeric", + // length:1000, + nullable:true + }) + subCategory:number + + @Column({ + name:'userId', + type:"numeric", + // length:1000, + nullable:true + }) + userId:number + + + + @ManyToOne(() => Pcduser, (Pcduser) => Pcduser.userSubcategoryMaster, { eager: false }) + @JoinColumn([{ name: "userId", referencedColumnName: "userId" }]) + userD: Pcduser + + @ManyToOne(() => tenderSubCategory, (tenderSubCategory) => tenderSubCategory.userSubcategoryMaster, { eager: true }) + @JoinColumn([{ name: "sub_category", referencedColumnName: "id" }]) + tenderSubCategoryD: tenderSubCategory + + @ManyToOne(() => TenderCategory, (TenderCategory) => TenderCategory.userSubcategoryMaster, { eager: true }) + @JoinColumn([{ name: "category", referencedColumnName: "id" }]) + categoryD: tenderSubCategory +} \ No newline at end of file diff --git a/src/tables/user-subcategory-master/user-subcategory-master.module.ts b/src/tables/user-subcategory-master/user-subcategory-master.module.ts new file mode 100644 index 0000000..dddfb8b --- /dev/null +++ b/src/tables/user-subcategory-master/user-subcategory-master.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { UserSubcategoryMasterController } from './user-subcategory-master.controller'; +import { UserSubcategoryMasterService } from './user-subcategory-master.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { userSubcategoryMaster } from './user-subcategory-master.entity'; +import { userSubCategoryMasterRepo } from './user-subcategory-master.repository'; + +@Module({ + imports:[ + TypeOrmModule.forFeature([userSubcategoryMaster]) + ], + controllers: [UserSubcategoryMasterController], + providers: [UserSubcategoryMasterService,userSubCategoryMasterRepo] +}) +export class UserSubcategoryMasterModule {} diff --git a/src/tables/user-subcategory-master/user-subcategory-master.repository.ts b/src/tables/user-subcategory-master/user-subcategory-master.repository.ts new file mode 100644 index 0000000..60f5598 --- /dev/null +++ b/src/tables/user-subcategory-master/user-subcategory-master.repository.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { userSubcategoryMaster } from "./user-subcategory-master.entity"; + +@Injectable() +export class userSubCategoryMasterRepo extends Repository{ + constructor( + private datasource : DataSource + ){super(userSubcategoryMaster , datasource.createEntityManager())} +} \ No newline at end of file diff --git a/src/tables/user-subcategory-master/user-subcategory-master.service.ts b/src/tables/user-subcategory-master/user-subcategory-master.service.ts new file mode 100644 index 0000000..35a53ba --- /dev/null +++ b/src/tables/user-subcategory-master/user-subcategory-master.service.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { userSubCategoryDto } from 'src/dto/user-subcategory-master.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { userSubCategoryMasterRepo } from './user-subcategory-master.repository'; + +@Injectable() +export class UserSubcategoryMasterService extends PcdFormGridService{ + constructor( + @InjectRepository(userSubCategoryMasterRepo) + private userSubCategoryMasterRepo:userSubCategoryMasterRepo + ){super(userSubCategoryMasterRepo)} + +} \ No newline at end of file diff --git a/src/tables/userCategory-master/category.controller.ts b/src/tables/userCategory-master/category.controller.ts new file mode 100644 index 0000000..498431b --- /dev/null +++ b/src/tables/userCategory-master/category.controller.ts @@ -0,0 +1,37 @@ +import { Body, Controller, Get, Param, Post, Put, UseGuards } from '@nestjs/common'; +import { categoryDto } from 'src/dto/category.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { CategoryService } from './category.service'; +import { AuthGuard } from '@nestjs/passport'; +import { categoryRepository } from './category.repository'; +import { GetUser } from 'src/auth/dto/get-user.decorator'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; + +@UseGuards(AuthGuard()) +@Controller('category-master') +export class CategoryController extends PcdFormGridController{ + + constructor( + private categoryService: CategoryService, + ) { + super(categoryService); + } + @Get('getusercategory') + async getUserCategory( + // @Param('id') id : any, + @GetUser() user:PcduserDto + ){ + return await this.categoryService.getUserCategory(user.userId) + } + + @Post('edit') + async editCategory( + // @Param('id') id : any, + @GetUser() user:PcduserDto , + @Body() body : any + ){ + console.log("ji"); + return await this.categoryService.editCategory(user.userId,body) + } + +} \ No newline at end of file diff --git a/src/tables/userCategory-master/category.entity.ts b/src/tables/userCategory-master/category.entity.ts new file mode 100644 index 0000000..6e4938f --- /dev/null +++ b/src/tables/userCategory-master/category.entity.ts @@ -0,0 +1,38 @@ +import { Pcduser } from "src/auth/pcduser.entity"; +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { TenderCategory } from "../tender-category/tender-category.entity"; + +@Entity('user-category') +export class category extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:'category', + type:"numeric", + // length:1000, + nullable:true + }) + category:number + + @Column({ + name:'userId', + type:"numeric", + // length:1000, + nullable:true + }) + userId:number + + + @ManyToOne(() => Pcduser, (pcduser) => pcduser.category, { eager: false }) + @JoinColumn([{ name: "userId", referencedColumnName: "userId" }]) + userD: Pcduser + + @ManyToOne(() => TenderCategory, (TenderCategory) => TenderCategory.category, { eager: true }) + @JoinColumn([{ name: "category", referencedColumnName: "id" }]) + categoryD: TenderCategory +} + \ No newline at end of file diff --git a/src/tables/userCategory-master/category.module.ts b/src/tables/userCategory-master/category.module.ts new file mode 100644 index 0000000..1c22a89 --- /dev/null +++ b/src/tables/userCategory-master/category.module.ts @@ -0,0 +1,19 @@ +import { Module } from '@nestjs/common'; +import { CategoryController } from './category.controller'; +import { CategoryService } from './category.service'; +import { categoryRepository } from './category.repository'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { category } from './category.entity'; +import { AuthModule } from 'src/auth/auth.module'; +import { userSubCategoryMasterRepo } from '../user-subcategory-master/user-subcategory-master.repository'; +import { userSubcategoryMaster } from '../user-subcategory-master/user-subcategory-master.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([category,userSubcategoryMaster]), + AuthModule + ], + controllers: [CategoryController], + providers: [CategoryService,categoryRepository,userSubCategoryMasterRepo] +}) +export class CategoryModule {} diff --git a/src/tables/userCategory-master/category.repository.ts b/src/tables/userCategory-master/category.repository.ts new file mode 100644 index 0000000..c695577 --- /dev/null +++ b/src/tables/userCategory-master/category.repository.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { category } from "./category.entity"; + +@Injectable() +export class categoryRepository extends Repository{ + constructor( + private datasource:DataSource + ){ + super(category,datasource.createEntityManager()); + } +} \ No newline at end of file diff --git a/src/tables/userCategory-master/category.service.ts b/src/tables/userCategory-master/category.service.ts new file mode 100644 index 0000000..36bc96c --- /dev/null +++ b/src/tables/userCategory-master/category.service.ts @@ -0,0 +1,53 @@ +import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { category } from './category.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { categoryRepository } from './category.repository'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { FindManyOptions } from 'typeorm'; +import { categoryDto } from 'src/dto/category.dto'; +import { userSubCategoryMasterRepo } from '../user-subcategory-master/user-subcategory-master.repository'; +import { userSubCategoryDto } from 'src/dto/user-subcategory-master.dto'; + +@Injectable() +export class CategoryService extends PcdFormGridService{ + + constructor( + @InjectRepository(categoryRepository) + private categoryRepository: categoryRepository, + private userSubcategoryRepo : userSubCategoryMasterRepo + ) { + super(categoryRepository); + } + categoryDto: any; + +async getUserCategory(id){ + return await this.userSubcategoryRepo.find({where:{userId:id}}) +} + + async editCategory(id, body) { + try { + if(body) + await this.userSubcategoryRepo.delete({ userId: id }) + + for (let c of body) { + let categoryDto = new userSubCategoryDto() + categoryDto.userId = id + categoryDto.Category = c.Category + categoryDto.subCategory = c.subCategory + console.log("categoryDto-------", categoryDto); + + let u= await this.userSubcategoryRepo.save(categoryDto) + console.log("hehe",u); + + + } + return { data: "Data Updated Successfully" }; + } catch (err) { + return { data: "Failed to update data" }; + } + + } +} + + diff --git a/src/transactions/images/images.controller.ts b/src/transactions/images/images.controller.ts new file mode 100644 index 0000000..133ed8e --- /dev/null +++ b/src/transactions/images/images.controller.ts @@ -0,0 +1,13 @@ +import { Controller } from '@nestjs/common'; +import { galleryDto } from 'src/dto/gallery.dto'; +import { PcdTransactionController } from 'src/framework/beans/pcd-transaction.controller'; +import { ImagesService } from './images.service'; + +@Controller('images') +export class ImagesController extends PcdTransactionController { + constructor( + private imageService: ImagesService + ) { + super(imageService); + } +} \ No newline at end of file diff --git a/src/transactions/images/images.module.ts b/src/transactions/images/images.module.ts new file mode 100644 index 0000000..7d006e9 --- /dev/null +++ b/src/transactions/images/images.module.ts @@ -0,0 +1,21 @@ +import { Module } from '@nestjs/common'; +import { ImagesController } from './images.controller'; +import { ImagesService } from './images.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { gallery } from 'src/tables/gallery/gallery.entity'; +import { subGallery } from 'src/tables/sub-gallery/sub-gallery.entity'; +import { AuthModule } from 'src/auth/auth.module'; +import { galleryRepository } from 'src/tables/gallery/gallery.repository'; +import { subGalleryRepository } from 'src/tables/sub-gallery/sub-gallery.repository'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([gallery, + subGallery, + ]), + AuthModule + ], + controllers: [ImagesController], + providers: [ImagesService,galleryRepository,subGalleryRepository] +}) +export class ImagesModule {} diff --git a/src/transactions/images/images.service.ts b/src/transactions/images/images.service.ts new file mode 100644 index 0000000..3e140a1 --- /dev/null +++ b/src/transactions/images/images.service.ts @@ -0,0 +1,86 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { galleryDto } from 'src/dto/gallery.dto'; +import { PcdTransactionService } from 'src/framework/beans/pcd-transaction.service'; +import { TransactionDetailDto } from 'src/framework/custom/transaction-detail.dto'; +import { galleryRepository } from 'src/tables/gallery/gallery.repository'; +import { subGalleryRepository } from 'src/tables/sub-gallery/sub-gallery.repository'; +import { DataSource, FindManyOptions } from 'typeorm'; +import * as fs from 'fs'; + +@Injectable() +export class ImagesService extends PcdTransactionService{ + MAIN_KEY: string = 'id'; + + DETAIL_DATA_FORMAT: TransactionDetailDto[] = [ + { + detailName: "subGallery", repo: this.subGalleryRepository, + filter: [{ columnName: "galleryId", headerColumn: "id" }], + foreignKeyColumnName: "galleryId", + childDetail: [], + addtionalSettingOfRowsInInsertion: [], + orderByColumn: { columnName: "id", sort: "DESC" } + }, + // { + // detailName: "covers", repo: this.subGalleryRepository, + // filter: [{ columnName: "tenderId", headerColumn: "id" }], + // foreignKeyColumnName: "tenderId", + // childDetail: [], + // addtionalSettingOfRowsInInsertion: [], + // orderByColumn: { columnName: "id", sort: "DESC" } + // } + ]; + constructor( + private conn: DataSource, + @InjectRepository(galleryRepository) + private galleryRepository: galleryRepository, + @InjectRepository(subGalleryRepository) + private subGalleryRepository: subGalleryRepository, + + ) { + super(conn, galleryRepository); + // this.TenderMasterRepository = conn.getCustomRepository(SisPaymentDetailRepository) + } + async postFindList(filter: FindManyOptions, result: galleryDto[]): Promise { + + let res = [] + for (let r of result) { + res.push(await this.getDetailData(r,{ where: {} }, this.DETAIL_DATA_FORMAT)) + } + return res + } + + async preCreateOne(body: galleryDto, user: any): Promise { + + if (body.id || body.id != null) { + let image = await this.galleryRepository.findOne({ where: { id: body.id } }) + if (image) { + if (image.imageUrl != body.imageUrl) { + const filePath = './uploads/Pictures/'+ image.imageUrl; + await fs.promises.unlink(filePath); + } + } + + } + return true + } + + async preDeleteOne(filter: FindManyOptions, id:any ): Promise { + + let gallery = await this.galleryRepository.findOne({where:{id:id}}) + if(gallery){ + const filePath = './uploads/Pictures/'+ gallery.imageUrl; + await fs.promises.unlink(filePath); + } + + let subGallery = await this.subGalleryRepository.find({where:{galleryId:id}}) + if(subGallery){ + for(let image of subGallery){ + const filePath = './uploads/Pictures/'+ image.imageUrl; + await fs.promises.unlink(filePath); + } + } + + return true + } +} \ No newline at end of file diff --git a/src/transactions/tender/tender.controller.ts b/src/transactions/tender/tender.controller.ts new file mode 100644 index 0000000..1cba482 --- /dev/null +++ b/src/transactions/tender/tender.controller.ts @@ -0,0 +1,61 @@ +import { Body, Controller, Get, UseGuards,Query, Post, Param } from '@nestjs/common'; +import { TenderDetailDto } from 'src/dto/tender-master.dto'; +import { PcdTransactionController } from 'src/framework/beans/pcd-transaction.controller'; +import { TenderService } from './tender.service'; +import { AuthGuard } from '@nestjs/passport'; + +import { FindManyOptions } from 'typeorm'; +import { GetUser } from 'src/auth/dto/get-user.decorator'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; + +@UseGuards(AuthGuard()) + +@Controller('tender') +export class TenderController extends PcdTransactionController { + constructor( + private tenderService: TenderService + ) { + super(tenderService); + } + @Get('admin') + async getTender( + @Query() filter: FindManyOptions, + @GetUser() user:PcduserDto + ) { + + return this.tenderService.GetAdminTenderD(filter,user) + } + @UseGuards(AuthGuard()) + @Get('admin/dashboard') + async getDashboard() { + + return this.tenderService.GetAdminDashboard() + } + + @Post('status/:id') //STATUS - S=submitted,Y=Active,N=Inactive + async tenderStatus( //STATUS = S is when the the tender is created(super admin needs to verify status to Y(Active) or N(Inactive) + @Param('id') id:string, + @Body() body:{activeYn:string}, + @GetUser() user:PcduserDto + ) { + return this.tenderService.tenderStatus(id,body,user) + } + + @Get('user') + async getTenderByCategory( + @Query() filter: FindManyOptions, + @GetUser() user:PcduserDto + ) { + console.log("hihihui"); + + return this.tenderService.getTenderByCategory(user) + } + +// @Get('users1') +// async userClosedTender( +// @Query() filter: FindManyOptions, +// @GetUser() user:PcduserDto +// ) { +// return this.tenderService.userClosedTender(user) +// } +} diff --git a/src/transactions/tender/tender.module.ts b/src/transactions/tender/tender.module.ts new file mode 100644 index 0000000..d927570 --- /dev/null +++ b/src/transactions/tender/tender.module.ts @@ -0,0 +1,38 @@ +import { Module } from '@nestjs/common'; +import { TenderController } from './tender.controller'; +import { TenderService } from './tender.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { TenderMasterRepository } from 'src/tables/tender-master/tender-master.repository'; +import { AuthModule } from 'src/auth/auth.module'; +import { TenderMaster } from 'src/tables/tender-master/tender-master.entity'; +import { TenderDoc } from 'src/tables/tender-documents/tender-doc.entity'; +import { CoverDoc } from 'src/tables/covers-master/covers-master.entity'; +import { tenderDocRepository } from 'src/tables/tender-documents/tender-doc.repository'; +import { CoverMasterRepository } from 'src/tables/covers-master/covers-master.repository'; +import { categoryRepository } from 'src/tables/userCategory-master/category.repository'; +import { tenderSubCategoryMaster } from 'src/tables/tender-subcategory-master/tender-subcategory-master.entity'; +import { tenderSubCategoryMasterRepository } from 'src/tables/tender-subcategory-master/tender-subcategory-master.repository'; +import { closedTenderUsersRepository } from 'src/tables/closed-tender-users/closed-tender-users.repository'; +import { tenderSubCategoryRepository } from 'src/tables/tender-subcategory/tender-subcategory.repository'; +import { userSubCategoryMasterRepo } from 'src/tables/user-subcategory-master/user-subcategory-master.repository'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([TenderMaster, + TenderDoc, + CoverDoc,tenderSubCategoryMaster]), + AuthModule + ], + controllers: [TenderController], + providers: [TenderService, + TenderMasterRepository, + tenderDocRepository, + CoverMasterRepository, + tenderSubCategoryMasterRepository, + categoryRepository, + closedTenderUsersRepository, + tenderSubCategoryRepository, + userSubCategoryMasterRepo + ] +}) +export class TenderModule {} diff --git a/src/transactions/tender/tender.service.ts b/src/transactions/tender/tender.service.ts new file mode 100644 index 0000000..e365fa6 --- /dev/null +++ b/src/transactions/tender/tender.service.ts @@ -0,0 +1,279 @@ +import { BadRequestException, Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { PcduserDto } from 'src/auth/dto/pcd-user.dto'; +import { TenderDetailDto } from 'src/dto/tender-master.dto'; +import { PcdTransactionService } from 'src/framework/beans/pcd-transaction.service'; +import { TransactionDetailDto } from 'src/framework/custom/transaction-detail.dto'; +import { closedTenderUsersRepository } from 'src/tables/closed-tender-users/closed-tender-users.repository'; +import { CoverMasterRepository } from 'src/tables/covers-master/covers-master.repository'; +import { tenderDocRepository } from 'src/tables/tender-documents/tender-doc.repository'; +import { TenderMasterRepository } from 'src/tables/tender-master/tender-master.repository'; +import { tenderSubCategoryMaster } from 'src/tables/tender-subcategory-master/tender-subcategory-master.entity'; +import { tenderSubCategoryMasterRepository } from 'src/tables/tender-subcategory-master/tender-subcategory-master.repository'; +import { tenderSubCategoryRepository } from 'src/tables/tender-subcategory/tender-subcategory.repository'; +import { userSubCategoryMasterRepo } from 'src/tables/user-subcategory-master/user-subcategory-master.repository'; +import { categoryRepository } from 'src/tables/userCategory-master/category.repository'; +import { Admin, DataSource, FindManyOptions, In, LessThanOrEqual, MoreThanOrEqual, Not } from 'typeorm'; + +@Injectable() +export class TenderService extends PcdTransactionService{ + MAIN_KEY: string = 'id'; + + DETAIL_DATA_FORMAT: TransactionDetailDto[] = [ + { + detailName: "tenderDoc", repo: this.tenderDocRepository, + filter: [{ columnName: "tenderId", headerColumn: "id" }], + foreignKeyColumnName: "tenderId", + childDetail: [], + addtionalSettingOfRowsInInsertion: [], + orderByColumn: { columnName: "id", sort: "DESC" } + }, + { + detailName: "covers", repo: this.coverMasterRepository, + filter: [{ columnName: "tenderId", headerColumn: "id" }], + foreignKeyColumnName: "tenderId", + childDetail: [], + addtionalSettingOfRowsInInsertion: [], + orderByColumn: { columnName: "id", sort: "DESC" } + }, + { + detailName: "subCategoryMaster", repo: this.tenderSubCategoryMasterRepository, //tender sub category + filter: [{ columnName: "tenderId", headerColumn: "id" }], + foreignKeyColumnName: "tenderId", + childDetail: [], + addtionalSettingOfRowsInInsertion: [], + orderByColumn: { columnName: "id", sort: "DESC" } + }, + { + detailName: "closedTenderUsers", repo: this.closedTenderUsersRepo, + filter: [{ columnName: "tenderId", headerColumn: "id" }], + foreignKeyColumnName: "tenderId", + childDetail: [], + addtionalSettingOfRowsInInsertion: [], + orderByColumn: { columnName: "id", sort: "DESC" } + } + ]; + constructor( + private conn: DataSource, + @InjectRepository(TenderMasterRepository) + private tenderMasterRepository: TenderMasterRepository, + @InjectRepository(tenderSubCategoryMasterRepository) + private tenderSubCategoryMasterRepository: tenderSubCategoryMasterRepository, + @InjectRepository(CoverMasterRepository) + private coverMasterRepository: CoverMasterRepository, + @InjectRepository(tenderDocRepository) + private tenderDocRepository: tenderDocRepository, + private tenderCategoryrepo: categoryRepository, + private tendemasterRepo: TenderMasterRepository, + private closedTenderUsersRepo: closedTenderUsersRepository, + private tenderSubCategory: tenderSubCategoryRepository, + private usersubCategoryRepo: userSubCategoryMasterRepo + ) { + super(conn, tenderMasterRepository); + // this.TenderMasterRepository = conn.getCustomRepository(SisPaymentDetailRepository) + } + async preCreateOne(body: TenderDetailDto, user): Promise { + + console.log("useris------------", user); + console.log("activeYn-----------", body.activeYn); + let tender + if (body.id) { + tender = await this.tendemasterRepo.findOne({ where: { id: body.id } }) + console.log('tender', tender.publishDate); + if (user.secuLevel == 'SuperAdmin' && tender.publishDate < new Date() && tender.secuLevel != 'S' || user.secuLevel == 'Admin' && tender.publishDate < new Date() && tender.secuLevel != 'S') { + throw new BadRequestException('Cannot modify Tender after publish Date.') + } else if (tender.activeYn == 'Y' && user.secuLevel == 'Analyst' || tender.activeYn == 'Y' && user.secuLevel == 'Admin') { + throw new UnauthorizedException('You dont have the right to edit tender details after publishing tender') + } + } + if (user.secuLevel != 'Analyst' && user.secuLevel != 'Admin' && user.secuLevel != 'SuperAdmin') { + throw new UnauthorizedException('You dont have the right to create a new category and submit a tender') + } + return true; + + + } + async preFindList(filter: FindManyOptions, user: PcduserDto): Promise { + + if (!filter.where) filter.where = {}; + if (!user || user.secuLevel == 'User') { + throw new BadRequestException("You don't have the right to access this Url") + // filter.where["publishDate"] = LessThanOrEqual(new Date()); + // filter.where["bidOpenDate"] = MoreThanOrEqual(new Date()); + // let userCategory = await this.tenderCategoryrepo.find({ where: { userId: parseInt(user.userId) } }) + // const categoryArray = []; + + // for (let category of userCategory) { + // console.log('userCategory', category.category); + // categoryArray.push(category.category); + // } + // filter.where["tenderCategory"] = In(categoryArray) + + } + else { + filter.where = {}; + } + return true; + } + async GetAdminTenderD(filter: FindManyOptions, user) { + // console.log(user); + if (user.secuLevel == 'SuperAdmin' || user.secuLevel == 'Admin' || user.secuLevel == 'Analyst') { + return this.tenderMasterRepository.find(filter) + } else if (user.secuLevel == 'User') { + return this.tenderMasterRepository.find(filter) + } + else { + throw new UnauthorizedException('Permission Denied to View Tender.') + } + } + + async GetAdminDashboard() { + let query = `select id, title , bid_open_date as bidOpenDate, publish_date as publishDate from tender_master tm order by id desc` + return await this.tenderMasterRepository.query(query) + } + + async tenderStatus(id, body, user) { + console.log("secuLevel====", user.secuLevel); + + if (user.secuLevel == 'SuperAdmin' || user.secuLevel == 'Admin') { + let tender = await this.tenderMasterRepository.findOne({ where: { id: id } }) + if (!tender) { + throw new NotFoundException("Tender Details not Found") + } + tender.activeYn = body.activeYn; + this.tenderMasterRepository.save(tender); + if (body.activeYn == 'Y') { + return { data: "Tender is Active" } + } else { + return { data: "Tender is Inactive" } + } + } else { + throw new UnauthorizedException('Insufficient Rights to Update Status.') + } + } + + + async getTenderByCategory(user) { + const categoryArray = []; + let subCategoryArray = []; + + let subcategory = await this.usersubCategoryRepo.find({ where: { userId: parseInt(user.userId) } }) + for (let s of subcategory) { + // console.log('userCategory', category.category); + subCategoryArray.push(s.subCategory); + } + + // let userCategory = await this.tenderCategoryrepo.find({ where: { userId: parseInt(user.userId) } }) + // // console.log(userCategory); + + // for (let category of userCategory) { + // // console.log('userCategory', category.category); + // categoryArray.push(category.category); + // } + // // console.log("usercategory", categoryArray); + // for( let category of categoryArray){ + // let subCategory = await this.tenderSubCategory.find({where:{tenderCategory : category}}) + // for(let id of subCategory){ + // subCategoryArray.push(id.id) + // } + // } + + /////////////////////////////////////// + + let filter: any = {}; + + filter.where = { + publishDate: LessThanOrEqual(new Date()), + bidOpenDate: MoreThanOrEqual(new Date()), + tenderType: Not(7), + activeYn: 'Y' + }; + let tender = await this.tenderMasterRepository.find(filter) + const tenderArray = []; + + for (let t of tender) { + // console.log('userCategory', t.id); + tenderArray.push(t.id); + } + // console.log("tenderID", tenderArray); + + //////////////////////////////////////////// + + + + + let tenderfinalArray = [] + let userTenderDetails = [] + for (let tender of tenderArray) { + let tenderSubCat = await this.tenderSubCategoryMasterRepository.find({ where: { tenderId: tender } }) + // console.log("length", tenderSubCat.length); + + for (let tendersub of tenderSubCat) { + tenderfinalArray.push(tendersub.subCategoryId); + } + + // console.log("subCategoryArray", subCategoryArray); + + + let CategoryresultArray = []; + for (const element of tenderfinalArray) { + // console.log("element=======",element); + + if (subCategoryArray.includes(element)) { + CategoryresultArray.push([element]); + } + } + // console.log("ressss", CategoryresultArray); + // console.log("resultArray.length", CategoryresultArray.length); + + if (CategoryresultArray && CategoryresultArray.length > 0) { + let tenderRes = await this.tenderMasterRepository.findOne({ where: { id: tender } }) + userTenderDetails.push([tenderRes]) + } + tenderfinalArray = [] + CategoryresultArray = [] + // subCategoryArray = [] + } + // console.log("🤣🤣🤣",userTenderDetails.length); + + let closedTender = await this.userClosedTender(user) + // console.log("closedTender", closedTender.length); + // console.log("userTenderDetails", userTenderDetails.length); + // let combinedData = closedTender.concat(userTenderDetails); + let flattenedArray = [...closedTender, ...userTenderDetails]; + let combinedArray = closedTender.concat(...userTenderDetails); + return combinedArray + } + + async userClosedTender(user) { + let filter: any = {}; + filter.where = { + publishDate: LessThanOrEqual(new Date()), + bidOpenDate: MoreThanOrEqual(new Date()), + tenderType: 7, + activeYn: 'Y' + }; + let tender = await this.tenderMasterRepository.find(filter) + // console.log(tender); + + let tenderArray = [] + let UserArray = [] + for (let t of tender) { + // tenderArray.push(t.id) + let userTender = await this.closedTenderUsersRepo.find({ where: { tenderId: t.id } }) + for (let user of userTender) { + UserArray.push(user.userId) + } + let specificUserId = user.userId; + if (UserArray.includes(specificUserId)) { + tenderArray.push(t) + } + UserArray = [] + } + + return tenderArray + + + + } +} diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts new file mode 100644 index 0000000..50cda62 --- /dev/null +++ b/test/app.e2e-spec.ts @@ -0,0 +1,24 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; +import { AppModule } from './../src/app.module'; + +describe('AppController (e2e)', () => { + let app: INestApplication; + + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [AppModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + it('/ (GET)', () => { + return request(app.getHttpServer()) + .get('/') + .expect(200) + .expect('Hello World!'); + }); +}); diff --git a/test/jest-e2e.json b/test/jest-e2e.json new file mode 100644 index 0000000..e9d912f --- /dev/null +++ b/test/jest-e2e.json @@ -0,0 +1,9 @@ +{ + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": ".", + "testEnvironment": "node", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } +} diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..26c30d4 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "test", "dist"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1ba6c1e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "es2017", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "resolveJsonModule": true, + } +}