first commit

This commit is contained in:
harshithnrao 2025-02-24 12:51:11 +05:30
commit 23b7266db6
105 changed files with 28398 additions and 0 deletions

8
.env Normal file
View File

@ -0,0 +1,8 @@
POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DATABASE=remedify-users-local
PORT=3000
MODE=DEV
RUN_MIGRATIONS=false

24
.eslintrc.js Normal file
View File

@ -0,0 +1,24 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/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',
},
};

36
.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
# compiled output
/dist
/node_modules
/uploads/*
# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# OS
.DS_Store
# Tests
/coverage
/.nyc_output
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

1
Insomnia_2024-01-21.json Normal file

File diff suppressed because one or more lines are too long

73
README.md Normal file
View File

@ -0,0 +1,73 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="200" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).

File diff suppressed because one or more lines are too long

98
create table queries.sql Normal file
View File

@ -0,0 +1,98 @@
CREATE TABLE "users" (
"id" BIGSERIAL PRIMARY KEY,
"email" TEXT,
"phoneNumber" TEXT,
"password" TEXT,
"name" TEXT,
"userTypeCode" TEXT,
"primaryRole" TEXT,
"instituteCode" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "user_type" (
"id" BIGSERIAL PRIMARY KEY,
"userTypeCode" TEXT,
"userTypeName" TEXT,
"userTypeDesc" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "user_additional_details" (
"id" BIGSERIAL PRIMARY KEY,
"userId" BIGINT,
"addlDataType" TEXT,
"addlDataName" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC,
);
CREATE TABLE "roles_ref" (
"id" BIGSERIAL PRIMARY KEY,
"appCode" TEXT,
"roleCode" TEXT,
"roleName" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "institute" (
"id" BIGSERIAL PRIMARY KEY,
"instituteCode" TEXT,
"instituteName" TEXT,
"address" TEXT,
"lat" NUMERIC,
"lng" NUMERIC,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "subscription" (
"id" BIGSERIAL PRIMARY KEY,
"user_id" BIGINT,
"plan_type" TEXT,
"start_date" DATE,
"end_date" DATE,
"is_active" BOOLEAN,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC,
);

View File

@ -0,0 +1,283 @@
CREATE TABLE public.actions_ref (
id bigserial NOT NULL,
"appCode" text,
"actionCode" text,
"actionName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.apps_ref (
id bigserial NOT NULL,
"appCode" text,
"appName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.companies (
id bigserial NOT NULL,
"companyCode" text,
"companyName" text,
address text,
gst text,
status text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.company_details (
id bigserial NOT NULL,
"companyId" numeric,
"companyCode" text,
"addlDataType" text,
"addlDataName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.crud_config_info (
id bigserial NOT NULL,
"endPtNm" text,
"opsTypeName" text,
"sqlQueryText" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.item_category_ref (
id bigserial NOT NULL,
"categoryName" text,
"categoryCode" text,
"categoryDescription" text,
"parentCode" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.items_ref (
id bigserial NOT NULL,
"itemCode" text,
"itemName" text,
"itemCategoryCode" text,
"itemDesc" text,
"parentCode" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.policies_ref (
id bigserial NOT NULL,
"appCode" text,
"roleCode" text,
"resourceCode" text,
"actionCode" text,
"canAllow" boolean,
priority boolean,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.resources_ref (
id bigserial NOT NULL,
"appCode" text,
"resourceCode" text,
"resourceName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.roles_ref (
id bigserial NOT NULL,
"appCode" text,
"roleCode" text,
"roleName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.user_additional_details (
id bigserial NOT NULL,
"userId" numeric,
"addlDataType" text,
"addlDataName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.users (
id bigserial NOT NULL,
email text,
password text,
name text,
"userTypeCode" text,
"primaryRole" text,
"companyCode" text,
status text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.master_config_category_ref (
id bigserial NOT NULL,
"categoryName" text,
"categoryCode" text,
"categoryDescription" text,
"categoryType" text,
"parentCode" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.master_config_ref (
id bigserial NOT NULL,
"configCode" text,
"configName" text,
"configCategoryCode" text,
"configDesc" text,
"parentCode" text,
"configType" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.master_config_mapping (
id bigserial NOT NULL,
"configCode" text,
"companyCode" text,
"status" text,
"dispSerialNumber" text,
"defaultValue" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.config_transcations (
id bigserial NOT NULL,
"configCode" text,
"companyCode" text,
"itemCategoryCode" text,
"itemCode" text,
"status" text,
"value" text,
"fileUrl" text,
"weight" numeric,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.config_logs (
id bigserial NOT NULL,
"tableName" text,
"prevValue" text,
"currValue" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
)

10
nest-cli.json Normal file
View File

@ -0,0 +1,10 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"assets": ["mail/templates/**/*"],
"watchAssets": true
}
}

11
nodemon.json Normal file
View File

@ -0,0 +1,11 @@
{
"watch": [
"src"
],
"ext": "ts",
"ignore": [
"src/**/*.spec.ts"
],
"exec": "node --inspect=127.0.0.1:9223 -r ts-node/register -- src/main.ts",
"env": {}
}

23924
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

89
package.json Normal file
View File

