// ============================================================================= // populate_vi_remaining.js // // Purpose : Seed Vietnamese (*Vi) fields for collections not covered by // populate_vi.js (which handled: locations, activity, travelguides). // Touches : hotel, room, promotions, advertisement, visa_articles // Run with : mongosh --quiet --eval "load('scripts/populate_vi_remaining.js')" // or inside a mongosh shell: load('scripts/populate_vi_remaining.js') // // Idempotent: Each section skips documents that already have a non-null Vi field. // Ja / Ko : Left empty intentionally — the frontend useLocalizedField hook // falls back to English, which is acceptable at this stage. // ============================================================================= // --------------------------------------------------------------------------- // Shared lookup tables (copied from populate_vi.js — do not import) // --------------------------------------------------------------------------- const cityMap = { 'Hanoi': 'Hà Nội', 'Ho Chi Minh City': 'TP. Hồ Chí Minh', 'Da Nang': 'Đà Nẵng', 'Hai Phong': 'Hải Phòng', 'Can Tho': 'Cần Thơ', 'Hoi An': 'Hội An', 'Nha Trang': 'Nha Trang', 'Phu Quoc': 'Phú Quốc', 'Hue': 'Huế', 'Ha Long': 'Hạ Long', 'Da Lat': 'Đà Lạt', 'Vung Tau': 'Vũng Tàu', 'Quy Nhon': 'Quy Nhơn', 'Phan Thiet': 'Phan Thiết', 'Buon Ma Thuot': 'Buôn Ma Thuột', 'Vinh': 'Vinh', 'Thanh Hoa': 'Thanh Hóa', 'Hai Duong': 'Hải Dương', 'Nam Dinh': 'Nam Định', 'Thai Nguyen': 'Thái Nguyên', 'Viet Tri': 'Việt Trì', 'Ha Giang': 'Hà Giang', 'Cao Bang': 'Cao Bằng', 'Lang Son': 'Lạng Sơn', 'Lao Cai': 'Lào Cai', 'Dien Bien Phu': 'Điện Biên Phủ', 'Son La': 'Sơn La', 'Hoa Binh': 'Hòa Bình', 'Ninh Binh': 'Ninh Bình', 'Dong Hoi': 'Đồng Hới', 'Pleiku': 'Pleiku', 'Tuy Hoa': 'Tuy Hòa', 'Ca Mau': 'Cà Mau', 'Soc Trang': 'Sóc Trăng', // Common aliases that may appear in hotel.city 'HCMC': 'TP. Hồ Chí Minh', 'Saigon': 'TP. Hồ Chí Minh', 'Ho Chi Minh': 'TP. Hồ Chí Minh', 'HCM': 'TP. Hồ Chí Minh' }; // --------------------------------------------------------------------------- // Hotel-specific lookup tables // --------------------------------------------------------------------------- // Confirmed from HotelType.java: HOTEL, VILLA, APARTMENT, RESORT, HOSTEL, MOTEL, GUEST_HOUSE const hotelTypeViMap = { 'HOTEL': 'Khách sạn', 'VILLA': 'Biệt thự', 'APARTMENT': 'Căn hộ', 'RESORT': 'Resort', 'HOSTEL': 'Nhà nghỉ', 'MOTEL': 'Nhà nghỉ ven đường', 'GUEST_HOUSE': 'Nhà khách' }; const amenityViMap = { 'Free WiFi': 'WiFi miễn phí', 'WiFi': 'WiFi', 'Swimming Pool': 'Bể bơi', 'Pool': 'Bể bơi', 'Breakfast': 'Bữa sáng', 'Free Breakfast': 'Bữa sáng miễn phí', 'Parking': 'Bãi đỗ xe', 'Free Parking': 'Bãi đỗ xe miễn phí', 'Gym': 'Phòng tập gym', 'Fitness Center': 'Trung tâm thể dục', 'Restaurant': 'Nhà hàng', 'Bar': 'Quầy bar', 'Spa': 'Spa', 'Air Conditioning': 'Điều hòa không khí', 'Airport Shuttle': 'Đưa đón sân bay', 'Room Service': 'Dịch vụ phòng', '24-Hour Front Desk': 'Lễ tân 24/7', 'Concierge': 'Dịch vụ hỗ trợ khách', 'Laundry': 'Dịch vụ giặt ủi', 'Laundry Service': 'Dịch vụ giặt ủi', 'Meeting Room': 'Phòng họp', 'Business Center': 'Trung tâm kinh doanh', 'Kids Club': 'Khu vui chơi trẻ em', 'Beach Access': 'Lối ra bãi biển', 'Private Beach': 'Bãi biển riêng', 'Hot Tub': 'Bồn tắm nước nóng', 'Jacuzzi': 'Bồn Jacuzzi', 'Sauna': 'Phòng xông hơi', 'Minibar': 'Minibar', 'Safe': 'Két an toàn', 'Balcony': 'Ban công', 'Sea View': 'View biển', 'Mountain View': 'View núi', 'City View': 'View thành phố', 'Non-smoking': 'Không hút thuốc', 'Pet Friendly': 'Thân thiện thú cưng', 'Elevator': 'Thang máy', 'Electric Kettle': 'Ấm đun nước điện', 'TV': 'TV', 'Cable TV': 'Truyền hình cáp' }; // Helper: translate a list of amenity strings, return first N as Vietnamese function translateAmenities(amenities, count) { if (!amenities || amenities.length === 0) return []; const result = []; for (let i = 0; i < Math.min(count, amenities.length); i++) { result.push(amenityViMap[amenities[i]] || amenities[i]); } return result; } // Helper: build a nameVi for a hotel function buildHotelNameVi(hotel) { const typeLabel = hotelTypeViMap[hotel.hotelType] || 'Khách sạn'; const cityVi = cityMap[hotel.city] || hotel.city || ''; // If the English name already contains a proper-noun identifier we keep it // and simply prepend the Vietnamese type label + city. // Pattern: " , " const name = hotel.name || ''; // Strip common English hotel-type words from start of name for cleaner result const cleaned = name .replace(/^(Hotel|Resort|Villa|Hostel|Apartment|Guesthouse|Guest House|Motel)\s+/i, '') .trim(); if (cleaned) { return typeLabel + ' ' + cleaned + (cityVi ? ', ' + cityVi : ''); } return typeLabel + (cityVi ? ' ' + cityVi : ''); } // Helper: build addressVi — swap English city name with Vietnamese equivalent function buildAddressVi(hotel) { if (!hotel.address) return ''; let addr = hotel.address; // Replace city names in the address string for (const [en, vi] of Object.entries(cityMap)) { addr = addr.replace(new RegExp(en, 'gi'), vi); } // Common street-type translations addr = addr.replace(/\bStreet\b/gi, 'Đường'); addr = addr.replace(/\bAvenue\b/gi, 'Đại lộ'); addr = addr.replace(/\bDistrict\b/gi, 'Quận'); addr = addr.replace(/\bWard\b/gi, 'Phường'); return addr; } // Helper: build shortDescriptionVi function buildShortDescVi(hotel) { const typeLabel = hotelTypeViMap[hotel.hotelType] || 'Khách sạn'; const stars = hotel.starRating || ''; const cityVi = cityMap[hotel.city] || hotel.city || ''; const ams = translateAmenities(hotel.amenities, 3); const amStr = ams.length > 0 ? ' với ' + ams.join(', ') + '.' : '.'; const starPart = stars ? stars + ' sao ' : ''; return typeLabel + ' ' + starPart + 'tại ' + cityVi + amStr; } // Helper: build descriptionVi (2-3 sentences) function buildDescVi(hotel) { const typeLabel = hotelTypeViMap[hotel.hotelType] || 'Khách sạn'; const stars = hotel.starRating || ''; const cityVi = cityMap[hotel.city] || hotel.city || ''; const name = hotel.name || typeLabel; const ams = translateAmenities(hotel.amenities, 4); const starPart = stars ? stars + ' sao ' : ''; let sentence1 = 'Chào mừng đến với ' + name + ', ' + typeLabel.toLowerCase() + ' ' + starPart + 'tại ' + cityVi + '.'; let sentence2 = ''; if (ams.length > 0) { sentence2 = 'Cơ sở lưu trú sở hữu đầy đủ tiện nghi bao gồm ' + ams.join(', ') + '.'; } else { sentence2 = 'Cơ sở lưu trú cung cấp dịch vụ chất lượng cao cho du khách.'; } let sentence3 = 'Phù hợp cho cả kỳ nghỉ gia đình lẫn chuyến công tác tại ' + cityVi + '.'; return sentence1 + ' ' + sentence2 + ' ' + sentence3; } // ============================================================================= // SECTION 1 — hotel // ============================================================================= print(''); print('=== [1/5] Updating hotel collection ==='); let hotelUpdated = 0; db.hotel.find({}).forEach(function(hotel) { // Only set fields that are currently null/missing (idempotent guard) const setFields = {}; if (!hotel.nameVi) { setFields.nameVi = buildHotelNameVi(hotel); } if (!hotel.addressVi) { setFields.addressVi = buildAddressVi(hotel); } if (!hotel.shortDescriptionVi) { setFields.shortDescriptionVi = buildShortDescVi(hotel); } if (!hotel.descriptionVi) { setFields.descriptionVi = buildDescVi(hotel); } if (Object.keys(setFields).length > 0) { db.hotel.updateOne({ _id: hotel._id }, { $set: setFields }); hotelUpdated++; } }); print(' Updated ' + hotelUpdated + ' hotels with nameVi / addressVi / shortDescriptionVi / descriptionVi'); // ============================================================================= // SECTION 2 — room // ============================================================================= print(''); print('=== [2/5] Updating room collection ==='); // Confirmed from RoomType.java: SINGLE, DOUBLE, SUITE, FAMILY const roomTypeViMap = { 'SINGLE': 'Phòng Đơn', 'DOUBLE': 'Phòng Đôi', 'SUITE': 'Phòng Suite', 'FAMILY': 'Phòng Gia đình' }; let roomUpdated = 0; db.room.find({}).forEach(function(room) { const setFields = {}; if (!room.nameVi) { const typeVi = roomTypeViMap[room.type] || room.type || 'Phòng'; setFields.nameVi = typeVi; } if (!room.descriptionVi) { const typeVi = roomTypeViMap[room.type] || room.type || 'Phòng'; const areaPart = room.size ? ' rộng ' + room.size + 'm²' : ''; const bedPart = room.bedType ? ', trang bị ' + room.bedType : ''; const guestPart = room.maxOccupancy ? ', sức chứa tối đa ' + room.maxOccupancy + ' khách' : ''; setFields.descriptionVi = typeVi + areaPart + bedPart + guestPart + '.'; } if (Object.keys(setFields).length > 0) { db.room.updateOne({ _id: room._id }, { $set: setFields }); roomUpdated++; } }); print(' Updated ' + roomUpdated + ' rooms with nameVi / descriptionVi'); // ============================================================================= // SECTION 3 — promotions // ============================================================================= print(''); print('=== [3/5] Updating promotions collection ==='); // Confirmed from PromotionCategory.java: HOTEL, FLIGHT, CAR, ACTIVITY, ALL const promoCategoryViMap = { 'HOTEL': 'khách sạn', 'FLIGHT': 'chuyến bay', 'CAR': 'thuê xe', 'ACTIVITY': 'hoạt động', 'ALL': 'tất cả dịch vụ' }; // Promotion type field uses plain strings: "PERCENTAGE" or "FIXED_AMOUNT" function buildPromoTitleVi(promo) { const categoryVi = promo.category ? (promoCategoryViMap[promo.category] || promo.category.toLowerCase()) : 'dịch vụ'; if (promo.type === 'PERCENTAGE' && promo.value) { return 'Giảm ' + promo.value + '% ' + categoryVi; } if (promo.type === 'FIXED_AMOUNT' && promo.value) { const formattedVal = Number(promo.value).toLocaleString('vi-VN') + 'đ'; return 'Giảm ' + formattedVal + ' cho ' + categoryVi; } // Fallback: use the code or a generic title if (promo.code) { return 'Ưu đãi đặc biệt – mã ' + promo.code; } return 'Ưu đãi đặc biệt cho ' + categoryVi; } function buildPromoDescVi(promo) { const categoryVi = promo.category ? (promoCategoryViMap[promo.category] || promo.category.toLowerCase()) : 'dịch vụ'; let parts = []; if (promo.type === 'PERCENTAGE' && promo.value) { parts.push('Giảm ngay ' + promo.value + '% cho ' + categoryVi + '.'); } else if (promo.type === 'FIXED_AMOUNT' && promo.value) { const formattedVal = Number(promo.value).toLocaleString('vi-VN') + 'đ'; parts.push('Tiết kiệm ' + formattedVal + ' khi đặt ' + categoryVi + '.'); } else { parts.push('Ưu đãi hấp dẫn cho ' + categoryVi + '.'); } if (promo.minSpend) { const formattedMin = Number(promo.minSpend).toLocaleString('vi-VN') + 'đ'; parts.push('Áp dụng cho đơn hàng tối thiểu ' + formattedMin + '.'); } if (promo.endDate) { parts.push('Ưu đãi có hiệu lực đến ' + promo.endDate + '.'); } return parts.join(' '); } let promoUpdated = 0; db.promotions.find({}).forEach(function(promo) { const setFields = {}; if (!promo.titleVi) { setFields.titleVi = buildPromoTitleVi(promo); } if (!promo.descriptionVi) { setFields.descriptionVi = buildPromoDescVi(promo); } if (Object.keys(setFields).length > 0) { db.promotions.updateOne({ _id: promo._id }, { $set: setFields }); promoUpdated++; } }); print(' Updated ' + promoUpdated + ' promotions with titleVi / descriptionVi'); // ============================================================================= // SECTION 4 — advertisement // ============================================================================= print(''); print('=== [4/5] Updating advertisement collection ==='); // Keyword-swap map for ad titles (longest-match wins via ordered checks) const adTitleKeywordMap = [ // Common marketing phrases ['Summer Sale', 'Khuyến mãi mùa hè'], ['Flash Sale', 'Flash Sale – Giảm giá sốc'], ['New Destinations', 'Điểm đến mới'], ['New Arrival', 'Sản phẩm mới'], ['Limited Offer', 'Ưu đãi có hạn'], ['Special Offer', 'Ưu đãi đặc biệt'], ['Exclusive Deal', 'Ưu đãi độc quyền'], ['Weekend Deal', 'Ưu đãi cuối tuần'], ['Holiday Sale', 'Khuyến mãi kỳ nghỉ'], ['Early Bird', 'Đặt sớm – Giá ưu đãi'], ['Last Minute', 'Ưu đãi phút chót'], ['Best Price', 'Giá tốt nhất'], ['Top Hotels', 'Khách sạn nổi bật'], ['Featured Hotels', 'Khách sạn nổi bật'], ['Luxury Hotels', 'Khách sạn cao cấp'], ['Budget Hotels', 'Khách sạn giá rẻ'], ['Beach Resorts', 'Resort biển'], ['City Break', 'Du lịch thành phố'], ['Family Travel', 'Du lịch gia đình'], ['Honeymoon', 'Tuần trăng mật'], ['Adventure Travel', 'Du lịch phiêu lưu'], ['Cultural Tour', 'Tour văn hóa'], ['Food Tour', 'Tour ẩm thực'], ['Visa Services', 'Dịch vụ visa'], ['Car Rental', 'Thuê xe'], ['Flight Deals', 'Ưu đãi vé máy bay'], ['Hotel Deals', 'Ưu đãi khách sạn'], ['Travel Insurance', 'Bảo hiểm du lịch'], ['Tour Packages', 'Gói tour'], ['Group Tours', 'Tour nhóm'] ]; // Try to match any keyword; return mapped value or original function translateAdText(text) { if (!text) return ''; for (let i = 0; i < adTitleKeywordMap.length; i++) { const pair = adTitleKeywordMap[i]; if (text.toLowerCase().indexOf(pair[0].toLowerCase()) !== -1) { return text.replace(new RegExp(pair[0], 'gi'), pair[1]); } } // No mapping found — return original (frontend at least shows something) return text; } let adUpdated = 0; db.advertisement.find({}).forEach(function(ad) { const setFields = {}; if (!ad.titleVi) { setFields.titleVi = translateAdText(ad.title) || (ad.title || ''); } if (!ad.descriptionVi) { // Never leave null — fall back to English copy if no translation found const translated = translateAdText(ad.description); setFields.descriptionVi = translated || (ad.description || ''); } if (Object.keys(setFields).length > 0) { db.advertisement.updateOne({ _id: ad._id }, { $set: setFields }); adUpdated++; } }); print(' Updated ' + adUpdated + ' advertisements with titleVi / descriptionVi'); // ============================================================================= // SECTION 5 — visa_articles // ============================================================================= print(''); print('=== [5/5] Updating visa_articles collection ==='); // Country name translations for common visa article destinations const countryViMap = { 'United States': 'Mỹ', 'USA': 'Mỹ', 'US': 'Mỹ', 'United Kingdom': 'Anh', 'UK': 'Anh', 'Japan': 'Nhật Bản', 'South Korea': 'Hàn Quốc', 'Korea': 'Hàn Quốc', 'China': 'Trung Quốc', 'Australia': 'Úc', 'Canada': 'Canada', 'Germany': 'Đức', 'France': 'Pháp', 'Singapore': 'Singapore', 'Thailand': 'Thái Lan', 'Malaysia': 'Malaysia', 'Indonesia': 'Indonesia', 'Philippines': 'Philippines', 'Taiwan': 'Đài Loan', 'Hong Kong': 'Hồng Kông', 'India': 'Ấn Độ', 'Russia': 'Nga', 'Italy': 'Ý', 'Spain': 'Tây Ban Nha', 'Portugal': 'Bồ Đào Nha', 'Netherlands': 'Hà Lan', 'Switzerland': 'Thụy Sĩ', 'New Zealand': 'New Zealand', 'Vietnam': 'Việt Nam', 'Cambodia': 'Campuchia', 'Laos': 'Lào', 'Myanmar': 'Myanmar', 'Nepal': 'Nepal', 'Sri Lanka': 'Sri Lanka', 'Maldives': 'Maldives', 'Dubai': 'Dubai', 'UAE': 'UAE', 'Turkey': 'Thổ Nhĩ Kỳ', 'Greece': 'Hy Lạp', 'Czech Republic': 'Cộng hòa Séc', 'Austria': 'Áo', 'Belgium': 'Bỉ', 'Sweden': 'Thụy Điển', 'Norway': 'Na Uy', 'Denmark': 'Đan Mạch', 'Finland': 'Phần Lan', 'Poland': 'Ba Lan', 'Mexico': 'Mexico', 'Brazil': 'Brazil', 'Argentina': 'Argentina', 'South Africa': 'Nam Phi', 'Egypt': 'Ai Cập', 'Morocco': 'Maroc', 'Kenya': 'Kenya' }; // Citizen country translations (used in title patterns like "for US Citizens") const citizenViMap = { 'US Citizens': 'công dân Mỹ', 'American Citizens': 'công dân Mỹ', 'UK Citizens': 'công dân Anh', 'British Citizens': 'công dân Anh', 'Australian Citizens': 'công dân Úc', 'Canadian Citizens': 'công dân Canada', 'Indian Citizens': 'công dân Ấn Độ', 'Chinese Citizens': 'công dân Trung Quốc', 'Japanese Citizens': 'công dân Nhật Bản', 'Korean Citizens': 'công dân Hàn Quốc', 'Vietnamese Citizens': 'công dân Việt Nam', 'European Citizens': 'công dân châu Âu', 'Citizens': 'công dân' }; // Category translations const visaCategoryViMap = { 'tourist': 'du lịch', 'business': 'công tác', 'student': 'du học', 'work': 'lao động', 'transit': 'quá cảnh', 'e-visa': 'visa điện tử', 'evisa': 'visa điện tử', 'on arrival': 'visa khi đến nơi', 'visa-free': 'miễn visa' }; function buildVisaTitleVi(article) { if (!article.title) return ''; let title = article.title; // Replace citizen phrases first (longer matches before shorter) for (const [en, vi] of Object.entries(citizenViMap)) { title = title.replace(new RegExp(en, 'gi'), vi); } // Replace country names for (const [en, vi] of Object.entries(countryViMap)) { title = title.replace(new RegExp('\\b' + en + '\\b', 'gi'), vi); } // Replace category keywords for (const [en, vi] of Object.entries(visaCategoryViMap)) { title = title.replace(new RegExp('\\b' + en + '\\b', 'gi'), vi); } // Common structural words title = title.replace(/\bVisa Guide\b/gi, 'Hướng dẫn Visa'); title = title.replace(/\bVisa Requirements\b/gi, 'Yêu cầu Visa'); title = title.replace(/\bVisa Application\b/gi, 'Đăng ký Visa'); title = title.replace(/\bVisa\b/gi, 'Visa'); title = title.replace(/\bHow to Apply\b/gi, 'Cách đăng ký'); title = title.replace(/\bComplete Guide\b/gi, 'Hướng dẫn toàn diện'); title = title.replace(/\bEverything You Need to Know\b/gi, 'Tất cả những gì bạn cần biết'); title = title.replace(/\bfor\b/gi, 'cho'); title = title.replace(/\bto\b/gi, 'đến'); return title; } function buildVisaExcerptVi(article) { // If we can derive something useful from country + category, do so. // Otherwise copy the English excerpt (never leave null). if (!article.excerpt && !article.country) return ''; const countryVi = countryViMap[article.country] || article.country || ''; const categoryVi = article.category ? (visaCategoryViMap[article.category.toLowerCase()] || article.category) : ''; if (countryVi) { let parts = ['Hướng dẫn đầy đủ về thủ tục xin visa ' + (categoryVi ? categoryVi + ' ' : '') + 'đến ' + countryVi + '.']; if (article.processingTime) { parts.push('Thời gian xử lý: ' + article.processingTime + '.'); } if (article.fee) { parts.push('Lệ phí: ' + article.fee + ' USD.'); } return parts.join(' '); } // Fallback: return English excerpt so the field is never null return article.excerpt || ''; } let visaUpdated = 0; db.visa_articles.find({}).forEach(function(article) { const setFields = {}; if (!article.titleVi) { const titleVi = buildVisaTitleVi(article); // If nothing changed from the original (no keywords matched), keep English title setFields.titleVi = titleVi || article.title || ''; } if (!article.excerptVi) { // Never leave null — buildVisaExcerptVi already falls back to English copy setFields.excerptVi = buildVisaExcerptVi(article); if (!setFields.excerptVi) { setFields.excerptVi = article.excerpt || ''; } } if (Object.keys(setFields).length > 0) { db.visa_articles.updateOne({ _id: article._id }, { $set: setFields }); visaUpdated++; } }); print(' Updated ' + visaUpdated + ' visa articles with titleVi / excerptVi'); // ============================================================================= // VERIFICATION — sample one document from each collection // ============================================================================= print(''); print('=== Verification: sample documents ==='); // hotel const sampleHotel = db.hotel.findOne({}, { name: 1, nameVi: 1, shortDescriptionVi: 1 }); if (sampleHotel) { print(''); print('Sample Hotel:'); print(' name: ' + sampleHotel.name); print(' nameVi: ' + sampleHotel.nameVi); print(' shortDescriptionVi: ' + sampleHotel.shortDescriptionVi); } else { print(' (no hotel documents found)'); } // room const sampleRoom = db.room.findOne({}, { name: 1, nameVi: 1, descriptionVi: 1 }); if (sampleRoom) { print(''); print('Sample Room:'); print(' name: ' + sampleRoom.name); print(' nameVi: ' + sampleRoom.nameVi); print(' descriptionVi: ' + sampleRoom.descriptionVi); } else { print(' (no room documents found)'); } // promotions const samplePromo = db.promotions.findOne({}, { title: 1, titleVi: 1, descriptionVi: 1 }); if (samplePromo) { print(''); print('Sample Promotion:'); print(' title: ' + samplePromo.title); print(' titleVi: ' + samplePromo.titleVi); print(' descriptionVi: ' + samplePromo.descriptionVi); } else { print(' (no promotion documents found)'); } // advertisement const sampleAd = db.advertisement.findOne({}, { title: 1, titleVi: 1, descriptionVi: 1 }); if (sampleAd) { print(''); print('Sample Advertisement:'); print(' title: ' + sampleAd.title); print(' titleVi: ' + sampleAd.titleVi); print(' descriptionVi: ' + sampleAd.descriptionVi); } else { print(' (no advertisement documents found)'); } // visa_articles const sampleVisa = db.visa_articles.findOne({}, { title: 1, titleVi: 1, excerptVi: 1 }); if (sampleVisa) { print(''); print('Sample VisaArticle:'); print(' title: ' + sampleVisa.title); print(' titleVi: ' + sampleVisa.titleVi); print(' excerptVi: ' + sampleVisa.excerptVi); } else { print(' (no visa_articles documents found)'); } print(''); print('=== populate_vi_remaining.js complete ==='); print(' hotel: ' + hotelUpdated + ' updated'); print(' room: ' + roomUpdated + ' updated'); print(' promotions: ' + promoUpdated + ' updated'); print(' advertisement: ' + adUpdated + ' updated'); print(' visa_articles: ' + visaUpdated + ' updated');