user
This commit is contained in:
@@ -50,8 +50,6 @@ export class Order extends BaseEntity {
|
|||||||
@ManyToOne(() => Admin, { nullable: true })
|
@ManyToOne(() => Admin, { nullable: true })
|
||||||
designer?: Admin
|
designer?: Admin
|
||||||
|
|
||||||
// @Property({ nullable: true })
|
|
||||||
// userAddress?: string | null;
|
|
||||||
|
|
||||||
@Property({ type: 'int', nullable: true })
|
@Property({ type: 'int', nullable: true })
|
||||||
orderNumber?: number;
|
orderNumber?: number;
|
||||||
@@ -67,9 +65,6 @@ export class Order extends BaseEntity {
|
|||||||
taxAmount: number;
|
taxAmount: number;
|
||||||
|
|
||||||
|
|
||||||
// @Property({ type: 'decimal', precision: 10, scale: 0, default: 0 })
|
|
||||||
// deliveryFee: number = 0;
|
|
||||||
|
|
||||||
@Property({ type: 'decimal', precision: 10, scale: 0 })
|
@Property({ type: 'decimal', precision: 10, scale: 0 })
|
||||||
total!: number;
|
total!: number;
|
||||||
|
|
||||||
@@ -97,8 +92,6 @@ export class Order extends BaseEntity {
|
|||||||
@Enum(() => OrderStatusEnum)
|
@Enum(() => OrderStatusEnum)
|
||||||
status!: OrderStatusEnum;
|
status!: OrderStatusEnum;
|
||||||
|
|
||||||
// @Property({ nullable: true, columnType: 'timestamptz' })
|
|
||||||
// confirmedAt?: Date;
|
|
||||||
|
|
||||||
@Property({ type: 'json', nullable: true })
|
@Property({ type: 'json', nullable: true })
|
||||||
attachments?: string[]
|
attachments?: string[]
|
||||||
|
|||||||
@@ -44,16 +44,9 @@ export class UsersController {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(AuthGuard)
|
|
||||||
@ApiBearerAuth()
|
|
||||||
@ApiOperation({ summary: 'Get all addresses for the authenticated user' })
|
|
||||||
|
|
||||||
@ApiOkResponse({ description: 'List of user addresses' })
|
|
||||||
@Get('public/user/addresses')
|
|
||||||
async getUserAddresses(@UserId() userId: string) {
|
|
||||||
const addresses = await this.userService.getUserAddresses(userId);
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @UseGuards(AuthGuard)
|
// @UseGuards(AuthGuard)
|
||||||
// @ApiBearerAuth()
|
// @ApiBearerAuth()
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ export class CreateUserDto {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
lastName?: string;
|
lastName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Address", example: '' })
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
address?: string;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Gender flag (boolean)', example: true })
|
@ApiProperty({ description: 'Gender flag (boolean)', example: true })
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
gender: boolean;
|
gender: boolean;
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
import { Entity, Property, ManyToOne, PrimaryKey } from '@mikro-orm/core';
|
|
||||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
|
||||||
import { User } from './user.entity';
|
|
||||||
|
|
||||||
@Entity({ tableName: 'user_addresses' })
|
|
||||||
export class UserAddress extends BaseEntity {
|
|
||||||
@PrimaryKey({ type: 'bigint', autoincrement: true })
|
|
||||||
id: bigint
|
|
||||||
|
|
||||||
@ManyToOne(() => User)
|
|
||||||
user!: User;
|
|
||||||
|
|
||||||
@Property()
|
|
||||||
title!: string; // e.g., "Home", "Work", "Office"
|
|
||||||
|
|
||||||
@Property()
|
|
||||||
address!: string;
|
|
||||||
|
|
||||||
@Property()
|
|
||||||
city!: string;
|
|
||||||
|
|
||||||
@Property({ nullable: true })
|
|
||||||
province?: string;
|
|
||||||
|
|
||||||
@Property({ nullable: true })
|
|
||||||
postalCode?: string | null = null;
|
|
||||||
|
|
||||||
@Property({ type: 'float' })
|
|
||||||
latitude!: number;
|
|
||||||
|
|
||||||
@Property({ type: 'float' })
|
|
||||||
longitude!: number;
|
|
||||||
|
|
||||||
@Property({ nullable: true })
|
|
||||||
phone?: string; // Contact phone for this address
|
|
||||||
|
|
||||||
@Property({ default: false })
|
|
||||||
isDefault: boolean = false; // Whether this is the default address
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Entity, Index, Property, OneToMany, Collection, Cascade, PrimaryKey } from '@mikro-orm/core';
|
import { Entity, Index, Property, OneToMany, Collection, Cascade, PrimaryKey } from '@mikro-orm/core';
|
||||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||||
import { UserAddress } from './user-address.entity';
|
|
||||||
import { Order } from 'src/modules/order/entities/order.entity';
|
import { Order } from 'src/modules/order/entities/order.entity';
|
||||||
import { normalizePhone } from '../../util/phone.util';
|
import { normalizePhone } from '../../util/phone.util';
|
||||||
import { ulid } from 'ulid';
|
import { ulid } from 'ulid';
|
||||||
@@ -41,9 +40,6 @@ export class User extends BaseEntity {
|
|||||||
@Property({ default: 0 })
|
@Property({ default: 0 })
|
||||||
maxCredit: number;
|
maxCredit: number;
|
||||||
|
|
||||||
@OneToMany(() => UserAddress, address => address.user, {
|
@Property({ type: 'string', nullable: true })
|
||||||
cascade: [Cascade.ALL],
|
addresse?: string
|
||||||
orphanRemoval: true,
|
|
||||||
})
|
|
||||||
addresses = new Collection<UserAddress>(this);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
||||||
import { RequiredEntityData } from '@mikro-orm/core';
|
import { RequiredEntityData } from '@mikro-orm/core';
|
||||||
import { User } from '../entities/user.entity';
|
import { User } from '../entities/user.entity';
|
||||||
import { UserAddress } from '../entities/user-address.entity';
|
|
||||||
import { EntityManager } from '@mikro-orm/postgresql';
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
import { CreateUserDto } from '../dto/create-user.dto';
|
import { CreateUserDto } from '../dto/create-user.dto';
|
||||||
import { FindUsersDto } from '../dto/find-user.dto';
|
import { FindUsersDto } from '../dto/find-user.dto';
|
||||||
@@ -69,135 +68,5 @@ export class UserService {
|
|||||||
return this.userRepository.findAllPaginated(dto)
|
return this.userRepository.findAllPaginated(dto)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserAddresses(userId: string): Promise<UserAddress[]> {
|
|
||||||
const user = await this.userRepository.findOne({ id: userId }, { populate: ['addresses'] });
|
|
||||||
if (!user) {
|
|
||||||
throw new NotFoundException(`User with ID ${userId} not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load addresses if not already loaded
|
|
||||||
await user.addresses.loadItems();
|
|
||||||
return user.addresses.getItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
// async createUserAddress(userId: string, dto: CreateUserAddressDto): Promise<UserAddress> {
|
|
||||||
// const user = await this.userRepository.findOne({ id: userId });
|
|
||||||
// if (!user) {
|
|
||||||
// throw new NotFoundException(`User with ID ${userId} not found.`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // If setting as default, unset other default addresses
|
|
||||||
// if (dto.isDefault) {
|
|
||||||
// const existingAddresses = await this.em.find(UserAddress, { user: { id: userId }, isDefault: true });
|
|
||||||
// for (const address of existingAddresses) {
|
|
||||||
// address.isDefault = false;
|
|
||||||
// }
|
|
||||||
// await this.em.flush();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Create new address
|
|
||||||
// const address = this.em.create(UserAddress, {
|
|
||||||
// user,
|
|
||||||
// title: dto.title,
|
|
||||||
// address: dto.address,
|
|
||||||
// city: dto.city,
|
|
||||||
// province: dto.province,
|
|
||||||
// postalCode: dto.postalCode,
|
|
||||||
// latitude: dto.latitude,
|
|
||||||
// longitude: dto.longitude,
|
|
||||||
// phone: dto.phone,
|
|
||||||
// isDefault: dto.isDefault ?? false,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// await this.em.persistAndFlush(address);
|
|
||||||
// return address;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async getUserAddress(userId: string, addressId: string): Promise<UserAddress> {
|
|
||||||
// const address = await this.em.findOne(UserAddress, {
|
|
||||||
// id: addressId,
|
|
||||||
// user: { id: userId },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (!address) {
|
|
||||||
// throw new NotFoundException(`Address with ID ${addressId} not found for user ${userId}.`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return address;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async updateUserAddress(userId: string, addressId: string, dto: UpdateUserAddressDto): Promise<UserAddress> {
|
|
||||||
// const address = await this.em.findOne(UserAddress, {
|
|
||||||
// id: addressId,
|
|
||||||
// user: { id: userId },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (!address) {
|
|
||||||
// throw new NotFoundException(`Address with ID ${addressId} not found for user ${userId}.`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // If setting as default, unset other default addresses
|
|
||||||
// if (dto.isDefault === true) {
|
|
||||||
// const existingAddresses = await this.em.find(UserAddress, {
|
|
||||||
// user: { id: userId },
|
|
||||||
// isDefault: true,
|
|
||||||
// id: { $ne: addressId },
|
|
||||||
// });
|
|
||||||
// for (const existingAddress of existingAddresses) {
|
|
||||||
// existingAddress.isDefault = false;
|
|
||||||
// }
|
|
||||||
// await this.em.flush();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Update address fields
|
|
||||||
// this.em.assign(address, dto);
|
|
||||||
// await this.em.flush();
|
|
||||||
|
|
||||||
// return address;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async deleteUserAddress(userId: string, addressId: string): Promise<void> {
|
|
||||||
// const address = await this.em.findOne(UserAddress, {
|
|
||||||
// id: addressId,
|
|
||||||
// user: { id: userId },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (!address) {
|
|
||||||
// throw new NotFoundException(`Address with ID ${addressId} not found for user ${userId}.`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Soft delete the address
|
|
||||||
// address.deletedAt = new Date();
|
|
||||||
// await this.em.persistAndFlush(address);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async setDefaultAddress(userId: string, addressId: string): Promise<UserAddress> {
|
|
||||||
// const address = await this.em.findOne(UserAddress, {
|
|
||||||
// id: addressId,
|
|
||||||
// user: { id: userId },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (!address) {
|
|
||||||
// throw new NotFoundException(`Address with ID ${addressId} not found for user ${userId}.`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Unset all other default addresses
|
|
||||||
// const existingAddresses = await this.em.find(UserAddress, {
|
|
||||||
// user: { id: userId },
|
|
||||||
// isDefault: true,
|
|
||||||
// id: { $ne: addressId },
|
|
||||||
// });
|
|
||||||
// for (const existingAddress of existingAddresses) {
|
|
||||||
// existingAddress.isDefault = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Set this address as default
|
|
||||||
// address.isDefault = true;
|
|
||||||
// await this.em.flush();
|
|
||||||
|
|
||||||
// return address;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import { UserService } from './providers/user.service';
|
|||||||
import { UsersController } from './controllers/users.controller';
|
import { UsersController } from './controllers/users.controller';
|
||||||
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
||||||
import { User } from './entities/user.entity';
|
import { User } from './entities/user.entity';
|
||||||
import { UserAddress } from './entities/user-address.entity';
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
|
||||||
import { UserRepository } from './repositories/user.repository';
|
import { UserRepository } from './repositories/user.repository';
|
||||||
import { CreditRepository } from './repositories/credit.repository';
|
import { CreditRepository } from './repositories/credit.repository';
|
||||||
import { CreditService } from './providers/credit.service';
|
import { CreditService } from './providers/credit.service';
|
||||||
@@ -19,7 +18,7 @@ import { CreditTransaction } from './entities/credit-transaction.entity';
|
|||||||
],
|
],
|
||||||
controllers: [UsersController],
|
controllers: [UsersController],
|
||||||
imports: [
|
imports: [
|
||||||
MikroOrmModule.forFeature([User, UserAddress, CreditTransaction]),
|
MikroOrmModule.forFeature([User, CreditTransaction]),
|
||||||
JwtModule,
|
JwtModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import type { EntityManager } from '@mikro-orm/core';
|
import type { EntityManager } from '@mikro-orm/core';
|
||||||
import { User } from '../modules/user/entities/user.entity';
|
import { User } from '../modules/user/entities/user.entity';
|
||||||
import { UserAddress } from '../modules/user/entities/user-address.entity';
|
|
||||||
import { usersData } from './data/users.data';
|
import { usersData } from './data/users.data';
|
||||||
import { userAddressesData } from './data/user-addresses.data';
|
|
||||||
import { normalizePhone } from '../modules/util/phone.util';
|
import { normalizePhone } from '../modules/util/phone.util';
|
||||||
|
|
||||||
export class UsersSeeder {
|
export class UsersSeeder {
|
||||||
@@ -20,57 +18,14 @@ export class UsersSeeder {
|
|||||||
lastName: userData.lastName,
|
lastName: userData.lastName,
|
||||||
isActive: userData.isActive,
|
isActive: userData.isActive,
|
||||||
gender: userData.gender,
|
gender: userData.gender,
|
||||||
maxCredit: 0
|
maxCredit: 0,
|
||||||
|
addresse: 'اراک'
|
||||||
});
|
});
|
||||||
em.persist(user);
|
em.persist(user);
|
||||||
}
|
}
|
||||||
usersMap.set(normalizedPhone, user); // Use normalized phone as key
|
usersMap.set(normalizedPhone, user); // Use normalized phone as key
|
||||||
}
|
}
|
||||||
|
|
||||||
await em.flush();
|
|
||||||
|
|
||||||
// Create addresses for users
|
|
||||||
for (const addressData of userAddressesData) {
|
|
||||||
const normalizedPhone = normalizePhone(addressData.userPhone);
|
|
||||||
const user = usersMap.get(normalizedPhone);
|
|
||||||
if (!user) continue;
|
|
||||||
|
|
||||||
// Check if address already exists for this user
|
|
||||||
const existingAddress = await em.findOne(UserAddress, {
|
|
||||||
user: { id: user.id },
|
|
||||||
title: addressData.title,
|
|
||||||
address: addressData.address,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingAddress) {
|
|
||||||
// If setting as default, unset other default addresses for this user
|
|
||||||
if (addressData.isDefault) {
|
|
||||||
const existingDefaultAddresses = await em.find(UserAddress, {
|
|
||||||
user: { id: user.id },
|
|
||||||
isDefault: true,
|
|
||||||
});
|
|
||||||
for (const defaultAddress of existingDefaultAddresses) {
|
|
||||||
defaultAddress.isDefault = false;
|
|
||||||
em.persist(defaultAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const address = em.create(UserAddress, {
|
|
||||||
user,
|
|
||||||
title: addressData.title,
|
|
||||||
address: addressData.address,
|
|
||||||
city: addressData.city,
|
|
||||||
province: addressData.province,
|
|
||||||
postalCode: addressData.postalCode,
|
|
||||||
latitude: addressData.latitude,
|
|
||||||
longitude: addressData.longitude,
|
|
||||||
phone: addressData.phone,
|
|
||||||
isDefault: addressData.isDefault,
|
|
||||||
});
|
|
||||||
em.persist(address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await em.flush();
|
await em.flush();
|
||||||
return usersMap;
|
return usersMap;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user