@ -0,0 +1,89 @@
{
"name": "epr-be",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"build": "node script-util.js config.local.json config.json && nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "node script-util.js config.local.json config.json && nest start",
"start:local": "node script-util.js config.local.json config.json && nest start --watch",
"start:debug": "node script-util.js config.local.json config.json && nest start --debug --watch",
"start:prod": "node dist/main",
"build:dev": "node script-util.js config.dev.json config.json && nest build && cp package.json dist/package.json && cp -r config dist/",
"build:prod": "node script-util.js config.prod.json config.json && nest build && cp package.json dist/package.json && cp -r config dist/",
"build:test": "node script-util.js config.test.json config.json && nest build && cp package.json dist/package.json && cp -r config dist/",
"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": {
"@nestjs-modules/mailer": "^1.10.3",
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/typeorm": "^10.0.1",
"dotenv": "^16.3.1",
"handlebars": "^4.7.8",
"moment": "^2.30.1",
"nexe": "^4.0.0-rc.6",
"nodemailer": "^6.9.9",
"otp-generator": "^4.0.1",
"pg": "^8.11.3",
"reflect-metadata": "^0.1.14",
"rxjs": "^7.8.1",
"sequelize": "^6.35.2",
"sequelize-typescript": "^2.1.6",
"typeorm": "^0.3.17"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/multer": "^1.4.11",
"@types/node": "^20.10.6",
"@types/nodemailer": "^6.4.14",
"@types/supertest": "^2.0.12",
"@types/validator": "^13.11.7",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"nodemon": "^3.0.2",
"prettier": "^3.0.0",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}

11
script-util.js Normal file
View File

@ -0,0 +1,11 @@
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the required modules
const fs = require('fs');
// Get the source and destination file paths from the command-line arguments
const sourcePath = `src/app-config/${process.argv[2]}`;
const destinationPath = `src/app-config/${process.argv[3]}`;
// Read the source file
fs.writeFileSync(destinationPath, fs.readFileSync(sourcePath));

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppConfigController } from './app-config.controller';
describe('AppConfigController', () => {
let controller: AppConfigController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AppConfigController],
}).compile();
controller = module.get<AppConfigController>(AppConfigController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,41 @@
import { Controller, Get, Post, Query, Req, Res } from '@nestjs/common';
import { getFile, updateFile } from './file.util';
import { Request, Response } from 'express';
import { Utility } from 'src/common/Utility';
@Controller('app-config')
export class AppConfigController {
@Get('/')
async get(@Req() req: Request, @Query() query, @Res() res: Response) {
console.log('Inside Config Controller GET', query);
const filePath = (query.path) ? `${Utility.fileConfig.configPath}/${query.path}` : `${Utility.fileConfig.configPath}`;
const response = await getFile(filePath, 'UTF-8');
return res.status(200).send(response);
}
@Post('/')
async post(@Req() req: Request, @Res() res: Response) {
const filePath = `${Utility.fileConfig.configPath}`;
const fileName = (req.body && req.body.fileName) ? req.body.fileName : null;
let data = (req.body && req.body.data) ? req.body.data : null;
let resultSet = {};
console.log('Inside Config Controller Post');
console.log(`File Path ${filePath}`);
console.log(`File Name ${fileName}`);
console.log(`File Data ${data}`);
if (!filePath || !fileName || !data) {
resultSet = {
exception: true,
exceptionMessage: 'Invalid Params',
exceptionSeverity: 'high'
}
return res.status(400).send(resultSet);
}
if(typeof data === 'object') {
data = JSON.stringify(data);
}
const response = await updateFile(filePath,fileName,data);
resultSet['result'] = response;
return res.status(200).send(resultSet);
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppConfigService } from './app-config.service';
describe('AppConfigService', () => {
let service: AppConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AppConfigService],
}).compile();
service = module.get<AppConfigService>(AppConfigService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,44 @@
import { Injectable } from '@nestjs/common';
import * as configMaster from './config.json';
@Injectable()
export class AppConfigService {
defaultEnv = 'local';
constructor() {
}
private getValue(key: string, throwOnMissing = true): any {
const value = configMaster[this.defaultEnv].dbConfig[key];
if (!value && throwOnMissing) {
throw new Error(`config error - missing env.${key}`);
}
return value;
}
public ensureValues(keys: string[]) {
keys.forEach(k => this.getValue(k, true));
return this;
}
public getPort() {
return this.getValue('PORT', true);
}
public isProduction() {
const mode = this.getValue('MODE', false);
return mode != 'DEV';
}
getDbConfig() {
return configMaster[this.defaultEnv].dbConfig;
}
initializeFileSystem() {
return configMaster[this.defaultEnv].fileConfig;
}
getMailConfig() {
return configMaster[this.defaultEnv].mailConfig;
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3003
},
"dbConfig": {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "epr",
"MODE": "DEV",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "/opt/www/wastecare-uploads/dev",
"configPath": "/opt/wastecare/config/dev"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3000
},
"dbConfig": {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "remedify-users-local",
"MODE": "DEV",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "./uploads",
"configPath": "./config"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3000
},
"dbConfig": {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "remedify-users-local",
"MODE": "DEV",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "./uploads",
"configPath": "./config"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3003
},
"dbConfig": {
"host": "127.0.0.1",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "epr",
"MODE": "PROD",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "/opt/www/wastecare-uploads/prod",
"configPath": "/opt/wastecare/config/prod"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3003
},
"dbConfig": {
"host": "127.0.0.1",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "epr",
"MODE": "TEST",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "/opt/www/wastecare-uploads/test",
"configPath": "/opt/wastecare/config/test"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,82 @@
// This file should exist in `src/common/helpers`
import * as fs from 'fs';
import { promisify } from 'util';
/**
* Check if a file exists at a given path.
*
* @param {string} path
*
* @returns {boolean}
*/
export const checkIfFileOrDirectoryExists = (path: string): boolean => {
return fs.existsSync(path);
};
/**
* Gets file data from a given path via a promise interface.
*
* @param {string} path
* @param {string} encoding
*
* @returns {Promise<Buffer>}
*/
export const getFile = async (
path: string,
encoding: string,
): Promise<string | Buffer> => {
const readFile = promisify(fs.readFile);
return encoding ? readFile(path) : readFile(path, {});
};
/**
* Writes a file at a given path via a promise interface.
*
* @param {string} path
* @param {string} fileName
* @param {string} data
*
* @return {Promise<void>}
*/
export const createFile = async (
path: string,
fileName: string,
data: string,
): Promise<void> => {
if (!checkIfFileOrDirectoryExists(path)) {
fs.mkdirSync(path);
}
const writeFile = promisify(fs.writeFile);
return await writeFile(`${path}/${fileName}`, data, 'utf8');
};
export const updateFile = async (
path: string,
fileName: string,
data: string,
): Promise<void> => {
const fqdn = `${path}/${fileName}`
if (!checkIfFileOrDirectoryExists(path)) {
fs.mkdirSync(path);
}
// const writeFile = promisify(fs.writeFile);
return fs.writeFileSync(`${fqdn}`, data);
};
/**
* Delete file at the given path via a promise interface
*
* @param {string} path
*
* @returns {Promise<void>}
*/
export const deleteFile = async (path: string): Promise<void> => {
const unlink = promisify(fs.unlink);
return await unlink(path);
};

View File

@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

14
src/app.controller.ts Normal file
View File

@ -0,0 +1,14 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {
this.appService.initializeSequelize();
}
@Get()
getHello(): string {
return this.appService.getHello();
}
}

29
src/app.module.ts Normal file
View File

@ -0,0 +1,29 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { CommonService } from './common/common.service';
import { AppConfigService } from './app-config/app-config.service';
import { DataModule } from './data/data.module';
import { MailModule } from './mail/mail.module';
import { AppConfigController } from './app-config/app-config.controller';
import { ItemsModule } from './items/item.module';
import { MasterConfigModule } from './master-config/master-config.module';
import { ConfigModule } from './config/config.module';
import { SubscriptionsModule } from './subscription/subscription.module';
import { InstituteModule } from './institute/institute.module';
@Module({
imports: [
UserModule,
InstituteModule,
DataModule,
MailModule,
ItemsModule,
SubscriptionsModule,
MasterConfigModule,
ConfigModule
],
controllers: [AppController, AppConfigController],
providers: [CommonService, AppConfigService, AppService],
})
export class AppModule {}

76
src/app.service.ts Normal file
View File

@ -0,0 +1,76 @@
import { Injectable } from '@nestjs/common';
import { CommonService } from './common/common.service';
import * as fs from 'fs';
import * as path from 'path';
import { Sequelize } from 'sequelize-typescript';
import { AppConfigService } from './app-config/app-config.service';
import { Utility } from './common/Utility';
@Injectable()
export class AppService {
modelFilePaths: string[] = [] as string[];
constructor(private commonService: CommonService, private configService: AppConfigService) { }
getHello(): string {
return 'Hello World!';
}
initializeSequelize() {
this.getModels();
const dbConfig = this.configService.getDbConfig();
if (this.modelFilePaths.length > 0) {
this.commonService.sequelize = new Sequelize({
database: dbConfig.database,
dialect: 'postgres',
username: dbConfig.user,
password: dbConfig.password,
models: this.modelFilePaths,
modelMatch: (filename, member) => {
return filename.substring(0, filename.indexOf('.entity')) === member.toLowerCase();
},
});
Utility.sequelize = this.commonService.sequelize;
}
const fileConfig = this.configService.initializeFileSystem();
this.commonService.fileConfig = fileConfig;
Utility.fileConfig = fileConfig;
const emailConfig = this.configService.getMailConfig();
this.commonService.mailConfig = emailConfig;
Utility.mailConfig = emailConfig;
}
getModels() {
this.fromDir(__dirname, '.entity', ['.js', '.ts']);
if (this.modelFilePaths.length > 0) {
}
}
fromDir(startPath, filter, extensions) {
if (!fs.existsSync(startPath) || !extensions || extensions.length === 0) {
console.log("no dir ", startPath);
return;
}
const files = fs.readdirSync(startPath);
for (let i = 0; i < files.length; i++) {
const filename = path.join(startPath, files[i]);
const stat = fs.lstatSync(filename);
if (stat.isDirectory()) {
this.fromDir(filename, filter, extensions); //recurse
} else if (filename.includes(filter)) {
extensions.map((extension) => {
if (filename.endsWith(`${filter}${extension}`)) {
this.modelFilePaths.push(filename);
}
})
};
};
}
}

View File

@ -0,0 +1,18 @@
export class Exception {
public exception: boolean;
public exceptionSeverity: 'HIGH' | 'MEDIUM' | 'LOW';
public exceptionMessage: string;
public stackTrace: any;
constructor(
exception,
exceptionSeverity,
exceptionMessage,
stackTrace = null,
) {
this.exception = exception;
this.exceptionSeverity = exceptionSeverity;
this.exceptionMessage = exceptionMessage;
this.stackTrace = stackTrace;
}
}

View File

@ -0,0 +1,14 @@
import { Exception } from "./Exception.model";
export class GenericResponse {
public notification: Exception;
data: any
constructor(
exception: Exception,
data
) {
this.notification = exception;
this.data = data;
}
}

22
src/common/Utility.ts Normal file
View File

@ -0,0 +1,22 @@
import { Sequelize } from "sequelize";
export class Utility {
static sequelize: Sequelize;
static appPort: number = 3000;
static models: any;
static fileConfig: any = {"storagePath": "./uploads"};
static mailConfig: any = {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
};
}

View File

@ -0,0 +1,13 @@
import { Injectable } from '@nestjs/common';
import {Sequelize} from 'sequelize-typescript';
@Injectable()
export class CommonService {
sequelize: Sequelize;
models: any;
fileConfig: any;
mailConfig: any;
constructor() {
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigLogsController } from './config-logs.controller';
describe('ConfigLogsController', () => {
let controller: ConfigLogsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ConfigLogsController],
}).compile();
controller = module.get<ConfigLogsController>(ConfigLogsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { ConfigLogsService } from './config-logs.service';
import ConfigLog from './config-logs.entity';
import { GenericResponse } from 'src/common/GenericResponse.model';
@Controller('config/logs')
export class ConfigLogsController {
constructor(private configService: ConfigLogsService) {}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.configService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() config: ConfigLog, @Res() res: Response) {
if(!config) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.filter(config) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() config: ConfigLog, @Res() res: Response) {
if(!config) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete config.id;
const response = await this.configService.upsert(config, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() config: ConfigLog, @Res() res: Response) {
if(!config || !config.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.upsert(config, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,29 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({tableName: 'config_logs'})
export default class ConfigLog extends Model {
@Column({type: DataType.TEXT})
tableName: string;
@Column({type: DataType.TEXT})
prevValue: string;
@Column({type: DataType.TEXT})
currValue: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigLogsService } from './config-logs.service';
describe('ConfigLogsService', () => {
let service: ConfigLogsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ConfigLogsService],
}).compile();
service = module.get<ConfigLogsService>(ConfigLogsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import ConfigLog from './config-logs.entity';
@Injectable()
export class ConfigLogsService {
async findAll(): Promise<{rows: ConfigLog[], count: number}> {
return ConfigLog.findAndCountAll();
}
findByPk(id: number): Promise<ConfigLog> {
return ConfigLog.findByPk(id)
}
filter(config: ConfigLog) : Promise<ConfigLog[]> {
return ConfigLog.findAll({where: config as any})
}
findOne(config: ConfigLog): Promise<ConfigLog> {
return ConfigLog.findOne({where: config as any})
}
async remove(id: number): Promise<number> {
return ConfigLog.destroy({where: {id: id}});
}
async upsert(config: ConfigLog, insertIfNotFound: boolean): Promise<ConfigLog | [affectedCount: number]> {
if(config.id) {
const existingUser = await this.findByPk(config.id);
if(existingUser) {
return ConfigLog.update(config, {where: {id: config.id}});
}
}
if(insertIfNotFound) {
return ConfigLog.create(config as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigController } from './config.controller';
describe('ConfigController', () => {
let controller: ConfigController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ConfigController],
}).compile();
controller = module.get<ConfigController>(ConfigController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,104 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { ConfigService } from './config.service';
import Config from './config.entity';
import { GenericResponse } from 'src/common/GenericResponse.model';
@Controller('config')
export class ConfigController {
constructor(private configService: ConfigService) {}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.configService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() config: Config, @Res() res: Response) {
if(!config) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.filter(config) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() config: Config, @Res() res: Response) {
if(!config) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete config.id;
const response = await this.configService.upsert(config, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() config: Config, @Res() res: Response) {
if(!config || !config.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.upsert(config, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,44 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({tableName: 'config_transcations'})
export default class Config extends Model {
@Column({type: DataType.TEXT})
configCode: string;
@Column({type: DataType.TEXT})
companyCode: string;
@Column({type: DataType.TEXT})
itemCategoryCode: string;
@Column({type: DataType.TEXT})
itemCode: string;
@Column({type: DataType.TEXT})
status: string;
@Column({type: DataType.TEXT})
value: string;
@Column({type: DataType.TEXT})
fileUrl: string;
@Column({type: DataType.NUMBER})
weight: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { ConfigController } from './config.controller';
import { ConfigService } from './config.service';
import { ConfigLogsController } from './config-logs/config-logs.controller';
import { ConfigLogsService } from './config-logs/config-logs.service';
@Module({
controllers: [ConfigController, ConfigLogsController],
providers: [ConfigService, ConfigLogsService]
})
export class ConfigModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from './config.service';
describe('ConfigService', () => {
let service: ConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ConfigService],
}).compile();
service = module.get<ConfigService>(ConfigService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import Config from './config.entity';
@Injectable()
export class ConfigService {
async findAll(): Promise<{rows: Config[], count: number}> {
return Config.findAndCountAll();
}
findByPk(id: number): Promise<Config> {
return Config.findByPk(id)
}
filter(config: Config) : Promise<Config[]> {
return Config.findAll({where: config as any})
}
findOne(config: Config): Promise<Config> {
return Config.findOne({where: config as any})
}
async remove(id: number): Promise<number> {
return Config.destroy({where: {id: id}});
}
async upsert(config: Config, insertIfNotFound: boolean): Promise<Config | [affectedCount: number]> {
if(config.id) {
const existingUser = await this.findByPk(config.id);
if(existingUser) {
return Config.update(config, {where: {id: config.id}});
}
}
if(insertIfNotFound) {
return Config.create(config as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DataController } from './data.controller';
describe('DataController', () => {
let controller: DataController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [DataController],
}).compile();
controller = module.get<DataController>(DataController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

132
src/data/data.controller.ts Normal file
View File

@ -0,0 +1,132 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { GenericResponse } from 'src/common/GenericResponse.model';
import DataModel from './data.entity';
import { DataService } from './data.service';
import { Response } from 'express';
@Controller('data')
export class DataController {
constructor(private dataService: DataService) {}
@Get("/all")
async getAllUsers(@Res() res: Response) {
const response: any = await this.dataService.findAll() || [];
res.send((response && response.rows) ? response.rows : []);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.dataService.findByPk(id) || {};
res.send(response);
}
@Post('/:endPtNm/:opType')
async performOperation(@Param('endPtNm') endPtNm: string, @Param('opType') opType: string, @Body() body, @Res() res: Response) {
if(!opType || !endPtNm) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response: DataModel = await this.dataService.findOne({endPtNm: endPtNm, opsTypeName: opType.toUpperCase()} as any);
if(response && response.sqlQueryText) {
if(body) {
for(const key in body) {
response.sqlQueryText = response.sqlQueryText.replaceAll(`:${key}`, (typeof body[key] === 'string') ? `'${body[key]}'` : body[key]);
}
}
let dataResponse = await this.dataService.executeQuery(response.sqlQueryText);
if(dataResponse && dataResponse.length && Array.isArray(dataResponse[0])) {
dataResponse = dataResponse[0];
}
res.send(dataResponse);
return;
}
return new GenericResponse(null, []);
}
@Post('/filter')
async filter(@Body() quote: DataModel, @Res() res: Response) {
if(!quote) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.dataService.filter(quote) || [];
res.send(response);
}
@Post()
async insert(@Body() quote: DataModel, @Res() res: Response) {
if(!quote) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete quote.id;
const response = await this.dataService.upsert(quote, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() quote: DataModel, @Res() res: Response) {
if(!quote || !quote.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.dataService.upsert(quote, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.dataService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

29
src/data/data.entity.ts Normal file
View File

@ -0,0 +1,29 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({tableName: 'crud_config_info'})
export default class DataModel extends Model {
@Column({type: DataType.NUMBER})
endPtNm: number;
@Column({type: DataType.TEXT})
sqlQueryText: string;
@Column({type: DataType.TEXT})
opsTypeName: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

9
src/data/data.module.ts Normal file
View File

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { DataService } from './data.service';
import { DataController } from './data.controller';
@Module({
providers: [DataService],
controllers: [DataController]
})
export class DataModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DataService } from './data.service';
describe('DataService', () => {
let service: DataService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [DataService],
}).compile();
service = module.get<DataService>(DataService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

44
src/data/data.service.ts Normal file
View File

@ -0,0 +1,44 @@
import { Injectable } from '@nestjs/common';
import DataModel from './data.entity';
import { Utility } from 'src/common/Utility';
@Injectable()
export class DataService {
constructor() { }
async findAll(): Promise<{rows: DataModel[], count: number}> {
return DataModel.findAndCountAll();
}
findByPk(id: number): Promise<DataModel> {
return DataModel.findByPk(id)
}
findOne(dataDetail: DataModel): Promise<DataModel> {
return DataModel.findOne({where: dataDetail as any})
}
filter(dataDetail: DataModel) : Promise<DataModel[]> {
return DataModel.findAll({where: dataDetail as any})
}
async remove(id: number): Promise<number> {
return DataModel.destroy({where: {id: id}});
}
async upsert(dataDetail: DataModel, insertIfNotFound: boolean): Promise<DataModel | [affectedCount: number]> {
if(dataDetail.id) {
const existingUser = await this.findByPk(dataDetail.id);
if(existingUser) {
return DataModel.update(dataDetail, {where: {id: dataDetail.id}});
}
}
if(insertIfNotFound) {
return DataModel.create(dataDetail as any)
}
}
executeQuery(sqlQueryText: string): Promise<any> {
return Utility.sequelize.query(sqlQueryText);
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CompanyAdditionalDetailsController } from './company-additional-details.controller';
describe('CompanyAdditionalDetailsController', () => {
let controller: CompanyAdditionalDetailsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [CompanyAdditionalDetailsController],
}).compile();
controller = module.get<CompanyAdditionalDetailsController>(CompanyAdditionalDetailsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { InstituteAdditionalDetailsService } from './institute-additional-details.service';
import { GenericResponse } from 'src/common/GenericResponse.model';
import InstituteAdditionalDetail from './institute-additional-details.entity';
@Controller('institute/addlDetail')
export class InstituteAdditionalDetailsController {
constructor(private instituteDetailService: InstituteAdditionalDetailsService) {}
@Get("/all")
async getAllInstitutes(@Res() res: Response) {
const response = await this.instituteDetailService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.instituteDetailService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() institute: InstituteAdditionalDetail, @Res() res: Response) {
if(!institute) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.instituteDetailService.findOne(institute) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() institute: InstituteAdditionalDetail, @Res() res: Response) {
if(!institute) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete institute.id;
const response = await this.instituteDetailService.upsert(institute, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() institute: InstituteAdditionalDetail, @Res() res: Response) {
if(!institute || !institute.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.instituteDetailService.upsert(institute, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.instituteDetailService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,33 @@
import { Table, Column, Model, Default, DataType, ForeignKey } from 'sequelize-typescript';
import Institute from '../institute.entity';
@Table({tableName: 'institute_details'})
export default class InstituteAdditionalDetail extends Model {
@ForeignKey(() => Institute)
@Column({type: DataType.NUMBER})
instituteId: number;
@Column({type: DataType.TEXT})
instituteCode: string;
@Column({type: DataType.TEXT})
addlDataType: string;
@Column({type: DataType.TEXT})
addlDataName: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CompanyAdditionalDetailsService } from './company-additional-details.service';
describe('CompanyAdditionalDetailsService', () => {
let service: CompanyAdditionalDetailsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CompanyAdditionalDetailsService],
}).compile();
service = module.get<CompanyAdditionalDetailsService>(CompanyAdditionalDetailsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,33 @@
import { Injectable } from '@nestjs/common';
import InstituteAdditionalDetail from './institute-additional-details.entity';
@Injectable()
export class InstituteAdditionalDetailsService {
async findAll(): Promise<{rows: InstituteAdditionalDetail[], count: number}> {
return InstituteAdditionalDetail.findAndCountAll();
}
findByPk(id: number): Promise<InstituteAdditionalDetail> {
return InstituteAdditionalDetail.findByPk(id)
}
findOne(institute: InstituteAdditionalDetail): Promise<InstituteAdditionalDetail> {
return InstituteAdditionalDetail.findOne({where: institute as any})
}
async remove(id: number): Promise<number> {
return InstituteAdditionalDetail.destroy({where: {id: id}});
}
async upsert(institute: InstituteAdditionalDetail, insertIfNotFound: boolean): Promise<InstituteAdditionalDetail | [affectedCount: number]> {
if(institute.id) {
const existingUser = await this.findByPk(institute.id);
if(existingUser) {
return InstituteAdditionalDetail.update(institute, {where: {id: institute.id}});
}
}
if(insertIfNotFound) {
return InstituteAdditionalDetail.create(institute as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CompanyController } from './company.controller';
describe('CompanyController', () => {
let controller: CompanyController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [CompanyController],
}).compile();
controller = module.get<CompanyController>(CompanyController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { InstituteService } from './institute.service';
import { Response } from 'express';
import { GenericResponse } from 'src/common/GenericResponse.model';
import Institute from './institute.entity';
@Controller('institute')
export class InstituteController {
constructor(private instituteService: InstituteService) {}
@Get("/all")
async getAllInstitutes(@Res() res: Response) {
const response = await this.instituteService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.instituteService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() institute: Institute, @Res() res: Response) {
if(!institute) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.instituteService.filter(institute) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() institute: Institute, @Res() res: Response) {
if(!institute) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete institute.id;
const response = await this.instituteService.upsert(institute, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() institute: Institute, @Res() res: Response) {
if(!Institute || !institute.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.instituteService.upsert(institute, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.instituteService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,36 @@
import { Table, Column, Model, Default, DataType, HasMany, Unique } from 'sequelize-typescript';
import InstituteAdditionalDetail from './institute-additional-details/institute-additional-details.entity';
@Table({ tableName: 'institute' })
export default class Institute extends Model {
@Unique(true)
@Column({ type: DataType.TEXT })
instituteCode: string;
@Column({ type: DataType.TEXT })
instituteName: string;
@Column({ type: DataType.TEXT })
address: string;
@Column({ type: DataType.DECIMAL })
lat: number;
@Column({ type: DataType.DECIMAL })
lng: number;
@Column({ type: DataType.TEXT })
status: string;
@Default(new Date())
@Column({ type: DataType.DATEONLY })
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({ type: DataType.DATEONLY })
validTill: Date;
// @HasMany(() => InstituteAdditionalDetail)
// additionalDetails: InstituteAdditionalDetail[];
}

View File

@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { InstituteController } from './institute.controller';
import { InstituteService } from './institute.service';
import { InstituteAdditionalDetailsController } from './institute-additional-details/institute-additional-details.controller';
import { InstituteAdditionalDetailsService } from './institute-additional-details/institute-additional-details.service';
@Module({
imports: [],
providers: [InstituteService, InstituteAdditionalDetailsService],
controllers: [InstituteController, InstituteAdditionalDetailsController]
})
export class InstituteModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CompanyService } from './company.service';
describe('CompanyService', () => {
let service: CompanyService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CompanyService],
}).compile();
service = module.get<CompanyService>(CompanyService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,39 @@
import { Injectable } from '@nestjs/common';
import Institute from './institute.entity';
import InstituteAdditionalDetail from './institute-additional-details/institute-additional-details.entity';
@Injectable()
export class InstituteService {
async findAll(): Promise<{rows: Institute[], count: number}> {
return Institute.findAndCountAll();
}
findByPk(id: number): Promise<Institute> {
return Institute.findByPk(id, {include: {model: InstituteAdditionalDetail} })
}
filter(institute: Institute) : Promise<Institute[]> {
return Institute.findAll({where: institute as any, include: InstituteAdditionalDetail})
}
findOne(institute: Institute): Promise<Institute> {
return Institute.findOne({where: institute as any, include: InstituteAdditionalDetail})
}
async remove(id: number): Promise<number> {
return Institute.destroy({where: {id: id}});
}
async upsert(institute: Institute, insertIfNotFound: boolean): Promise<Institute | [affectedCount: number]> {
if(institute.id) {
const existingUser = await this.findByPk(institute.id);
if(existingUser) {
return Institute.update(institute, {where: {id: institute.id}});
}
}
if(insertIfNotFound) {
return Institute.create(institute as any)
}
}
}

View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { GenericResponse } from 'src/common/GenericResponse.model';
import { ItemCategoryService } from './item-category.service';
import ItemCategory from './item-category.entity';
@Controller('items/category')
export class ItemCategoryController {
constructor(private itemsService: ItemCategoryService) {}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.itemsService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.itemsService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() item: ItemCategory, @Res() res: Response) {
if(!item) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.itemsService.filter(item) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() item: ItemCategory, @Res() res: Response) {
if(!item) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete item.id;
const response = await this.itemsService.upsert(item, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() item: ItemCategory, @Res() res: Response) {
if(!item || !item.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.itemsService.upsert(item, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.itemsService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,36 @@
import { Table, Column, Model, Default, DataType, Unique, HasMany } from 'sequelize-typescript';
import Item from '../item.entity';
@Table({tableName: 'item_category_ref'})
export default class ItemCategory extends Model {
@Unique(true)
@Column({type: DataType.TEXT})
categoryCode: string;
@Column({type: DataType.TEXT})
categoryName: string;
@Column({type: DataType.TEXT})
categoryDescription: string;
@Column({type: DataType.TEXT})
parentCode: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
@HasMany(() => Item)
items: Item[];
}

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import ItemCategory from './item-category.entity';
@Injectable()
export class ItemCategoryService {
async findAll(): Promise<{rows: ItemCategory[], count: number}> {
return ItemCategory.findAndCountAll();
}
findByPk(id: number): Promise<ItemCategory> {
return ItemCategory.findByPk(id)
}
findOne(itemCategory: ItemCategory): Promise<ItemCategory> {
return ItemCategory.findOne({where: itemCategory as any})
}
async remove(id: number): Promise<number> {
return ItemCategory.destroy({where: {id: id}});
}
filter(item: ItemCategory) : Promise<ItemCategory[]> {
return ItemCategory.findAll({where: item as any})
}
async upsert(itemCategory: ItemCategory, insertIfNotFound: boolean): Promise<ItemCategory | [affectedCount: number]> {
if(itemCategory.id) {
const existingUser = await this.findByPk(itemCategory.id);
if(existingUser) {
return ItemCategory.update(itemCategory, {where: {id: itemCategory.id}});
}
}
if(insertIfNotFound) {
return ItemCategory.create(itemCategory as any)
}
}
}

View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { GenericResponse } from 'src/common/GenericResponse.model';
import { ItemService } from './item.service';
import Item from './item.entity';
@Controller('items')
export class ItemController {
constructor(private itemsService: ItemService) {}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.itemsService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.itemsService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() item: Item, @Res() res: Response) {
if(!item) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.itemsService.filter(item) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() item: Item, @Res() res: Response) {
if(!item) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete item.id;
const response = await this.itemsService.upsert(item, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() item: Item, @Res() res: Response) {
if(!item || !item.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.itemsService.upsert(item, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.itemsService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

38
src/items/item.entity.ts Normal file
View File

@ -0,0 +1,38 @@
import { Table, Column, Model, Default, DataType, Unique, ForeignKey } from 'sequelize-typescript';
import ItemCategory from './item-category/item-category.entity';
@Table({tableName: 'items_ref'})
export default class Item extends Model {
@Unique(true)
@Column({type: DataType.TEXT})
itemCode: string;
@Column({type: DataType.TEXT})
itemName: string;
@ForeignKey(() => ItemCategory)
@Column({type: DataType.TEXT})
itemCategoryCode: string;
@Column({type: DataType.TEXT})
itemDesc: string;
@Column({type: DataType.TEXT})
parentCode: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

12
src/items/item.module.ts Normal file
View File

@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { ItemService } from './item.service';
import { ItemCategoryService } from './item-category/item-category.service';
import { ItemController } from './item.controller';
import { ItemCategoryController } from './item-category/item-category.controller';
@Module({
imports: [],
providers: [ItemService, ItemCategoryService],
controllers: [ItemController, ItemCategoryController]
})
export class ItemsModule {}

38
src/items/item.service.ts Normal file
View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import Item from './item.entity';
@Injectable()
export class ItemService {
async findAll(): Promise<{rows: Item[], count: number}> {
return Item.findAndCountAll();
}
findByPk(id: number): Promise<Item> {
return Item.findByPk(id)
}
filter(item: Item) : Promise<Item[]> {
return Item.findAll({where: item as any})
}
findOne(item: Item): Promise<Item> {
return Item.findOne({where: item as any})
}
async remove(id: number): Promise<number> {
return Item.destroy({where: {id: id}});
}
async upsert(item: Item, insertIfNotFound: boolean): Promise<Item | [affectedCount: number]> {
if(item.id) {
const existingUser = await this.findByPk(item.id);
if(existingUser) {
return Item.update(item, {where: {id: item.id}});
}
}
if(insertIfNotFound) {
return Item.create(item as any)
}
}
}

27
src/mail/mail.module.ts Normal file
View File

@ -0,0 +1,27 @@
import { MailerModule } from '@nestjs-modules/mailer';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { Module } from '@nestjs/common';
import { MailService } from './mail.service';
import { join } from 'path';
import { Utility } from 'src/common/Utility';
@Module({
imports: [
MailerModule.forRoot({
// transport: 'smtps://user@example.com:topsecret@smtp.example.com',
// or
transport: Utility.mailConfig.transport,
defaults: Utility.mailConfig.defaults,
template: {
dir: join(__dirname, 'templates'),
adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter()
options: {
strict: true,
},
},
}),
],
providers: [MailService],
exports: [MailService], // 👈 export for DI
})
export class MailModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { MailService } from './mail.service';
describe('MailService', () => {
let service: MailService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [MailService],
}).compile();
service = module.get<MailService>(MailService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

19
src/mail/mail.service.ts Normal file
View File

@ -0,0 +1,19 @@
import { MailerService } from '@nestjs-modules/mailer';
import { Injectable } from '@nestjs/common';
@Injectable()
export class MailService {
constructor(private mailerService: MailerService) { }
async sendEmail(templateName: string, subject: string, context: any, toEmail: string, ccEmails?: string[], bccEmails?: string[]) {
await this.mailerService.sendMail({
to: toEmail,
cc: ccEmails,
bcc: bccEmails,
subject: subject,
template: templateName, // `.hbs` extension is appended automatically
context,
})
}
}

View File

@ -0,0 +1,82 @@
<head>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.gjs-row {
display: flex;
justify-content: flex-start;
align-items: stretch;
flex-wrap: nowrap;
padding: 10px;
}
.gjs-cell {
min-height: 75px;
flex-grow: 1;
flex-basis: 100%;
}
#im43 {
background-repeat: repeat;
background-position: left top;
background-attachment: scroll;
background-size: auto;
background-image: linear-gradient(#39960c 0%, #39960c 100%);
}
#ij93 {
padding: 10px;
}
#ilfj {
color: #ffffff;
text-align: left;
font-weight: 900;
font-size: 3rem;
}
#ihfp {
height: 577px;
}
#i23r {
padding: 10px;
}
@media (max-width: 768px) {
.gjs-row {
flex-wrap: wrap;
}
}
</style>
</head>
<body id="iohk">
<div class="gjs-row" id="iir1">
<div class="gjs-cell" id="im43">
<div id="ij93">
<span id="ilfj">Waste Care Technologies</span>
</div>
</div>
</div>
<div class="gjs-row" id="ihfp">
<div class="gjs-cell">
<div id="i23r">Dear {{ name }},
<br />
<br />Welcome to Waste Care Technologies.
<br />
<br />Use Password {{ password }} to login to your account.
<br />
<br />Contact our Support if you need any queries.
<br />
<br />Thank you for choosing us
</div>
</div>
</div>
</body>

View File

@ -0,0 +1,79 @@
<head>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.gjs-row {
display: flex;
justify-content: flex-start;
align-items: stretch;
flex-wrap: nowrap;
padding: 10px;
}
.gjs-cell {
min-height: 75px;
flex-grow: 1;
flex-basis: 100%;
}
#im43 {
background-repeat: repeat;
background-position: left top;
background-attachment: scroll;
background-size: auto;
background-image: linear-gradient(#39960c 0%, #39960c 100%);
}
#ij93 {
padding: 10px;
}
#ilfj {
color: #ffffff;
text-align: left;
font-weight: 900;
font-size: 3rem;
}
#ihfp {
height: 577px;
}
#i23r {
padding: 10px;
}
@media (max-width: 768px) {
.gjs-row {
flex-wrap: wrap;
}
}
</style>
</head>
<body id="iohk">
<div class="gjs-row" id="iir1">
<div class="gjs-cell" id="im43">
<div id="ij93">
<span id="ilfj">Waste Care Technologies</span>
</div>
</div>
</div>
<div class="gjs-row" id="ihfp">
<div class="gjs-cell" id="ihbs">
<div id="i23r">Dear {{ email }},
<br/>
<br/>A Quote with {{ quoteID }} is created by you.
<br/>
<br/>Current Quote is in {{ status }} status.
<br/>
<br/>Thank you for choosing us
</div>
</div>
</div>
</body>

16
src/main.ts Normal file
View File

@ -0,0 +1,16 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as bodyParser from 'body-parser';
import * as configMaster from './app-config/config.json';
import { Utility } from './common/Utility';
async function bootstrap() {
Utility.appPort = configMaster.local.appConfig.port;
Utility.mailConfig = configMaster.local.mailConfig;
Utility.fileConfig = configMaster.local.fileConfig;
const app = await NestFactory.create(AppModule, { cors: true });
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
await app.listen(Utility.appPort);
}
bootstrap();

View File

@ -0,0 +1,104 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { GenericResponse } from 'src/common/GenericResponse.model';
import MasterConfigCategory from './master-config-category.entity';
import { MasterConfigCategoryService } from './master-config-category.service';
@Controller('master-config/category')
export class MasterConfigCategoryController {
constructor(private masterConfigService: MasterConfigCategoryService) { }
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.masterConfigService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_IN_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() masterConfig: MasterConfigCategory, @Res() res: Response) {
if (!masterConfig) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.filter(masterConfig) || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() masterConfig: MasterConfigCategory, @Res() res: Response) {
if (!masterConfig) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete masterConfig.id;
const response = await this.masterConfigService.upsert(masterConfig, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() masterConfig: MasterConfigCategory, @Res() res: Response) {
if (!masterConfig || !masterConfig.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.upsert(masterConfig, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,34 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({tableName: 'master_config_category_ref'})
export default class MasterConfigCategory extends Model {
@Column({type: DataType.TEXT})
categoryName: string;
@Column({type: DataType.TEXT})
categoryCode: number;
@Column({type: DataType.TEXT})
categoryDescription: string;
@Column({type: DataType.TEXT})
categoryType: string;
@Column({type: DataType.TEXT})
parentCode: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import MasterConfigCategory from './master-config-category.entity';
@Injectable()
export class MasterConfigCategoryService {
async findAll(): Promise<{rows: MasterConfigCategory[], count: number}> {
return MasterConfigCategory.findAndCountAll();
}
findByPk(id: number): Promise<MasterConfigCategory> {
return MasterConfigCategory.findByPk(id)
}
filter(masterConfig: MasterConfigCategory) : Promise<MasterConfigCategory[]> {
return MasterConfigCategory.findAll({where: masterConfig as any})
}
findOne(masterConfig: MasterConfigCategory): Promise<MasterConfigCategory> {
return MasterConfigCategory.findOne({where: masterConfig as any})
}
async remove(id: number): Promise<number> {
return MasterConfigCategory.destroy({where: {id: id}});
}
async upsert(masterConfig: MasterConfigCategory, insertIfNotFound: boolean): Promise<MasterConfigCategory | [affectedCount: number]> {
if(masterConfig.id) {
const existingmasterConfig = await this.findByPk(masterConfig.id);
if(existingmasterConfig) {
return MasterConfigCategory.update(masterConfig, {where: {id: masterConfig.id}});
}
}
if(insertIfNotFound) {
return MasterConfigCategory.create(masterConfig as any)
}
}
}

View File

@ -0,0 +1,105 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { GenericResponse } from 'src/common/GenericResponse.model';
import { MasterConfigMappingService } from './master-config-mapping.service';
import MasterConfigMapping from './master-config-mapping.entity';
@Controller('master-config/mapping')
export class MasterConfigMappingController {
constructor(private masterConfigService: MasterConfigMappingService) {
}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.masterConfigService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_IN_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() masterConfig: MasterConfigMapping, @Res() res: Response) {
if(!masterConfig) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.filter(masterConfig) || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() masterConfig: MasterConfigMapping, @Res() res: Response) {
if(!masterConfig) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete masterConfig.id;
const response = await this.masterConfigService.upsert(masterConfig, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() masterConfig: MasterConfigMapping, @Res() res: Response) {
if(!masterConfig || !masterConfig.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.upsert(masterConfig, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,34 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({tableName: 'master_config_mapping'})
export default class MasterConfigMapping extends Model {
@Column({type: DataType.TEXT})
configCode: string;
@Column({type: DataType.TEXT})
companyCode: string;
@Column({type: DataType.TEXT})
status: string;
@Column({type: DataType.TEXT})
dispSerialNumber: string;
@Column({type: DataType.TEXT})
defaultValue: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,39 @@
import { Injectable } from '@nestjs/common';
import MasterConfigMapping from './master-config-mapping.entity';
@Injectable()
export class MasterConfigMappingService {
async findAll(): Promise<{rows: MasterConfigMapping[], count: number}> {
return MasterConfigMapping.findAndCountAll();
}
findByPk(id: number): Promise<MasterConfigMapping> {
return MasterConfigMapping.findByPk(id)
}
filter(masterConfig: MasterConfigMapping) : Promise<MasterConfigMapping[]> {
return MasterConfigMapping.findAll({where: masterConfig as any})
}
findOne(masterConfig: MasterConfigMapping): Promise<MasterConfigMapping> {
return MasterConfigMapping.findOne({where: masterConfig as any})
}
async remove(id: number): Promise<number> {
return MasterConfigMapping.destroy({where: {id: id}});
}
async upsert(masterConfig: MasterConfigMapping, insertIfNotFound: boolean): Promise<MasterConfigMapping | [affectedCount: number]> {
if(masterConfig.id) {
const existingUser = await this.findByPk(masterConfig.id);
if(existingUser) {
return MasterConfigMapping.update(masterConfig, {where: {id: masterConfig.id}});
}
}
if(insertIfNotFound) {
return MasterConfigMapping.create(masterConfig as any)
}
}
}

View File

@ -0,0 +1,102 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { MasterConfigService } from './master-config.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import MasterConfig from './master-config.entity';
@Controller('master-config')
export class MasterConfigController {
constructor(private masterConfigService: MasterConfigService) {}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.masterConfigService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() masterConfig: MasterConfig, @Res() res: Response) {
if(!masterConfig) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.filter(masterConfig) || [];
const httpResponse = new GenericResponse(null, response)
res.status(200).send(httpResponse);
}
@Post()
async insert(@Body() masterConfig: MasterConfig, @Res() res: Response) {
if(!masterConfig) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.upsert(masterConfig, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() masterConfig: MasterConfig, @Res() res: Response) {
if(!masterConfig || !masterConfig.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.upsert(masterConfig, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.masterConfigService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,38 @@
import { Table, Column, Model, Default, DataType, Unique } from 'sequelize-typescript';
@Table({tableName: 'master_config_ref'})
export default class MasterConfig extends Model {
@Unique(true)
@Column({type: DataType.TEXT})
configCode: string;
@Column({type: DataType.TEXT})
configName: string;
@Column({type: DataType.TEXT})
configCategoryCode: string;
@Column({type: DataType.TEXT})
configDesc: string;
@Column({type: DataType.TEXT})
parentCode: string;
@Column({type: DataType.TEXT})
configType: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { MasterConfigMappingController } from './master-config-mapping/master-config-mapping.controller';
import { MasterConfigCategoryController } from './master-config-category/master-config-category.controller';
import { MasterConfigController } from './master-config.controller';
import { MasterConfigService } from './master-config.service';
import { MasterConfigMappingService } from './master-config-mapping/master-config-mapping.service';
import { MasterConfigCategoryService } from './master-config-category/master-config-category.service';
@Module({
controllers: [MasterConfigController, MasterConfigMappingController, MasterConfigCategoryController],
providers: [MasterConfigService, MasterConfigMappingService, MasterConfigCategoryService],
imports: []
})
export class MasterConfigModule { }

View File

@ -0,0 +1,43 @@
import { Injectable } from '@nestjs/common';
import MasterConfig from './master-config.entity';
@Injectable()
export class MasterConfigService {
constructor() { }
async findAll(): Promise<{rows: MasterConfig[], count: number}> {
return MasterConfig.findAndCountAll();
}
findByPk(id: number): Promise<MasterConfig> {
return MasterConfig.findByPk(id)
}
findOne(masterConfig: MasterConfig): Promise<MasterConfig> {
return MasterConfig.findOne({where: masterConfig as any})
}
filter(masterConfig: MasterConfig) : Promise<MasterConfig[]> {
return MasterConfig.findAll({where: masterConfig as any})
}
async remove(id: number): Promise<number> {
return MasterConfig.destroy({where: {id: id}});
}
async upsert(masterConfig: MasterConfig, insertIfNotFound: boolean): Promise<MasterConfig | [affectedCount: number]> {
if(masterConfig.id) {
const existingUser = await this.findByPk(masterConfig.id);
if(existingUser) {
return MasterConfig.update(masterConfig, {where: {id: masterConfig.id}});
}
}
if(insertIfNotFound) {
return MasterConfig.create(masterConfig as any)
}
}
async login(masterConfig: MasterConfig): Promise<MasterConfig> {
return MasterConfig.findOne({where: masterConfig as any})
}
}

View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { GenericResponse } from 'src/common/GenericResponse.model';
import { SubscriptionService } from './subscription.service';
import Subscription from './subscription.entity';
@Controller('subscriptions')
export class SubscriptionController {
constructor(private subscriptionsService: SubscriptionService) {}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.subscriptionsService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.subscriptionsService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() subscription: Subscription, @Res() res: Response) {
if(!subscription) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.subscriptionsService.filter(subscription) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() subscription: Subscription, @Res() res: Response) {
if(!subscription) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete subscription.id;
const response = await this.subscriptionsService.upsert(subscription, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() subscription: Subscription, @Res() res: Response) {
if(!subscription || !subscription.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.subscriptionsService.upsert(subscription, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.subscriptionsService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,55 @@
import { Table, Column, Model, Default, DataType, ForeignKey } from 'sequelize-typescript';
import { User } from 'src/user/user.entity';
@Table({ tableName: 'subscription', timestamps: true })
export default class Subscription extends Model {
@Column({ type: DataType.BIGINT, primaryKey: true, autoIncrement: true })
id: number;
@ForeignKey(() => User)
@Column({ type: DataType.BIGINT })
user_id: number;
@Column({ type: DataType.TEXT })
plan_type: string;
@Column({ type: DataType.DATEONLY })
start_date: Date;
@Column({ type: DataType.DATEONLY })
end_date: Date;
@Default(true)
@Column({ type: DataType.BOOLEAN })
is_active: boolean;
@Column({ type: DataType.TEXT })
status: string;
@Default(new Date())
@Column({ type: DataType.DATEONLY })
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({ type: DataType.DATEONLY })
validTill: Date;
@Column({ type: DataType.DATE })
createdAt: Date;
@Column({ type: DataType.DATE })
updatedAt: Date;
@Column({ type: DataType.TEXT })
createBy: string;
@Column({ type: DataType.TEXT })
modifiedBy: string;
@Column({ type: DataType.DATE })
deletedAt: Date;
@Column({ type: DataType.INTEGER })
version: number;
}

View File

@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { SubscriptionService } from './subscription.service';
// import { SubscriptionCategoryService } from './subscription-category/subscription-category.service';
import { SubscriptionController } from './subscription.controller';
// import { SubscriptionCategoryController } from './subscription-category/subscription-category.controller';
@Module({
imports: [],
providers: [SubscriptionService, ],
controllers: [SubscriptionController,]
})
export class SubscriptionsModule {}

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import Subscription from './subscription.entity';
@Injectable()
export class SubscriptionService {
async findAll(): Promise<{rows: Subscription[], count: number}> {
return Subscription.findAndCountAll();
}
findByPk(id: number): Promise<Subscription> {
return Subscription.findByPk(id)
}
filter(subscription: Subscription) : Promise<Subscription[]> {
return Subscription.findAll({where: subscription as any})
}
findOne(subscription: Subscription): Promise<Subscription> {
return Subscription.findOne({where: subscription as any})
}
async remove(id: number): Promise<number> {
return Subscription.destroy({where: {id: id}});
}
async upsert(subscription: Subscription, insertIfNotFound: boolean): Promise<Subscription | [affectedCount: number]> {
if(subscription.id) {
const existingUser = await this.findByPk(subscription.id);
if(existingUser) {
return Subscription.update(subscription, {where: {id: subscription.id}});
}
}
if(insertIfNotFound) {
return Subscription.create(subscription as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserAdditionalDetailsController } from './user-additional-details.controller';
describe('UserAdditionalDetailsController', () => {
let controller: UserAdditionalDetailsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserAdditionalDetailsController],
}).compile();
controller = module.get<UserAdditionalDetailsController>(UserAdditionalDetailsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { UserAdditionalDetailsService } from './user-additional-details.service';
import { GenericResponse } from 'src/common/GenericResponse.model';
import UserAdditionalDetail from './user-additional-details.entity';
@Controller('users/addl/')
export class UserAdditionalDetailsController {
constructor(private userAdditionalDetailsService: UserAdditionalDetailsService) { }
@Get("/all")
async userTypegetAll(@Res() res: Response) {
const response = await this.userAdditionalDetailsService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async userTypeFindById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_IN_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userAdditionalDetailsService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async userTypeFilter(@Body() user: UserAdditionalDetail, @Res() res: Response) {
if (!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userAdditionalDetailsService.filter(user) || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async userTypeInsert(@Body() user: UserAdditionalDetail, @Res() res: Response) {
if (!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete user.id;
const response = await this.userAdditionalDetailsService.upsert(user, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async userTypeUpdate(@Body() user: UserAdditionalDetail, @Res() res: Response) {
if (!user || !user.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userAdditionalDetailsService.upsert(user, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async userTypeDeleteById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userAdditionalDetailsService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,31 @@
import { Table, Column, Model, Default, DataType, ForeignKey, BelongsTo } from 'sequelize-typescript';
import { User } from '../user.entity';
@Table({tableName: 'user_additional_details'})
export default class UserAdditionalDetail extends Model {
@Column({type: DataType.TEXT})
addlDataType: string;
@Column({type: DataType.NUMBER})
@ForeignKey(() => User)
userId: number;
@Column({type: DataType.TEXT})
addlDataName: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserAdditionalDetailsService } from './user-additional-details.service';
describe('UserAdditionalDetailsService', () => {
let service: UserAdditionalDetailsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserAdditionalDetailsService],
}).compile();
service = module.get<UserAdditionalDetailsService>(UserAdditionalDetailsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import UserAdditionalDetail from './user-additional-details.entity';
@Injectable()
export class UserAdditionalDetailsService {
async findAll(): Promise<{rows: UserAdditionalDetail[], count: number}> {
return UserAdditionalDetail.findAndCountAll();
}
findByPk(id: number): Promise<UserAdditionalDetail> {
return UserAdditionalDetail.findByPk(id)
}
filter(userAdditionalDetail: UserAdditionalDetail) : Promise<UserAdditionalDetail[]> {
return UserAdditionalDetail.findAll({where: userAdditionalDetail as any})
}
findOne(user: UserAdditionalDetail): Promise<UserAdditionalDetail> {
return UserAdditionalDetail.findOne({where: user as any})
}
async remove(id: number): Promise<number> {
return UserAdditionalDetail.destroy({where: {id: id}});
}
async upsert(userDetail: UserAdditionalDetail, insertIfNotFound: boolean): Promise<UserAdditionalDetail | [affectedCount: number]> {
if(userDetail.id) {
const existingUser = await this.findByPk(userDetail.id);
if(existingUser) {
return UserAdditionalDetail.update(userDetail, {where: {id: userDetail.id}});
}
}
if(insertIfNotFound) {
return UserAdditionalDetail.create(userDetail as any)
}
}
}

View File

@ -0,0 +1,108 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { GenericResponse } from 'src/common/GenericResponse.model';
import UserType from './user-type.entity';
import { UserTypesService } from './user-types.service';
@Controller('users/types')
export class UserTypesController {
constructor(private userTypeService?: UserTypesService) {
if(!userTypeService) {
userTypeService = new UserTypesService();
}
}
@Get("/all")
async userTypegetAll(@Res() res: Response) {
const response = await this.userTypeService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async userTypeFindById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_IN_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userTypeService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async userTypeFilter(@Body() user: UserType, @Res() res: Response) {
if(!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userTypeService.filter(user) || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async userTypeInsert(@Body() user: UserType, @Res() res: Response) {
if(!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete user.id;
const response = await this.userTypeService.upsert(user, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async userTypeUpdate(@Body() user: UserType, @Res() res: Response) {
if(!user || !user.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userTypeService.upsert(user, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async userTypeDeleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userTypeService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,44 @@
import { Table, Column, Model, Default, DataType, Unique } from 'sequelize-typescript';
@Table({ tableName: 'user_type' })
export default class UserType extends Model {
@Unique(true)
@Column({ type: DataType.TEXT })
userTypeCode: string;
@Column({ type: DataType.TEXT })
userTypeName: string;
@Column({ type: DataType.TEXT })
userTypeDesc: string;
@Column({ type: DataType.TEXT })
status: string;
@Default(new Date())
@Column({ type: DataType.DATEONLY })
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({ type: DataType.DATEONLY })
validTill: Date;
@Column({ type: DataType.TEXT })
createBy: string;
@Column({ type: DataType.TEXT })
modifiedBy: string;
@Column({ type: DataType.DATE })
createdAt: Date;
@Column({ type: DataType.DATE })
updatedAt: Date;
@Column({ type: DataType.DATE })
deletedAt: Date;
@Column({ type: DataType.NUMBER })
version: number;
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserTypesService } from './user-types.service';
describe('UserTypesService', () => {
let service: UserTypesService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserTypesService],
}).compile();
service = module.get<UserTypesService>(UserTypesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,39 @@
import { Injectable } from '@nestjs/common';
import UserType from './user-type.entity';
@Injectable()
export class UserTypesService {
async findAll(): Promise<{rows: UserType[], count: number}> {
return UserType.findAndCountAll();
}
findByPk(id: number): Promise<UserType> {
return UserType.findByPk(id)
}
filter(userType: UserType) : Promise<UserType[]> {
return UserType.findAll({where: userType as any})
}
findOne(user: UserType): Promise<UserType> {
return UserType.findOne({where: user as any})
}
async remove(id: number): Promise<number> {
return UserType.destroy({where: {id: id}});
}
async upsert(userDetail: UserType, insertIfNotFound: boolean): Promise<UserType | [affectedCount: number]> {
if(userDetail.id) {
const existingUser = await this.findByPk(userDetail.id);
if(existingUser) {
return UserType.update(userDetail, {where: {id: userDetail.id}});
}
}
if(insertIfNotFound) {
return UserType.create(userDetail as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserController } from './user.controller';
describe('UserController', () => {
let controller: UserController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController],
}).compile();
controller = module.get<UserController>(UserController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

136
src/user/user.controller.ts Normal file
View File

@ -0,0 +1,136 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { UserService } from './user.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import { User } from './user.entity';
@Controller('users')
export class UserController {
constructor(private userService: UserService) {}
@Get("/all")
async getAllUsers(@Res() res: Response) {
const response = await this.userService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() user: User, @Res() res: Response) {
if(!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userService.filter(user) || [];
const httpResponse = new GenericResponse(null, response)
res.status(200).send(httpResponse);
}
@Post()
async insert(@Body() user: User, @Res() res: Response) {
if(!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete user.id;
if(user.password) {
user.password = this.encryptPassword(user.password);
}
const response = await this.userService.upsert(user, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() user: User, @Res() res: Response) {
if(!user || !user.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
if(user.password) {
user.password = this.encryptPassword(user.password);
}
const response = await this.userService.upsert(user, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.userService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/login')
async login(@Body() user: User, @Res() res: Response) {
if(!user || !user.email || !user.password) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.status(401).send(response);
return;
}
user.password = this.encryptPassword(user.password);
user.status = 'active';
const response = {user: {} as User, token: ''};
response.user = await this.userService.login(user) || {} as User;
if(response.user && response.user.id) {
response.token = await this.encryptPassword(response.user.email);
}
const httpResponse = new GenericResponse(null, response)
res.status(200).send(httpResponse);
}
encryptPassword(password: string) {
return Buffer.from(password).toString('base64');
}
}

59
src/user/user.entity.ts Normal file
View File

@ -0,0 +1,59 @@
import { Table, Column, Model, Default, DataType, HasMany, Unique, ForeignKey } from 'sequelize-typescript';
import UserAdditionalDetail from './user-additional-details/user-additional-details.entity';
import UserType from './user-types/user-type.entity';
@Table({ tableName: 'users' })
export class User extends Model {
@Unique(true)
@Column({ type: DataType.TEXT })
email: string;
@Column({ type: DataType.TEXT })
name: string;
@Column({ type: DataType.TEXT })
password: string;
@ForeignKey(() => UserType)
@Column({ type: DataType.TEXT })
userTypeCode: string;
@Column({ type: DataType.TEXT })
primaryRole: string;
@Column({ type: DataType.TEXT })
instituteCode: string;
@Column({ type: DataType.TEXT })
status: string;
@Default(new Date())
@Column({ type: DataType.DATEONLY })
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({ type: DataType.DATEONLY })
validTill: Date;
@Column({ type: DataType.TEXT })
createBy: string;
@Column({ type: DataType.TEXT })
modifiedBy: string;
@Column({ type: DataType.DATE })
createdAt: Date;
@Column({ type: DataType.DATE })
updatedAt: Date;
@Column({ type: DataType.DATE })
deletedAt: Date;
@Column({ type: DataType.NUMBER })
version: number;
@HasMany(() => UserAdditionalDetail)
additionalDetails: UserAdditionalDetail[];
}

14
src/user/user.module.ts Normal file
View File

@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { UserTypesService } from './user-types/user-types.service';
import { UserTypesController } from './user-types/user-type.controller';
import { UserAdditionalDetailsController } from './user-additional-details/user-additional-details.controller';
import { UserAdditionalDetailsService } from './user-additional-details/user-additional-details.service';
@Module({
controllers: [UserController, UserTypesController, UserAdditionalDetailsController],
providers: [UserService, UserTypesService, UserAdditionalDetailsService],
imports: []
})
export class UserModule { }

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserService],
}).compile();
service = module.get<UserService>(UserService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

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