Default user getting created automatically while updating rfq - nestjs

When I am trying to update the RFQ it is creating a user automatically using the default value but its nowhere mentioned in the code to create a default new user checked the relations also but couldnot find anything solid
service section
async update(id: number, data: UpdateRfqDto) {
const project = await Rfq.findOne({ where: { id: id } });
if (!project) throw new NotFoundException('Project not found');
const assignee = await this.usersService.findUserById(data.assignee);
if (!assignee) throw new NotFoundException('Assignee not found');
if (data.dueDate) data.dueDate = moment.utc(data.dueDate).format();
if (data.status != 'draft' && !(data.assignee)) throw new NotAcceptableException()
// data.user=assignee
// return data.nonMember;
if (data.nonMember) {
const mem = data.nonMember
const nonmember = (mem.includes(",")) ? mem.split(",") : mem;
this.SendEmailToNonMemberVendor(nonmember, project, data.dueDate);
}
delete data.nonMember;
// return assignee;
// data.user=assignee
this.SendEmailToProjectAssignee(assignee, data.dueDate, project);
let vendorsList = [];
let listVendor = [] ;
if (data.requestVendors.length > 0) {
const vendors=data.requestVendors.map((v)=>{
return v.id;
})
// return vendors;
let vendorsListt = await Users.findBy({ id: In(vendors) });
vendorsList.push(vendorsListt)
await this.SendEmailToRequestQuoteVendor(vendorsListt, data.dueDate, data);
}
delete data.assignee;
delete data.requestVendors;
// return data;
await Rfq.update(id, data);
const newRfq = await Rfq.findOne({
where: { id: id },
relations: ['user'],
});
newRfq.user = assignee;
newRfq.vendors = vendorsList;
await newRfq.save();
return newRfq;
}
async SendEmailToRequestQuoteVendor(vendor, dueDate, project) {
let due = dueDate ? moment(dueDate, 'DD-MM-YYYY') : 'not given';
for (let i = 0; i < vendor.length; i++) {
let emailData = {
name: vendor[i].fullName,
email: vendor[i].email,
subject: VendorRequestTemplate.subject,
body: VendorRequestTemplate.body,
// params:{},
params: {
name: vendor[i].fullName,
dueDate: due,
projectName: project.projectName,
},
};
await sendemail(emailData);
}
//
return vendor;
}
async SendEmailToProjectAssignee(assignee, dueDate, project) {
let due = dueDate ? moment(dueDate, 'DD-MM-YYYY') : 'not given';
let emailData = {
name: assignee.fullName,
email: assignee.email,
subject: AssigneeTemplate.subject,
body: AssigneeTemplate.body,
// params:{},
params: {
name: assignee.fullName,
dueDate: due,
projectName: project.projectName,
},
};
await sendemail(emailData);
return assignee;
}
async SendEmailToNonMemberVendor(vendorEmail, project, dueDate) {
let due = dueDate ? moment(dueDate, 'DD-MM-YYYY') : 'not given';
for (let i = 0; i < vendorEmail.length; i++) {
// if(!inviteSave){
// throw new BadRequestException();
// }
let emailData = {
name: 'Vendor',
email: vendorEmail[i],
subject: InviteVendorTemplate.subject,
body: InviteVendorTemplate.body,
// params:{},
params: {
name: 'Vendor',
dueDate: due,
projectName: project.projectName,
},
};
await sendemail(emailData);
}
return dueDate;
}
model:
import { QuoteMilestone } from 'src/quotePricing/models/quote-milestone.entity';
import { QuotePricing } from 'src/quotePricing/models/quote-pricing.entity';
import {
BaseEntity,
BeforeInsert,
BeforeUpdate,
Column,
CreateDateColumn,
Entity,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
OneToMany,
OneToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { Users } from '../../users/models/users.entity';
import { InviteVendor } from './invite.entity';
#Entity()
export class Rfq extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column()
projectName: string;
#Column({ unique: true, default: 'JOB-1' })
jobNumber: string;
#Column()
projectType: string;
#Column({ type: 'text' })
projectDescription: string;
#Column({ type: 'text' })
projectScope: string;
#Column()
attachment: string;
#Column({ default: null })
dueDate: Date;
#Column({ default: 'draft' })
status: string; //draft/created/assigned/quote/paid/completed
#Column()
#CreateDateColumn()
createdAt: Date;
#Column()
#UpdateDateColumn()
updatedAt: Date;
#ManyToOne(() => Users, (user) => user.rfqs) //Assignee
user: Users;
#ManyToOne(() => Users, (user) => user.created_by) //CreatedBy
created_by: Users;
#OneToMany(() => QuotePricing, (QuotePricing) => QuotePricing.rfq)
quotePricings: QuotePricing[];
#OneToMany(() => InviteVendor, (invite) => invite.project)
inviteVendor: InviteVendor[];
#OneToMany(() => QuoteMilestone, (milestone) => milestone.rfq)
milestone: QuoteMilestone[];
#ManyToMany(() => Users, (requestVendors: Users) => requestVendors.id, {
cascade: true,
})
#JoinTable({
name: 'rfqs_vendors',
joinColumn: {
name: 'rfqId',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'userId',
referencedColumnName: 'id',
},
})
vendors: Users[];
}
I have tried in many ways but not able to find any way out please help
and any help would be highly appriciated

