This commit is contained in:
@@ -445,73 +445,108 @@ export class UserService {
|
||||
errors: [],
|
||||
};
|
||||
|
||||
const validRows: Array<{ row: (typeof rows)[number]; phone: string }> = [];
|
||||
|
||||
for (const row of rows) {
|
||||
try {
|
||||
if (!row.phone) {
|
||||
result.errors.push({
|
||||
row: row.rowNumber,
|
||||
message: UserImportMessage.PHONE_REQUIRED,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if (!row.phone) {
|
||||
result.errors.push({
|
||||
row: row.rowNumber,
|
||||
message: UserImportMessage.PHONE_REQUIRED,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const normalizedPhone = normalizePhone(row.phone);
|
||||
if (!normalizedPhone) {
|
||||
result.errors.push({
|
||||
row: row.rowNumber,
|
||||
phone: row.phone,
|
||||
message: UserImportMessage.INVALID_PHONE,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
let user = await this.userRepository.findOne({ phone: normalizedPhone });
|
||||
|
||||
if (!user) {
|
||||
const createData = {
|
||||
phone: normalizedPhone,
|
||||
firstName: row.firstName?.trim() || '[نام]',
|
||||
lastName: row.lastName?.trim() || undefined,
|
||||
gender: row.gender,
|
||||
birthDate: undefined,
|
||||
marriageDate: undefined,
|
||||
} as unknown as RequiredEntityData<User>;
|
||||
|
||||
user = this.userRepository.create(createData);
|
||||
await this.em.persistAndFlush(user);
|
||||
result.usersCreated++;
|
||||
} else {
|
||||
const updates: Partial<User> = {};
|
||||
if (row.firstName?.trim()) {
|
||||
updates.firstName = row.firstName.trim();
|
||||
}
|
||||
if (row.lastName?.trim()) {
|
||||
updates.lastName = row.lastName.trim();
|
||||
}
|
||||
if (row.gender !== undefined) {
|
||||
updates.gender = row.gender;
|
||||
}
|
||||
if (Object.keys(updates).length > 0) {
|
||||
this.em.assign(user, updates);
|
||||
await this.em.flush();
|
||||
}
|
||||
}
|
||||
|
||||
const existingLink = await this.userRestaurantRepository.findOne({ user, restaurant });
|
||||
if (existingLink) {
|
||||
result.usersAlreadyLinked++;
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.addUserToRestaurant(user, restaurant);
|
||||
result.usersLinked++;
|
||||
} catch (error) {
|
||||
const normalizedPhone = normalizePhone(row.phone);
|
||||
if (!normalizedPhone) {
|
||||
result.errors.push({
|
||||
row: row.rowNumber,
|
||||
phone: row.phone,
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
message: UserImportMessage.INVALID_PHONE,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
validRows.push({ row, phone: normalizedPhone });
|
||||
}
|
||||
|
||||
if (validRows.length === 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const phones = [...new Set(validRows.map(entry => entry.phone))];
|
||||
const existingUsers = await this.userRepository.find({ phone: { $in: phones } });
|
||||
const userByPhone = new Map(existingUsers.map(user => [user.phone, user]));
|
||||
|
||||
for (const { row, phone } of validRows) {
|
||||
let user = userByPhone.get(phone);
|
||||
|
||||
if (!user) {
|
||||
const createData = {
|
||||
phone,
|
||||
firstName: row.firstName?.trim() || '[نام]',
|
||||
lastName: row.lastName?.trim() || undefined,
|
||||
gender: row.gender,
|
||||
birthDate: undefined,
|
||||
marriageDate: undefined,
|
||||
} as unknown as RequiredEntityData<User>;
|
||||
|
||||
user = this.userRepository.create(createData);
|
||||
userByPhone.set(phone, user);
|
||||
result.usersCreated++;
|
||||
} else {
|
||||
const updates: Partial<User> = {};
|
||||
if (row.firstName?.trim()) {
|
||||
updates.firstName = row.firstName.trim();
|
||||
}
|
||||
if (row.lastName?.trim()) {
|
||||
updates.lastName = row.lastName.trim();
|
||||
}
|
||||
if (row.gender !== undefined) {
|
||||
updates.gender = row.gender;
|
||||
}
|
||||
if (Object.keys(updates).length > 0) {
|
||||
this.em.assign(user, updates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const userIds = [...userByPhone.values()].map(user => user.id);
|
||||
const existingLinks = await this.userRestaurantRepository.find(
|
||||
{ restaurant, user: { $in: userIds } },
|
||||
{ populate: ['user'] },
|
||||
);
|
||||
const linkedUserIds = new Set(existingLinks.map(link => link.user.id));
|
||||
const linkedPhonesInBatch = new Set<string>();
|
||||
|
||||
for (const { phone } of validRows) {
|
||||
const user = userByPhone.get(phone);
|
||||
if (!user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (linkedUserIds.has(user.id) || linkedPhonesInBatch.has(phone)) {
|
||||
result.usersAlreadyLinked++;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.userRestaurantRepository.create({
|
||||
user,
|
||||
restaurant,
|
||||
orderCount: 0,
|
||||
totalOrderAmount: 0,
|
||||
});
|
||||
linkedUserIds.add(user.id);
|
||||
linkedPhonesInBatch.add(phone);
|
||||
result.usersLinked++;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.em.flush();
|
||||
} catch (error) {
|
||||
result.errors.push({
|
||||
row: 0,
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user