init push

main
Accurate 2 years ago
commit 12765d00c2

@ -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',
},
};

109
.gitignore vendored

@ -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

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

@ -0,0 +1,3 @@
# movie-bucket-project-api
Online Movie Show Management and Ticket Booking API

@ -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"

@ -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'

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

@ -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"
}
}

@ -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) {}
}

@ -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<TokenDto> {
return this.authService.signIn(authCredentialDto, req.ip);
}
@Get()
async getall() {
return this.authService
}
@Post('/signup')
async signUp(@Body() pcdUserDto: PcduserDto): Promise<any> {
// 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<any> {
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<void> {
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<void> {
// return await this.authService.resendOtp(body,flag);
// }
@Post('/verifyOtp/:flag')
async verifyOtp(
@Body() body: { otp: string, email: string },
@Param('flag') flag: string
): Promise<any> {
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)
}
}

@ -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 { }

File diff suppressed because it is too large Load Diff

@ -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
}
}

@ -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;
}

@ -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
}

@ -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;
},
);

@ -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 };
}

@ -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
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -0,0 +1,14 @@
export class TokenDto {
accessToken: string;
refreshToken: string;
emailId: string;
module: string;
changePassword?:string
secuLevel?:string
}

@ -0,0 +1,16 @@
export class UserBankDto {
custId:string;
custName:string;
mobile:string;
mPin:string;
tPin:string;
email:string;
bankId:string;
}

@ -0,0 +1,13 @@
export interface JwtPayload {
userId: string;
emailId: string;
userName: string;
sessionId: string;
module: string;
}

@ -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;
}
}

@ -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;
}

@ -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<Pcdotp>{
constructor(private dataSource: DataSource) {
super(Pcdotp, dataSource.createEntityManager());
}
private logger = new Logger('PcdotpRepository'); // for logging
}