Related

fill relation ManyToMany nestjs typeorm

I have a query, I'm trying to create a ManyToMany relationship between 2 tables (products and orders) the tables are created fine, but when I want to add the logic in the service to create the records I don't understand how it should be.
This is what I have written till now:
#Entity('pedido')
export class Pedido {
#PrimaryGeneratedColumn()
id: number;
#ManyToMany(() => Product)
#JoinTable({
name: 'pedidos_products',
joinColumn: {
name: 'pedido_id',
},
inverseJoinColumn: {
name: 'product_id',
},
})
product: Product[];
#Column('decimal')
quantity: number;
#Column('decimal')
price: number;
}
#Entity('product')
export class Product {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#ManyToOne(() => Category, (category) => category.product)
category: Category;
#ManyToMany(() => Pedido)
pedido: Pedido[];
}
Service:
async createPedido(body: any) {
const pedidos = body;
const pedidoInstance = new Pedido();
const productsIds = [];
pedidos.forEach(async (item: any) => {
productsIds.push(item.product_id);
pedidoInstance.price = item.price;
pedidoInstance.quantity = item.quantity;
pedidoInstance.product = productsIds;
await this.pedidoRepository.save(pedidoInstance);
});
return {
ok: true,
};
}

Save child relations with parent entity TypeORM

I'm inserting multiple entries simultaneously and wanted to store the child relationships as well, but using the code below, province isn't saving into the database. In essence, I want to save the "province" and user when I save the address, and I receive the userID and provinceID in the request.
entity.ts
#Entity()
export class Address {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column()
address1: string;
#Column({ nullable: true })
address2?: string;
#Column()
country: string;
#ManyToOne(() => Province, (province) => province.addresses, { lazy: true })
#JoinColumn({
name: 'province_id',
})
province: Province;
#ManyToOne(() => User, (user) => user.addresses, {
nullable: false,
onDelete: 'CASCADE',
lazy: true,
})
#JoinColumn({
name: 'user_id',
})
user: User;
}
Request from frontend:
[
{
"address1": "Test 1",
"address2": "Test 1",
"country": "Estonia",
"province_id": "3", // suppose uuid
"user_id": "4" // suppose uuid
},
{
"address1": "Test 2",
"address2": "Test 2",
"country": "Estonia",
"province_id": "3", // suppose uuid
"user_id": "4" // suppose uuid
}
]
service.ts
async saveAddresses (_addresses) {
const addresses: any = _addresses.map((address) => ({
...address,
user: address.user_id,
province: address.province_id
}));
const addressesToCreate = this.addressRepository.create(addresses);
await this.addressRepository.insert(addressesToCreate);
}
As you can see how I'm saving the records but unfortunately, the province and user saving as null and I don't want to query for province again n again.
I tried like this article, and works for me
The code:
//Entity
#Entity('organization')
export class Organization {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'varchar' })
name: string;
#OneToMany(() => Users, (obj) => obj.organization)
users: Users[];
}
#Entity('users')
export class Users {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'varchar' })
name: string;
#ManyToOne(() => Organization, (obj) => obj.users, { cascade: true }) // <--- cascade: true
organization: Organization;
}
//Service
async create(dto: CreateDto[]) {
try {
const orgEntity = function (name: string) {
const org = new Organization();
org.name = name;
return org;
};
const entity: any = dto.map((obj) => ({
...obj,
organization: orgEntity(obj.organization),
}));
const entityCreated = this._repoUser.create(entity);
await this._repoUser.save(entity); // <-- save
return entityCreated;
} catch (err) {
console.log(err);
}
}
//dto
export class CreateDto {
#ApiProperty()
#IsString()
name: string;
#ApiProperty()
#IsString()
organization: string;
}
//request
[
{
"name": "user-1",
"organization":"org-1"
},
{
"name": "user-2",
"organization":"org-2"
}
]

