update project
This commit is contained in:
@@ -49,6 +49,12 @@ const companySchema = new mongoose.Schema({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
metrics: {
|
||||||
|
type: {
|
||||||
|
profileViews: { type: Number, default: 0 }
|
||||||
|
},
|
||||||
|
default: {}
|
||||||
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
type: Date,
|
type: Date,
|
||||||
default: Date.now
|
default: Date.now
|
||||||
|
|||||||
@@ -463,6 +463,49 @@ router.patch('/profile', verifyToken, async (req, res) => {
|
|||||||
return res.status(result.status).json(result.body);
|
return res.status(result.status).json(result.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action === 'updateProfile') {
|
||||||
|
await waitForDatabaseConnection();
|
||||||
|
|
||||||
|
const { firstName, lastName, position, phone } = payload;
|
||||||
|
|
||||||
|
if (!firstName && !lastName && !position && !phone) {
|
||||||
|
return res.status(400).json({ error: 'At least one field must be provided' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await User.findById(req.userId);
|
||||||
|
if (!user) {
|
||||||
|
return res.status(404).json({ error: 'User not found' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstName) user.firstName = firstName;
|
||||||
|
if (lastName) user.lastName = lastName;
|
||||||
|
if (position !== undefined) user.position = position;
|
||||||
|
if (phone !== undefined) user.phone = phone;
|
||||||
|
user.updatedAt = new Date();
|
||||||
|
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
const company = user.companyId ? await Company.findById(user.companyId) : null;
|
||||||
|
|
||||||
|
return res.json({
|
||||||
|
message: 'Profile updated successfully',
|
||||||
|
user: {
|
||||||
|
id: user._id.toString(),
|
||||||
|
email: user.email,
|
||||||
|
firstName: user.firstName,
|
||||||
|
lastName: user.lastName,
|
||||||
|
position: user.position,
|
||||||
|
phone: user.phone,
|
||||||
|
companyId: user.companyId?.toString()
|
||||||
|
},
|
||||||
|
company: company ? {
|
||||||
|
id: company._id.toString(),
|
||||||
|
name: company.fullName,
|
||||||
|
inn: company.inn
|
||||||
|
} : null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
res.json({ message: 'Profile endpoint' });
|
res.json({ message: 'Profile endpoint' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Profile update error:', error);
|
console.error('Profile update error:', error);
|
||||||
|
|||||||
@@ -84,13 +84,30 @@ router.get('/my/stats', verifyToken, async (req, res) => {
|
|||||||
: Promise.resolve(0),
|
: Promise.resolve(0),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Подсчитываем просмотры профиля из запросов к профилю компании
|
||||||
|
const profileViews = company?.metrics?.profileViews || 0;
|
||||||
|
|
||||||
|
// Получаем статистику за последнюю неделю для изменений
|
||||||
|
const weekAgo = new Date();
|
||||||
|
weekAgo.setDate(weekAgo.getDate() - 7);
|
||||||
|
|
||||||
|
const sentRequestsLastWeek = await Request.countDocuments({
|
||||||
|
senderCompanyId: companyIdString,
|
||||||
|
createdAt: { $gte: weekAgo }
|
||||||
|
});
|
||||||
|
|
||||||
|
const receivedRequestsLastWeek = await Request.countDocuments({
|
||||||
|
recipientCompanyId: companyIdString,
|
||||||
|
createdAt: { $gte: weekAgo }
|
||||||
|
});
|
||||||
|
|
||||||
const stats = {
|
const stats = {
|
||||||
profileViews: company?.metrics?.profileViews || 0,
|
profileViews: profileViews,
|
||||||
profileViewsChange: 0,
|
profileViewsChange: 0, // Можно добавить отслеживание просмотров, если нужно
|
||||||
sentRequests,
|
sentRequests,
|
||||||
sentRequestsChange: 0,
|
sentRequestsChange: sentRequestsLastWeek,
|
||||||
receivedRequests,
|
receivedRequests,
|
||||||
receivedRequestsChange: 0,
|
receivedRequestsChange: receivedRequestsLastWeek,
|
||||||
newMessages: unreadMessages,
|
newMessages: unreadMessages,
|
||||||
rating: Number.isFinite(company?.rating) ? Number(company.rating) : 0,
|
rating: Number.isFinite(company?.rating) ? Number(company.rating) : 0,
|
||||||
};
|
};
|
||||||
@@ -231,6 +248,24 @@ router.get('/:id', async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Отслеживаем просмотр профиля (если это не владелец компании)
|
||||||
|
const userId = req.userId;
|
||||||
|
if (userId) {
|
||||||
|
const User = require('../models/User');
|
||||||
|
const user = await User.findById(userId);
|
||||||
|
if (user && user.companyId && user.companyId.toString() !== company._id.toString()) {
|
||||||
|
// Инкрементируем просмотры профиля
|
||||||
|
if (!company.metrics) {
|
||||||
|
company.metrics = {};
|
||||||
|
}
|
||||||
|
if (!company.metrics.profileViews) {
|
||||||
|
company.metrics.profileViews = 0;
|
||||||
|
}
|
||||||
|
company.metrics.profileViews = (company.metrics.profileViews || 0) + 1;
|
||||||
|
await company.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
...company.toObject(),
|
...company.toObject(),
|
||||||
id: company._id
|
id: company._id
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const express = require('express');
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const { verifyToken } = require('../middleware/auth');
|
const { verifyToken } = require('../middleware/auth');
|
||||||
const Review = require('../models/Review');
|
const Review = require('../models/Review');
|
||||||
|
const Company = require('../models/Company');
|
||||||
|
|
||||||
// Функция для логирования с проверкой DEV переменной
|
// Функция для логирования с проверкой DEV переменной
|
||||||
const log = (message, data = '') => {
|
const log = (message, data = '') => {
|
||||||
@@ -14,6 +15,35 @@ const log = (message, data = '') => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Функция для пересчета рейтинга компании
|
||||||
|
const updateCompanyRating = async (companyId) => {
|
||||||
|
try {
|
||||||
|
const reviews = await Review.find({ companyId });
|
||||||
|
|
||||||
|
if (reviews.length === 0) {
|
||||||
|
await Company.findByIdAndUpdate(companyId, {
|
||||||
|
rating: 0,
|
||||||
|
reviews: 0,
|
||||||
|
updatedAt: new Date()
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalRating = reviews.reduce((sum, review) => sum + review.rating, 0);
|
||||||
|
const averageRating = totalRating / reviews.length;
|
||||||
|
|
||||||
|
await Company.findByIdAndUpdate(companyId, {
|
||||||
|
rating: averageRating,
|
||||||
|
reviews: reviews.length,
|
||||||
|
updatedAt: new Date()
|
||||||
|
});
|
||||||
|
|
||||||
|
log('[Reviews] Updated company rating:', companyId, 'New rating:', averageRating);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Reviews] Error updating company rating:', error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// GET /reviews/company/:companyId - получить отзывы компании
|
// GET /reviews/company/:companyId - получить отзывы компании
|
||||||
router.get('/company/:companyId', verifyToken, async (req, res) => {
|
router.get('/company/:companyId', verifyToken, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
@@ -42,30 +72,54 @@ router.post('/', verifyToken, async (req, res) => {
|
|||||||
|
|
||||||
if (!companyId || !rating || !comment) {
|
if (!companyId || !rating || !comment) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'companyId, rating, and comment are required',
|
error: 'Заполните все обязательные поля: компания, рейтинг и комментарий',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rating < 1 || rating > 5) {
|
if (rating < 1 || rating > 5) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Rating must be between 1 and 5',
|
error: 'Рейтинг должен быть от 1 до 5',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comment.trim().length < 10 || comment.trim().length > 1000) {
|
const trimmedComment = comment.trim();
|
||||||
|
if (trimmedComment.length < 10) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Comment must be between 10 and 1000 characters',
|
error: 'Отзыв должен содержать минимум 10 символов',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trimmedComment.length > 1000) {
|
||||||
|
return res.status(400).json({
|
||||||
|
error: 'Отзыв не должен превышать 1000 символов',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить данные пользователя из БД для актуальной информации
|
||||||
|
const User = require('../models/User');
|
||||||
|
const Company = require('../models/Company');
|
||||||
|
|
||||||
|
const user = await User.findById(req.userId);
|
||||||
|
const userCompany = user && user.companyId ? await Company.findById(user.companyId) : null;
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return res.status(404).json({
|
||||||
|
error: 'Пользователь не найден',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Создать новый отзыв
|
// Создать новый отзыв
|
||||||
const newReview = new Review({
|
const newReview = new Review({
|
||||||
companyId,
|
companyId,
|
||||||
authorCompanyId: req.companyId,
|
authorCompanyId: user.companyId || req.companyId,
|
||||||
authorName: req.user.firstName + ' ' + req.user.lastName,
|
authorName: user.firstName && user.lastName
|
||||||
authorCompany: req.user.companyName || 'Company',
|
? `${user.firstName} ${user.lastName}`
|
||||||
|
: req.user?.firstName && req.user?.lastName
|
||||||
|
? `${req.user.firstName} ${req.user.lastName}`
|
||||||
|
: 'Аноним',
|
||||||
|
authorCompany: userCompany?.fullName || userCompany?.shortName || req.user?.companyName || 'Компания',
|
||||||
rating: parseInt(rating),
|
rating: parseInt(rating),
|
||||||
comment: comment.trim(),
|
comment: trimmedComment,
|
||||||
verified: true,
|
verified: true,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date()
|
updatedAt: new Date()
|
||||||
@@ -75,11 +129,14 @@ router.post('/', verifyToken, async (req, res) => {
|
|||||||
|
|
||||||
log('[Reviews] New review created:', savedReview._id);
|
log('[Reviews] New review created:', savedReview._id);
|
||||||
|
|
||||||
|
// Пересчитываем рейтинг компании
|
||||||
|
await updateCompanyRating(companyId);
|
||||||
|
|
||||||
res.status(201).json(savedReview);
|
res.status(201).json(savedReview);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Reviews] Error creating review:', error.message);
|
console.error('[Reviews] Error creating review:', error.message);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
error: 'Internal server error',
|
error: 'Ошибка при сохранении отзыва',
|
||||||
message: error.message,
|
message: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,29 +5,31 @@ require('dotenv').config();
|
|||||||
// Импорт моделей
|
// Импорт моделей
|
||||||
const User = require(path.join(__dirname, '..', 'models', 'User'));
|
const User = require(path.join(__dirname, '..', 'models', 'User'));
|
||||||
const Company = require(path.join(__dirname, '..', 'models', 'Company'));
|
const Company = require(path.join(__dirname, '..', 'models', 'Company'));
|
||||||
|
const Request = require(path.join(__dirname, '..', 'models', 'Request'));
|
||||||
|
|
||||||
const primaryUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/procurement_db';
|
const primaryUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/procurement_db';
|
||||||
const fallbackUri =
|
const fallbackUri =
|
||||||
process.env.MONGODB_AUTH_URI || 'mongodb://admin:password@localhost:27017/procurement_db?authSource=admin';
|
process.env.MONGODB_AUTH_URI || 'mongodb://admin:password@localhost:27017/procurement_db?authSource=admin';
|
||||||
|
|
||||||
const connectWithFallback = async () => {
|
const connectWithFallback = async () => {
|
||||||
|
// Сначала пробуем FALLBACK (с аутентификацией)
|
||||||
try {
|
try {
|
||||||
console.log('\n📡 Подключение к MongoDB (PRIMARY)...');
|
console.log('\n📡 Подключение к MongoDB (с аутентификацией)...');
|
||||||
await mongoose.connect(primaryUri, { useNewUrlParser: true, useUnifiedTopology: true });
|
await mongoose.connect(fallbackUri, { useNewUrlParser: true, useUnifiedTopology: true });
|
||||||
console.log('✅ Подключено к PRIMARY MongoDB');
|
console.log('✅ Подключено к MongoDB');
|
||||||
} catch (primaryError) {
|
return;
|
||||||
console.error('❌ Ошибка PRIMARY подключения:', primaryError.message);
|
} catch (fallbackError) {
|
||||||
|
console.log('❌ Ошибка подключения с аутентификацией:', fallbackError.message);
|
||||||
const requiresFallback =
|
|
||||||
primaryError.code === 18 || primaryError.code === 13 || String(primaryError.message || '').includes('auth');
|
|
||||||
|
|
||||||
if (!requiresFallback) {
|
|
||||||
throw primaryError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('\n📡 Подключение к MongoDB (FALLBACK)...');
|
// Если не получилось, пробуем без аутентификации
|
||||||
await mongoose.connect(fallbackUri, { useNewUrlParser: true, useUnifiedTopology: true });
|
try {
|
||||||
console.log('✅ Подключено к FALLBACK MongoDB');
|
console.log('\n📡 Подключение к MongoDB (без аутентификации)...');
|
||||||
|
await mongoose.connect(primaryUri, { useNewUrlParser: true, useUnifiedTopology: true });
|
||||||
|
console.log('✅ Подключено к MongoDB');
|
||||||
|
} catch (primaryError) {
|
||||||
|
console.error('❌ Не удалось подключиться к MongoDB:', primaryError.message);
|
||||||
|
throw primaryError;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,17 +60,26 @@ const recreateTestUser = async () => {
|
|||||||
const company = await Company.create({
|
const company = await Company.create({
|
||||||
_id: presetCompanyId,
|
_id: presetCompanyId,
|
||||||
fullName: 'ООО "Тестовая Компания"',
|
fullName: 'ООО "Тестовая Компания"',
|
||||||
|
shortName: 'Тестовая Компания',
|
||||||
inn: '1234567890',
|
inn: '1234567890',
|
||||||
ogrn: '1234567890123',
|
ogrn: '1234567890123',
|
||||||
legalForm: 'ООО',
|
legalForm: 'ООО',
|
||||||
industry: 'IT',
|
industry: 'IT',
|
||||||
companySize: '50-100',
|
companySize: '51-250',
|
||||||
website: 'https://test-company.ru',
|
website: 'https://test-company.ru',
|
||||||
|
phone: '+7 (999) 123-45-67',
|
||||||
|
email: 'info@test-company.ru',
|
||||||
description: 'Тестовая компания для разработки',
|
description: 'Тестовая компания для разработки',
|
||||||
address: 'г. Москва, ул. Тестовая, д. 1',
|
legalAddress: 'г. Москва, ул. Тестовая, д. 1',
|
||||||
|
actualAddress: 'г. Москва, ул. Тестовая, д. 1',
|
||||||
|
foundedYear: 2015,
|
||||||
|
employeeCount: '51-250',
|
||||||
|
revenue: 'До 120 млн ₽',
|
||||||
rating: 4.5,
|
rating: 4.5,
|
||||||
reviewsCount: 10,
|
reviews: 10,
|
||||||
dealsCount: 25,
|
verified: true,
|
||||||
|
partnerGeography: ['moscow', 'russia_all'],
|
||||||
|
slogan: 'Ваш надежный партнер в IT',
|
||||||
});
|
});
|
||||||
console.log(' ✓ Компания создана:', company.fullName);
|
console.log(' ✓ Компания создана:', company.fullName);
|
||||||
|
|
||||||
@@ -99,19 +110,210 @@ const recreateTestUser = async () => {
|
|||||||
console.log(' Пароль: SecurePass123!');
|
console.log(' Пароль: SecurePass123!');
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
||||||
// Обновить существующие mock компании
|
// Создать дополнительные тестовые компании для поиска
|
||||||
console.log('\n🔄 Обновление существующих mock компаний...');
|
console.log('\n🏢 Создание дополнительных тестовых компаний...');
|
||||||
const updates = [
|
const testCompanies = [
|
||||||
{ inn: '7707083894', updates: { companySize: '51-250', partnerGeography: ['moscow', 'russia_all'] } },
|
{
|
||||||
{ inn: '7707083895', updates: { companySize: '500+', partnerGeography: ['moscow', 'russia_all'] } },
|
fullName: 'ООО "ТехноСтрой"',
|
||||||
{ inn: '7707083896', updates: { companySize: '11-50', partnerGeography: ['moscow', 'russia_all'] } },
|
shortName: 'ТехноСтрой',
|
||||||
{ inn: '7707083897', updates: { companySize: '51-250', partnerGeography: ['moscow', 'russia_all'] } },
|
inn: '7707083894',
|
||||||
{ inn: '7707083898', updates: { companySize: '251-500', partnerGeography: ['moscow', 'russia_all'] } },
|
ogrn: '1077707083894',
|
||||||
|
legalForm: 'ООО',
|
||||||
|
industry: 'Строительство',
|
||||||
|
companySize: '51-250',
|
||||||
|
website: 'https://technostroy.ru',
|
||||||
|
phone: '+7 (495) 111-22-33',
|
||||||
|
email: 'info@technostroy.ru',
|
||||||
|
description: 'Строительство промышленных объектов',
|
||||||
|
foundedYear: 2010,
|
||||||
|
employeeCount: '51-250',
|
||||||
|
revenue: 'До 2 млрд ₽',
|
||||||
|
rating: 4.2,
|
||||||
|
reviews: 15,
|
||||||
|
verified: true,
|
||||||
|
partnerGeography: ['moscow', 'russia_all'],
|
||||||
|
slogan: 'Строим будущее вместе',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fullName: 'АО "ФинансГрупп"',
|
||||||
|
shortName: 'ФинансГрупп',
|
||||||
|
inn: '7707083895',
|
||||||
|
ogrn: '1077707083895',
|
||||||
|
legalForm: 'АО',
|
||||||
|
industry: 'Финансы',
|
||||||
|
companySize: '500+',
|
||||||
|
website: 'https://finansgrupp.ru',
|
||||||
|
phone: '+7 (495) 222-33-44',
|
||||||
|
email: 'contact@finansgrupp.ru',
|
||||||
|
description: 'Финансовые услуги для бизнеса',
|
||||||
|
foundedYear: 2005,
|
||||||
|
employeeCount: '500+',
|
||||||
|
revenue: 'Более 2 млрд ₽',
|
||||||
|
rating: 4.8,
|
||||||
|
reviews: 50,
|
||||||
|
verified: true,
|
||||||
|
partnerGeography: ['moscow', 'russia_all', 'international'],
|
||||||
|
slogan: 'Финансовая стабильность',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fullName: 'ООО "ИТ Решения"',
|
||||||
|
shortName: 'ИТ Решения',
|
||||||
|
inn: '7707083896',
|
||||||
|
ogrn: '1077707083896',
|
||||||
|
legalForm: 'ООО',
|
||||||
|
industry: 'IT',
|
||||||
|
companySize: '11-50',
|
||||||
|
website: 'https://it-solutions.ru',
|
||||||
|
phone: '+7 (495) 333-44-55',
|
||||||
|
email: 'hello@it-solutions.ru',
|
||||||
|
description: 'Разработка программного обеспечения',
|
||||||
|
foundedYear: 2018,
|
||||||
|
employeeCount: '11-50',
|
||||||
|
revenue: 'До 60 млн ₽',
|
||||||
|
rating: 4.5,
|
||||||
|
reviews: 8,
|
||||||
|
verified: true,
|
||||||
|
partnerGeography: ['moscow', 'spb', 'russia_all'],
|
||||||
|
slogan: 'Инновации для вашего бизнеса',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fullName: 'ООО "ЛогистикПро"',
|
||||||
|
shortName: 'ЛогистикПро',
|
||||||
|
inn: '7707083897',
|
||||||
|
ogrn: '1077707083897',
|
||||||
|
legalForm: 'ООО',
|
||||||
|
industry: 'Логистика',
|
||||||
|
companySize: '51-250',
|
||||||
|
website: 'https://logistikpro.ru',
|
||||||
|
phone: '+7 (495) 444-55-66',
|
||||||
|
email: 'info@logistikpro.ru',
|
||||||
|
description: 'Транспортные и логистические услуги',
|
||||||
|
foundedYear: 2012,
|
||||||
|
employeeCount: '51-250',
|
||||||
|
revenue: 'До 120 млн ₽',
|
||||||
|
rating: 4.3,
|
||||||
|
reviews: 20,
|
||||||
|
verified: true,
|
||||||
|
partnerGeography: ['russia_all', 'cis'],
|
||||||
|
slogan: 'Доставим в срок',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fullName: 'ООО "ПродуктТрейд"',
|
||||||
|
shortName: 'ПродуктТрейд',
|
||||||
|
inn: '7707083898',
|
||||||
|
ogrn: '1077707083898',
|
||||||
|
legalForm: 'ООО',
|
||||||
|
industry: 'Оптовая торговля',
|
||||||
|
companySize: '251-500',
|
||||||
|
website: 'https://produkttrade.ru',
|
||||||
|
phone: '+7 (495) 555-66-77',
|
||||||
|
email: 'sales@produkttrade.ru',
|
||||||
|
description: 'Оптовая торговля продуктами питания',
|
||||||
|
foundedYear: 2008,
|
||||||
|
employeeCount: '251-500',
|
||||||
|
revenue: 'До 2 млрд ₽',
|
||||||
|
rating: 4.1,
|
||||||
|
reviews: 30,
|
||||||
|
verified: true,
|
||||||
|
partnerGeography: ['moscow', 'russia_all'],
|
||||||
|
slogan: 'Качество и надежность',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fullName: 'ООО "МедСервис"',
|
||||||
|
shortName: 'МедСервис',
|
||||||
|
inn: '7707083899',
|
||||||
|
ogrn: '1077707083899',
|
||||||
|
legalForm: 'ООО',
|
||||||
|
industry: 'Здравоохранение',
|
||||||
|
companySize: '11-50',
|
||||||
|
website: 'https://medservice.ru',
|
||||||
|
phone: '+7 (495) 666-77-88',
|
||||||
|
email: 'info@medservice.ru',
|
||||||
|
description: 'Медицинские услуги и оборудование',
|
||||||
|
foundedYear: 2016,
|
||||||
|
employeeCount: '11-50',
|
||||||
|
revenue: 'До 60 млн ₽',
|
||||||
|
rating: 4.6,
|
||||||
|
reviews: 12,
|
||||||
|
verified: true,
|
||||||
|
partnerGeography: ['moscow', 'central'],
|
||||||
|
slogan: 'Забота о вашем здоровье',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const item of updates) {
|
for (const companyData of testCompanies) {
|
||||||
await Company.updateOne({ inn: item.inn }, { $set: item.updates });
|
await Company.updateOne(
|
||||||
console.log(` ✓ Компания обновлена: INN ${item.inn}`);
|
{ inn: companyData.inn },
|
||||||
|
{ $set: companyData },
|
||||||
|
{ upsert: true }
|
||||||
|
);
|
||||||
|
console.log(` ✓ Компания создана/обновлена: ${companyData.shortName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создать тестовые запросы
|
||||||
|
console.log('\n📨 Создание тестовых запросов...');
|
||||||
|
await Request.deleteMany({});
|
||||||
|
|
||||||
|
const companies = await Company.find().limit(10).exec();
|
||||||
|
const testCompanyId = company._id.toString();
|
||||||
|
const requests = [];
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// Создаем отправленные запросы (от тестовой компании)
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const recipientCompany = companies[i % companies.length];
|
||||||
|
if (recipientCompany._id.toString() === testCompanyId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdAt = new Date(now.getTime() - i * 24 * 60 * 60 * 1000);
|
||||||
|
|
||||||
|
requests.push({
|
||||||
|
senderCompanyId: testCompanyId,
|
||||||
|
recipientCompanyId: recipientCompany._id.toString(),
|
||||||
|
subject: `Запрос на поставку ${i + 1}`,
|
||||||
|
text: `Здравствуйте! Интересует поставка товаров/услуг. Запрос ${i + 1}. Прошу предоставить коммерческое предложение.`,
|
||||||
|
files: [],
|
||||||
|
responseFiles: [],
|
||||||
|
status: i % 3 === 0 ? 'accepted' : i % 3 === 1 ? 'rejected' : 'pending',
|
||||||
|
response: i % 3 === 0
|
||||||
|
? 'Благодарим за запрос! Готовы предоставить услуги. Отправили КП на почту.'
|
||||||
|
: i % 3 === 1
|
||||||
|
? 'К сожалению, в данный момент не можем предоставить эти услуги.'
|
||||||
|
: null,
|
||||||
|
respondedAt: i % 3 !== 2 ? new Date(createdAt.getTime() + 2 * 60 * 60 * 1000) : null,
|
||||||
|
createdAt,
|
||||||
|
updatedAt: i % 3 !== 2 ? new Date(createdAt.getTime() + 2 * 60 * 60 * 1000) : createdAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создаем полученные запросы (к тестовой компании)
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
const senderCompany = companies[(i + 2) % companies.length];
|
||||||
|
if (senderCompany._id.toString() === testCompanyId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdAt = new Date(now.getTime() - (i + 1) * 12 * 60 * 60 * 1000);
|
||||||
|
|
||||||
|
requests.push({
|
||||||
|
senderCompanyId: senderCompany._id.toString(),
|
||||||
|
recipientCompanyId: testCompanyId,
|
||||||
|
subject: `Предложение о сотрудничестве ${i + 1}`,
|
||||||
|
text: `Добрый день! Предлагаем сотрудничество. Запрос ${i + 1}. Заинтересованы в вашей продукции.`,
|
||||||
|
files: [],
|
||||||
|
responseFiles: [],
|
||||||
|
status: 'pending',
|
||||||
|
response: null,
|
||||||
|
respondedAt: null,
|
||||||
|
createdAt,
|
||||||
|
updatedAt: createdAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requests.length > 0) {
|
||||||
|
await Request.insertMany(requests);
|
||||||
|
console.log(` ✓ Создано ${requests.length} тестовых запросов`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await mongoose.connection.close();
|
await mongoose.connection.close();
|
||||||
|
|||||||
Reference in New Issue
Block a user