@ -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<boolean> {
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<boolean> {
// 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[]
}

@ -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<Pcduser>{
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<any> {
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<string[]> {
/*
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<string> {
return await this.hashPassword(password, salt);
}
private async hashPassword(password: string, salt: string): Promise<string> {
return await bcrypt.hash(password, salt);
}
}

@ -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
};

@ -0,0 +1,6 @@
export class basicCategoryDto {
id:number;
productCategory:string;
}

@ -0,0 +1,9 @@
export class categoryDto{
id?:number
category : number
userId? : number
}

@ -0,0 +1,7 @@
export class closedTenderUsersDto{
tenderId : number
userId : number
}

@ -0,0 +1,3 @@
export class CommonDto{
marquee : string
}

@ -0,0 +1,10 @@
export class CoverMasterDto{
tenderId:number;
coverType:string;
Description:string;
fileFormat:string
}

@ -0,0 +1,6 @@
export class coverTypeDto{
id:number
coverType:string
}

@ -0,0 +1,7 @@
export class DocumentTypeDto{
id:number;
documentType:string;
docCategory:string
}

@ -0,0 +1,6 @@
export class EmdFeeTypeDto {
id:number;
emdFeeType:string;
}

@ -0,0 +1,5 @@
export class FileFormatLovDto{
id:number;
fileFormat:string;
}

@ -0,0 +1,4 @@
export class FormOfContractDto {
id: number;
formOfContract: string;
}

@ -0,0 +1,15 @@
export class galleryDto{
id?:number
category : string
imageUrl : string
title: string
description:string
projectType:string
}

@ -0,0 +1,14 @@
export class MailConfigDto {
smtpUserName: string;
smtpId: number;
smtpPassword: string;
smtpHost: string;
encryptionType: string;
smtpPort: string;
}

@ -0,0 +1,16 @@
export class MenuDto {
menuId: number;
menuName: string;
moduleId: number;
menuIcon: string;
menuOrder: number;
routerLink: string;
menuParentId: number;
}

@ -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
}

@ -0,0 +1,7 @@
export class PaymentModeDto{
id:number ;
paymentMode:string;
}

@ -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
}

@ -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);
}
}

@ -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;
}

@ -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
}

@ -0,0 +1,17 @@
export class PurchaseDto {
amount: number;
application: string;
mobile: string;
email: string;
type: string;
menuId?: string;
}

@ -0,0 +1,11 @@
export class reportAuthenticationDto{
id:number;
adminUsers:string
key:number[]
}

@ -0,0 +1,10 @@
export class revisedTenderDto{
userId : string
tenderId : number
revisedDocument : string
requotedOrder : number
}

@ -0,0 +1,7 @@
export class subGalleryDto{
gallery_id : number
imageUrl : string
}

@ -0,0 +1,6 @@
export class TenderCategoryDto{
tenderCategory:string;
active : boolean
}

@ -0,0 +1,16 @@
export class TenderDocumentDto{
tenderId:number;
docName:string;
description:string;
docType:string;
documentSize:number;
documentCategory:string;
userId?:string
}

@ -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
}

@ -0,0 +1,6 @@
export class tenderSubcategoryMasterDto{
tenderId : number
subCategoryId : number
}

@ -0,0 +1,7 @@
export class tenderSubCategoryDto{
tenderSubCategory:string;
active : boolean
}

@ -0,0 +1,6 @@
export class TenderTypeDto{
id:number;
tenderType:string;
}

@ -0,0 +1,10 @@
export class userSubCategoryDto{
id?:string
Category:number
subCategory:number
userId:number
}

@ -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();
// }
}

@ -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 { }

@ -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 = `
<!doctype html>
<html lang="en-US">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>OTP</title>
<meta name="description" content="New Account Email Template.">
<style type="text/css">
a:hover {
text-decoration: underline !important;
}
img {
max-width: 100%;
height: auto;
}
p {
font-size: 1em;
/* Other styles */
}
</style>
</head>
<body marginheight="0" topmargin="0" marginwidth="0" style="margin: 0px; background-color: #f2f3f8;" leftmargin="0">
<!-- 100% body table -->
<table cellspacing="0" border="0" cellpadding="0" width="100%" bgcolor="#f2f3f8"
style="@import url(https://fonts.googleapis.com/css?family=Rubik:300,400,500,700|Open+Sans:300,400,600,700); font-family: 'Open Sans', sans-serif;">
<tr>
<td>
<table style="background-color: #f2f3f8; max-width:800px; margin:0 auto;" width="100%" border="0"
align="center" cellpadding="0" cellspacing="0">
<tr>
<td style="height:80px;">&nbsp;</td>
</tr>
<tr>
<td style="text-align:center;">
<a href="https://artnouveau.in/" title="" target="_blank">
<img width="60" src="https://tender.artnouveau.in/assets/img/Art-n-Artiect-removebg-preview.png" title="logo" alt="logo">
</a>
<h3 style="font-family: "Lucida Console", "Courier New", monospace;">Artnouveau Architects</h3>
</td>
</tr>
<tr>
<td style="height:20px;">&nbsp;</td>
</tr>
<tr>
<td>
<table width="95%" border="0" align="center" cellpadding="0" cellspacing="0"
style="max-width:670px; background:#fff; border-radius:3px; text-align:center;-webkit-box-shadow:0 6px 18px 0 rgba(0,0,0,.06);-moz-box-shadow:0 6px 18px 0 rgba(0,0,0,.06);box-shadow:0 6px 18px 0 rgba(0,0,0,.06);">
<tr>
<td style="height:40px;">&nbsp;</td>
</tr>
<tr>
<td style="padding:0 35px;">
<p style="font-size:15px; color:#455056; margin:8px 0 0; line-height:24px;">
Dear customer , <br>
<strong>
${content} <br>
For any inquiries or clarifications, please contact <br><br>
<br>
<div style="">
<div style="text-align: center; width:95%">
<p style="text-align: start;"><strong>Name:</strong>Subash</p>
<p style="text-align: start;"><strong>Email:</strong> subash@artnouveau.in</p>
<p style="text-align: start;"><strong>Phone:</strong> +91 94469 64558</p>
</div>
<br>
<div style="text-align: center; width:95%">
<p style="text-align: start;"><strong>Name:</strong>Boncy</p>
<p style="text-align: start;"><strong>Email:</strong> boncy@artnouveau.in</p>
<p style="text-align: start;"><strong>Phone:</strong> +91 85473 42848</p>
</div>
</div>
<br>
<br>
Best regards,<br>
Artnouveau Architects</strong></p>
<span
style="display:inline-block; vertical-align:middle; margin:29px 0 26px; border-bottom:1px solid #cecece; width:100px;"></span>
</td>
</tr>
<tr>
<td style="height:40px;">&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="height:20px;">&nbsp;</td>
</tr>
<tr>
<td style="text-align:center;">
<p style="font-size:14px; color:rgba(69, 80, 86, 0.7411764705882353); line-height:18px; margin:0 0 0;">&copy;<strong> <a href="https://www.artnouveau.in/" >www.artnouveau.in</a></strong> </p>
</td>
</tr>
<tr>
<td style="height:80px;">&nbsp;</td>
</tr>
</table>
</td>
</tr>
</table>
<!--/100% body table-->
</body>
</html> `;
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 = `
<!doctype html>
<html lang="en-US">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>OTP</title>
<meta name="description" content="New Account Email Template.">
<style type="text/css">
a:hover {
text-decoration: underline !important;
}
img {
max-width: 100%;
height: auto;
}
p {
font-size: 1em;
/* Other styles */
}
</style>
</head>
<body marginheight="0" topmargin="0" marginwidth="0" style="margin: 0px; background-color: #f2f3f8;" leftmargin="0">
<!-- 100% body table -->
<table cellspacing="0" border="0" cellpadding="0" width="100%" bgcolor="#f2f3f8"
style="@import url(https://fonts.googleapis.com/css?family=Rubik:300,400,500,700|Open+Sans:300,400,600,700); font-family: 'Open Sans', sans-serif;">
<tr>
<td>
<table style="background-color: #f2f3f8; max-width:800px; margin:0 auto;" width="100%" border="0"
align="center" cellpadding="0" cellspacing="0">
<tr>
<td style="height:80px;">&nbsp;</td>
</tr>
<tr>
<td style="text-align:center;">
<a href="https://artnouveau.in/" title="" target="_blank">
<img width="60" src="https://tender.artnouveau.in/assets/img/Art-n-Artiect-removebg-preview.png" title="logo" alt="logo">
</a>
<h3 style="font-family: "Lucida Console", "Courier New", monospace;">Artnouveau Architects</h3>
</td>
</tr>
<tr>
<td style="height:20px;">&nbsp;</td>
</tr>
<tr>
<td>
<table width="95%" border="0" align="center" cellpadding="0" cellspacing="0"
style="max-width:670px; background:#fff; border-radius:3px; text-align:center;-webkit-box-shadow:0 6px 18px 0 rgba(0,0,0,.06);-moz-box-shadow:0 6px 18px 0 rgba(0,0,0,.06);box-shadow:0 6px 18px 0 rgba(0,0,0,.06);">
<tr>
<td style="height:40px;">&nbsp;</td>
</tr>
<tr>
<td style="padding:0 35px;">
<p style="font-size:15px; color:#455056; margin:8px 0 0; line-height:24px;">
Dear Customer , <br>
<strong> We are excited to inform you that a <a style="color:red;">${t.title}</a> tender in the <a style="color:red;">${t.tenderCategoryD['productCategory']}</a> category will been added on our ArtNouveau website.<br><br>
You can view the details on <a style="color:red;">${publishDate}</a> and submit your bids by visiting the website at <strong> <a href="tender.artnouveau.in/#/auth/login" >tender.artnouveau.in</a></strong> <br><br>
For any inquiries or clarifications, please contact <br><br>
<br>
<div style="">
<div style="text-align: center; width:95%">
<p style="text-align: start;"><strong>Name:</strong>Subash</p>
<p style="text-align: start;"><strong>Email:</strong> subash@artnouveau.in</p>
<p style="text-align: start;"><strong>Phone:</strong> +91 94469 64558</p>
</div>
<br>
<div style="text-align: center; width:95%">
<p style="text-align: start;"><strong>Name:</strong>Boncy</p>
<p style="text-align: start;"><strong>Email:</strong> boncy@artnouveau.in</p>
<p style="text-align: start;"><strong>Phone:</strong> +91 85473 42848</p>
</div>
</div>
<br>
<br>
Best regards,<br>
Artnouveau Architects</strong></p>
<span
style="display:inline-block; vertical-align:middle; margin:29px 0 26px; border-bottom:1px solid #cecece; width:100px;"></span>
</td>
</tr>
<tr>
<td style="height:40px;">&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="height:20px;">&nbsp;</td>
</tr>
<tr>
<td style="text-align:center;">
<p style="font-size:14px; color:rgba(69, 80, 86, 0.7411764705882353); line-height:18px; margin:0 0 0;">&copy;<strong> <a href="https://www.artnouveau.in/" >www.artnouveau.in</a></strong> </p>
</td>
</tr>
<tr>
<td style="height:80px;">&nbsp;</td>
</tr>
</table>
</td>
</tr>
</table>
<!--/100% body table-->
</body>
</html>`
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<T>(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 = `
<!doctype html>
<html lang="en-US">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>OTP</title>
<meta name="description" content="New Account Email Template.">
<style type="text/css">
a:hover {
text-decoration: underline !important;
}
img {
max-width: 100%;
height: auto;
}
p {
font-size: 1em;
/* Other styles */
}
</style>
</head>
<body marginheight="0" topmargin="0" marginwidth="0" style="margin: 0px; background-color: #f2f3f8;" leftmargin="0">
<!-- 100% body table -->
<table cellspacing="0" border="0" cellpadding="0" width="100%" bgcolor="#f2f3f8"
style="@import url(https://fonts.googleapis.com/css?family=Rubik:300,400,500,700|Open+Sans:300,400,600,700); font-family: 'Open Sans', sans-serif;">
<tr>
<td>
<table style="background-color: #f2f3f8; max-width:800px; margin:0 auto;" width="100%" border="0"
align="center" cellpadding="0" cellspacing="0">
<tr>
<td style="height:80px;">&nbsp;</td>
</tr>
<tr>
<td style="text-align:center;">
<a href="https://artnouveau.in/" title="" target="_blank">
<img width="60" src="https://tender.artnouveau.in/assets/img/Art-n-Artiect-removebg-preview.png" title="logo" alt="logo">
</a>
<h3 style="font-family: "Lucida Console", "Courier New", monospace;">Artnouveau Architects</h3>
</td>
</tr>
<tr>
<td style="height:20px;">&nbsp;</td>
</tr>
<tr>
<td>
<table width="95%" border="0" align="center" cellpadding="0" cellspacing="0"
style="max-width:670px; background:#fff; border-radius:3px; text-align:center;-webkit-box-shadow:0 6px 18px 0 rgba(0,0,0,.06);-moz-box-shadow:0 6px 18px 0 rgba(0,0,0,.06);box-shadow:0 6px 18px 0 rgba(0,0,0,.06);">
<tr>
<td style="height:40px;">&nbsp;</td>
</tr>
<tr>
<td style="padding:0 35px;">
<p style="font-size:15px; color:#455056; margin:8px 0 0; line-height:24px;">
Dear Customer , <br>
<strong> We are excited to inform you that a <a style="color:red;">${t.title}</a> closed tender in the <a style="color:red;">${t.tenderCategoryD['productCategory']}</a> category will been added on our ArtNouveau website.<br><br>
You can view the details on <a style="color:red;">${publishDate}</a> and submit your bids by visiting the website at <strong> <a href="tender.artnouveau.in/#/auth/login" >tender.artnouveau.in</a></strong> <br><br>
For any inquiries or clarifications, please contact <br><br>
<br>
<div style="">
<div style="text-align: center; width:95%">
<p style="text-align: start;"><strong>Name:</strong>Subash</p>
<p style="text-align: start;"><strong>Email:</strong> subash@artnouveau.in</p>
<p style="text-align: start;"><strong>Phone:</strong> +91 94469 64558</p>
</div>
<br>
<div style="text-align: center; width:95%">
<p style="text-align: start;"><strong>Name:</strong>Boncy</p>
<p style="text-align: start;"><strong>Email:</strong> boncy@artnouveau.in</p>
<p style="text-align: start;"><strong>Phone:</strong> +91 85473 42848</p>
</div>
</div>
<br>
<br>
Best regards,<br>
Artnouveau Architects</strong></p>
<span
style="display:inline-block; vertical-align:middle; margin:29px 0 26px; border-bottom:1px solid #cecece; width:100px;"></span>
</td>
</tr>
<tr>
<td style="height:40px;">&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="height:20px;">&nbsp;</td>
</tr>
<tr>
<td style="text-align:center;">
<p style="font-size:14px; color:rgba(69, 80, 86, 0.7411764705882353); line-height:18px; margin:0 0 0;">&copy;<strong> <a href="https://www.artnouveau.in/" >www.artnouveau.in</a></strong> </p>
</td>
</tr>
<tr>
<td style="height:80px;">&nbsp;</td>
</tr>
</table>
</td>
</tr>
</table>
<!--/100% body table-->
</body>
</html>`
let subject = `New Tender Added in ${t.tenderCategoryD['productCategory']} Category on ArtNouveau Website`
// console.log(closedTenderUsers);
await this.sendMailManually(closedTenderUsers, subject, html, html)
closedTenderUsers = []
}
}
}

@ -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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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.');
}
}
}

@ -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 { }

@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class FileUploadService {}

@ -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<T>{
private logger = new Logger('PcdFormGridController'); // for logging
constructor(
private service: PcdFormGridService<T>
) {
}
@Get()
async findAll(
@Query() filter: FindManyOptions,
@GetUser() user: PcduserDto
): Promise<any[]> {
return await this.service.findAll(filter, user);
}
@Get('/:id')
async getOne(
@Query() filterDto: FindManyOptions,
@Param('id') id: string,
@GetUser() user: PcduserDto,
): Promise<any> {
return await this.service.findOne(filterDto, id, user);
}
@UsePipes(ValidationPipe)
@Post()
async createOne(
@Body() body: T,
@GetUser() user: PcduserDto
): Promise<any> {
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<any> {
return await this.service.deleteOne(filter, id, user);
}
}

@ -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<T> implements PcdFormGridInterface {
MAIN_KEY: string = 'id';
CUSTID: string = '';
MANDATORY_FEILDS: string[] = [];
DUPLICATE_CHK: string[] = [];
FK_FEILDS: { column: string, relation: Repository<any> }[] = [];
ROW_COUNT: string = '';
constructor(
// @Inject(TENANT_CONNECTION) conn:Connection,
private repo: Repository<any>
) { }
async preFindAll(filter: FindManyOptions, user: PcduserDto): Promise<boolean> {
return true;
}
async findAll(filter: FindManyOptions, user: PcduserDto): Promise<any[]> {
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<T[]> {
return result;
}
async preFindOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise<boolean> {
return true;
}
async findOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise<any> {
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<T> {
return result;
}
async preCreateOne(body: T, user: PcduserDto): Promise<boolean> {
return true;
}
async createOne(body: any, user: PcduserDto): Promise<any> {
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<T> {
return result;
}
async preUpdateOne(body: T, id: string | number, user: PcduserDto): Promise<boolean> {
return true;
}
async updateOne(body: any, id: string | number, user: PcduserDto): Promise<any> {
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<T> {
return result;
}
async preDeleteOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise<boolean> {
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<any> {
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<any> {
return result;
}
async getDeleteFilter(whereFilter: FindManyOptions): Promise<any> {
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<any> {
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<string[]> {
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<string[]> {
const PRIMARY_KEYS: string[] = [];
await this.repo.metadata.primaryColumns.forEach((row) => {
PRIMARY_KEYS.push(row.propertyName);
});
return PRIMARY_KEYS;
}
async getFilterWithPrimaryKey(body: T): Promise<FindManyOptions> {
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<string[]> {
/*
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;
}
}

@ -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<T> {
private logger = new Logger('PcdTransactionController'); // for logging
constructor(
private service: PcdTransactionService<T>
) { }
@Get()
async findList(@Query() filter: FindManyOptions,
@GetUser() user: PcduserDto
): Promise<T[]> {
return await this.service.findList(filter, user);
}
@Get('/:id')
async findOne(@Query() filter: FindManyOptions, @Param('id') id: string,): Promise<T> {
return await this.service.findOne(filter, id);
}
@UseGuards(AuthGuard())
@Post()
async createOne(@Body() body: T,
@GetUser() user: PcduserDto): Promise<T> {
return await this.service.createOne(body, user);
}
@UseGuards(AuthGuard())
@Delete('/:id')
async delete(@Query() filter: FindManyOptions, @Param('id') id: string,): Promise<any> {
return await this.service.deleteOne(filter, id,);
}
}

@ -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<T> implements PcdtTransactionInterface {
MAIN_KEY: string = "id";
TXN_TYPE: string = "";
DETAIL_DATA_FORMAT: TransactionDetailDto[] = [];
constructor(
private connection: DataSource,
private repo: Repository<any>
) { }
async preFindList(filter: FindManyOptions, user: PcduserDto): Promise<boolean> {
return true
}
async findList(filter: FindManyOptions, user: PcduserDto): Promise<T[]> {
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<T[]> {
return result;
}
async preFindOne(filter: FindManyOptions,): Promise<boolean> {
return true
}
async findOne(filter: FindOneOptions, id: string | number,): Promise<T> {
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<T> {
return result;
}
async preDeleteOne(filter: FindManyOptions, id: string | number,): Promise<boolean> {
return true;
}
async deleteOne(filter: any, id: string | number,): Promise<any> {
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<any> {
return result;
}
async preCreateOne(body: T,user): Promise<boolean> {
return true;
}
async beforeCreateOne(body: T, queryRunner: QueryRunner): Promise<boolean> {
return true;
}
async createOne(body: T, user: PcduserDto): Promise<T> {
//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<void> {
}
async postCreateOne(body: T, result: T): Promise<T> {
return result;
}
async insertDetailData(body: T, detailData: TransactionDetailDto[], queryRunner: QueryRunner, insertedData: T): Promise<void> {
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<any> {
for (let row of detailDataFormat) {
await this.deleteDetailTableData(id, row, queryRunner);
}
}
async deleteDetailTableData(id: string | number, detailData: TransactionDetailDto, queryRunner: QueryRunner): Promise<any> {
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<T[]> {
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<void> {
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<any> {
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<FindManyOptions> {
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<any> {
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<string[]> {
const PRIMARY_KEYS: string[] = [];
await this.repo.metadata.primaryColumns.forEach((row) => {
PRIMARY_KEYS.push(row.propertyName);
});
return PRIMARY_KEYS;
}
async getEagerColumns(repoDetail?: any): Promise<string[]> {
/*
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;
}
}

@ -0,0 +1,14 @@
export class PcdBaseDto {
createdBy: string;
createdDate: Date;
modifiedBy: string;
modifiedDate: Date;
versionNo: number;
sessionNo: number;
}

@ -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
}

@ -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;
}

@ -0,0 +1,23 @@
import { Repository } from "typeorm";
export class TransactionDetailDto {
detailName: string;
foreignKeyColumnName?: string;
foreignKeyAssignmentColumnName?: {columnName:string,headerColumn:string};
repo: Repository<any>;
filter: { columnName: string, value?: any, headerColumn?: string }[];
childDetail: TransactionDetailDto[];
addtionalSettingOfRowsInInsertion?: { columnName: string, value?: any, headerColumn?: string }[];
transactionTypeColumnName?:string;
orderByColumn?: {columnName : string, sort : "DESC" | "ASC" };
}

@ -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<any[]>;
findOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise<any>;
createOne(body: any, user: PcduserDto): Promise<any>
updateOne(body: any, id: string | number, user: PcduserDto): Promise<any>;
deleteOne(filter: FindManyOptions, id: string | number, user: PcduserDto): Promise<any>;
}

@ -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<any[]>;
}

@ -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()

@ -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<void> {
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<void> {
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<any> {
// console.log("===dd===", body);
// return await this.freeChargePaymentGatewayService.checkPaymentStatus(body, user);
// }
// @Post('refund')
// async refundPayment(
// @Body() body: any,
// @GetUser() user: PcduserDto
// ): Promise<any> {
// 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
}
}

@ -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 { }

@ -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)
}
}

@ -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"];

@ -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);
}
}

@ -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<basicCategoryDto> {
constructor(
private productCategoryService: basicCategoryService
) {
super(productCategoryService);
}
}

@ -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[]
}

@ -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 {}

@ -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<Category>{
constructor(
private datasource : DataSource
){
super(Category,datasource.createEntityManager());
}
}

@ -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<basicCategoryDto>{
constructor(
@InjectRepository(basicCategoryRepository)
private basicCategoryRepository: basicCategoryRepository,
) {
super(basicCategoryRepository);
}
}

@ -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<closedTenderUsersDto> {
constructor(
private ClosedTenderUsersService: ClosedTenderUsersService
) {
super(ClosedTenderUsersService);
}
@Post('users')
async closedTenderUsers(
@GetUser() user:PcduserDto,
@Body() body:any
) {
return await this.ClosedTenderUsersService.closedTenderUsers(user,body)
}
}

@ -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
}

@ -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 {}

@ -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<closedTenderUsers>{
constructor(
private datasource : DataSource
){
super(closedTenderUsers,datasource.createEntityManager());
}
}

@ -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<closedTenderUsersDto>{
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" }
}
}

@ -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<CommonDto>{
constructor(
private commonService: CommonService
) {
super(commonService);
}
}

@ -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
}

@ -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 {}

@ -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<Common>{
constructor(
private datasource:DataSource
){
super(Common,datasource.createEntityManager());
}
}

@ -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<Common>{
constructor(
@InjectRepository(commonRepository)
private commonRepository: commonRepository,
) {
super(commonRepository);
}
}

@ -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<coverTypeDto>{
constructor(
private coversLovService: CoversLovService
) {
super(coversLovService);
}
}

@ -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[]
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save