How do I return only the required nested field in NestJs?

I'm trying to get one record from a nested table.
controller:
#Get(':id/type')
async getType(): Promise<User[]> {
return this.userService.findType();
};
service:
async findType(id: FindOptionsWhere<number>): Promise<User[]> {
return this.userRepository.find({
select: [""], //here I want to select type.type_name
where: {user_id: id}
});
}
entity:
#Entity({ name: 'user' })
export class User {
#PrimaryGeneratedColumn()
public user_id: number;
#OneToOne(() => Type)
#JoinColumn({ name: "type_id", referencedColumnName: "type_id" })
public type: Type;
#Column({ nullable: true, name: 'test_id', type: 'int' })
public test_id: number;
table user:
user_id|type_id|test_id
table type:
type_id|type_name|type_adr
How can I retrieve only type.type_name in the url /:id/type ? thanks
First you have to fix some details, like the param in your route (id). So using your ex.
I'll going to modify the order of the route by convention.
// Controller
#Get('type/:id')
async getType(#Param('id') id: string): Promise<User[]> {
return this.userService.findType();
};
// Service
async findType(id: string): Promise<User[]> {
return this.userRepository.find({
select: { type: true },
where: { user_id: id }
});
}
// And using QueryBuilder
findType(id: string) {
return this.createQueryBuilder('user')
.select(['user.type'])
.where('user.user_id = :id', { id })
.getMany(); // or .getRawMany() to get the raw type
}

NestJS TypeORM ManytoMany how to save to a parameter in a related table?

I currently have a nestjs service /api/permission
To create a new permission I send the following parameters for REQUEST:
{"Id":"","EsName":"rxe2x","EnName":"rxi2x","Name":"rxclv2x","Type":"64","Role":"7,8,9"}
And RESPONSE is
{"status":201,"message":"Permission has been saved successfully.","permission":{"Id":"200","EsName":"rxe2x","EnName":"rxi2x","Name":"rxclv2x","Type":"64","Role":"7,8,9"}}
I want the Role parameter to also be saved, in the PermissionRole table, each role with an entry like this:
RoleId
PermissionId
7
200
8
200
9
200
on my permission.service.ts
async createPermission(permission: CreatePermissionDto) {
const exist = await this.permissionRepository.findOne({
where: { Name: permission.Name },
});
if (exist)
throw new ConflictException(
'The permission already exists.',
HttpStatus.CONFLICT.toString(),
);
const newPermission = await this.permissionRepository.save(permission);
return Object.assign(
{},
{
status: HttpStatus.CREATED,
message: 'Permission has been saved successfully.',
permission: newPermission,
},
);
}
summary of my Permission.entity.ts
import { Role } from './Role.entity';
#Entity('Permission', { schema: 'dbo' })
export class Permission extends BaseEntity {
#PrimaryGeneratedColumn({
type: 'int',
name: 'Id',
})
Id: number;
#Column('varchar', {
nullable: false,
name: 'Name',
})
Name: string;
#Column('int', {
nullable: false,
name: 'Type',
})
Type: number;
#Column('varchar', {
nullable: false,
name: 'EnName',
})
EnName: string;
#Column('varchar', {
nullable: false,
name: 'EsName',
})
EsName: string;
#ManyToMany(
() => Role,
(Role: Role) => Role.permissions,
)
roles: Role[];
}
summary of my Role.entity.ts
import { Permission } from './Permission.entity';
import { User } from './User.entity';
#Entity('Role', { schema: 'dbo' })
export class Role extends BaseEntity {
#PrimaryGeneratedColumn({
type: 'int',
name: 'Id',
})
Id: number;
#Column('varchar', {
nullable: false,
length: 50,
name: 'Name',
})
Name: string;
#Column('varchar', {
nullable: true,
length: 100,
name: 'AccessLevel',
})
AccessLevel: string;
#Column('bigint', {
nullable: true,
name: 'VALAccount',
})
VALAccount: string;
#Column('bit', {
name: 'CanModified',
default: '1',
})
CanModified: string;
#ManyToMany(
() => Permission,
(Permission: Permission) => Permission.roles,
{
nullable: false,
eager: true,
},
)
#JoinTable({
name: 'PermissionRole',
})
permissions: Permission[];
#ManyToMany(
() => User,
(User: User) => User.roles,
)
users: User[];
#ManyToMany(
() => User,
(User: User) => User.rolesCanAssign,
)
usersCanAssign: User[];
}
You have to define many to many like this in Permission.entity.ts
#ManyToMany(() => Role , (role) => role.id)
#JoinTable({
name: 'Permission_Role',
joinColumn: {
name: 'permissionId',
referencedColumnName: 'id'
},
inverseJoinColumn: {
name: 'roleId',
referencedColumnName: 'id'
}
})
roles: Role[];
And in permission.service.ts
async createPermission(permission: CreatePermissionDto) {
const exist = await this.permissionRepository.findOne({
where: { Name: permission.Name },
});
if (exist)
throw new ConflictException(
'The permission already exists.',
HttpStatus.CONFLICT.toString(),
);
const newPermissionDao = this.permissionRepository.create(permission);
newPermissionDao.roles = permission.roles.map((role) => {roleId: role, permissionId: newPermissionDao.id} );
const newPermission = await this.permissionRepository.save(newPermissionDao);
return Object.assign(
{},
{
status: HttpStatus.CREATED,
message: 'Permission has been saved successfully.',
permission: newPermission,
},
);
}
Basically you need to create an array of object for many to many relation like below:
permission.roles = [{
roleId: 1,
permissionId: 1
},
{
roleId: 2,
permissionId: 1
}];

TypeScript : MongoDB set method doesn't exist

I am working on an application in TypeScript and this is the first time I have gotten this error.
I am unable to use set method on an instance of a model.
Here is the model:
import mongoose from 'mongoose';
import { OrderStatus } from '#karantickets/common';
import { updateIfCurrentPlugin } from 'mongoose-update-if-current';
interface OrderAttrs {
id: string;
version: number;
userId: string;
price: number;
status: OrderStatus;
};
interface OrderDoc extends mongoose.Document {
version: number;
userId: string;
price: number;
status: OrderStatus;
};
interface OrderModel extends mongoose.Model<OrderDoc> {
build(attrs: OrderAttrs): OrderDoc;
};
const orderSchema = new mongoose.Schema({
userId: { type: String, required: true },
price: { type: Number, required: true },
status: { type: String, required: true }
}, {
toJSON: {
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
}
}
});
orderSchema.set('versionKey', 'version');
orderSchema.plugin(updateIfCurrentPlugin);
orderSchema.statics.build = (attrs: OrderAttrs) => {
return new Order({
_id: attrs.id,
version: attrs.version,
userId: attrs.userId,
price: attrs.price,
status: attrs.status
});
};
const Order = mongoose.model<OrderDoc, OrderModel>('Order', orderSchema);
export { Order };
And here is where I am using the <object.set()> method:
export class OrderCancelledListener extends Listener<OrderCancelledEvent> {
queueGroupName = queueGroupName;
subject: Subjects.OrderCancelled = Subjects.OrderCancelled;
async onMessage(data: OrderCancelledEvent['data'], msg: Message) {
const order = Order.findOne({
_id: data.id,
version: data.version - 1
});
if (!order) throw new Error('Order not found');
order.set({ // < -------------------------------- ERROR !!
status: OrderStatus.Cancelled
});
msg.ack();
}
}
Error: Property 'set' does not exist on type 'DocumentQuery<OrderDoc | null, OrderDoc, {}>'
Thanks in advance!

Resources