forked from UKSOURCE/cms.hailearning.edu.vn
first commit
This commit is contained in:
178
scripts/2025_12_11_075500_booking.js
Normal file
178
scripts/2025_12_11_075500_booking.js
Normal file
@@ -0,0 +1,178 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Booking = require('../models/booking');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
require('dotenv').config();
|
||||
|
||||
|
||||
|
||||
const filePath = path.join(__dirname, '..', 'data', 'booking.json');
|
||||
let raw = '{}';
|
||||
try {
|
||||
raw = fs.readFileSync(filePath, 'utf8');
|
||||
} catch (e) {
|
||||
console.error('Could not read booking.json at', filePath);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(raw || '{}');
|
||||
} catch (e) {
|
||||
console.error('Invalid JSON in booking.json:', e.message);
|
||||
process.exit(3);
|
||||
}
|
||||
|
||||
// Remove _id fields recursively to avoid conflicts
|
||||
function stripIds(obj) {
|
||||
if (Array.isArray(obj)) return obj.map(i => stripIds(i));
|
||||
if (obj && typeof obj === 'object') {
|
||||
const out = {};
|
||||
for (const k in obj) {
|
||||
if (k !== '_id') out[k] = stripIds(obj[k]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
data = stripIds(data);
|
||||
|
||||
// Normalize vouchers to an array of objects so Mongoose casting won't fail
|
||||
function normalizeVouchers(doc) {
|
||||
if (!doc) return;
|
||||
// support root-level `vouchers` and `configuration.vouchers`
|
||||
let v = doc.vouchers || (doc.configuration && doc.configuration.vouchers);
|
||||
if (!v) return;
|
||||
|
||||
// Try to parse stringified arrays (may use single quotes or JS literal)
|
||||
if (typeof v === 'string') {
|
||||
try {
|
||||
v = JSON.parse(v);
|
||||
} catch (e1) {
|
||||
try {
|
||||
// try parsing JS object-literal style strings
|
||||
// eslint-disable-next-line no-new-func
|
||||
v = (new Function('return ' + v))();
|
||||
} catch (e2) {
|
||||
// fallback: attempt to extract codes by splitting on commas
|
||||
v = v.split && v.split(',').map(s => s.trim()).filter(Boolean).map(s => ({ validCodes: s, type: 'unknown', value: null }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize array items into objects
|
||||
if (Array.isArray(v)) {
|
||||
v = v.map(item => {
|
||||
if (typeof item === 'string') return { validCodes: item, type: 'unknown', value: null };
|
||||
if (item && typeof item === 'object') {
|
||||
return {
|
||||
validCodes: item.validCodes || item.code || '',
|
||||
type: item.type || '',
|
||||
value: typeof item.value === 'number' ? item.value : (item.amount && Number(item.amount)) || null,
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
// If Booking schema expects array of strings, convert objects -> string codes
|
||||
try {
|
||||
const Booking = require('../models/booking');
|
||||
const pathType = Booking.schema.path('vouchers') || Booking.schema.path('configuration.vouchers');
|
||||
if (pathType && pathType.instance === 'Array' && pathType.caster && pathType.caster.instance === 'String') {
|
||||
const mapped = (v || []).map(it => (typeof it === 'string' ? it : (it && typeof it === 'object' ? it.validCodes || JSON.stringify(it) : String(it))));
|
||||
if (doc.vouchers) doc.vouchers = mapped;
|
||||
else if (doc.configuration) doc.configuration.vouchers = mapped;
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore and keep object form
|
||||
}
|
||||
|
||||
if (doc.vouchers) doc.vouchers = v;
|
||||
else if (doc.configuration) doc.configuration.vouchers = v;
|
||||
}
|
||||
|
||||
normalizeVouchers(data);
|
||||
|
||||
// Also normalize discounts (some inputs have them stringified or as objects)
|
||||
function normalizeDiscounts(doc) {
|
||||
if (!doc) return;
|
||||
let d = doc.discounts || (doc.configuration && doc.configuration.discounts);
|
||||
if (!d) return;
|
||||
|
||||
if (typeof d === 'string') {
|
||||
try {
|
||||
d = JSON.parse(d);
|
||||
} catch (e1) {
|
||||
try {
|
||||
// eslint-disable-next-line no-new-func
|
||||
d = (new Function('return ' + d))();
|
||||
} catch (e2) {
|
||||
d = d.split && d.split('\n').map(s => s.trim()).filter(Boolean).map(s => ({ id: '', name: s }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(d)) {
|
||||
d = d.map(item => {
|
||||
if (typeof item === 'string') return { id: '', name: item };
|
||||
if (item && typeof item === 'object') return item;
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const Booking = require('../models/booking');
|
||||
const pathType = Booking.schema.path('discounts') || Booking.schema.path('configuration.discounts');
|
||||
if (pathType && pathType.instance === 'Array' && pathType.caster && pathType.caster.instance === 'String') {
|
||||
const mapped = (d || []).map(it => (typeof it === 'string' ? it : (it.id || it.name || JSON.stringify(it))));
|
||||
if (doc.discounts) doc.discounts = mapped;
|
||||
else if (doc.configuration) doc.configuration.discounts = mapped;
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (doc.discounts) doc.discounts = d;
|
||||
else if (doc.configuration) doc.configuration.discounts = d;
|
||||
}
|
||||
|
||||
normalizeDiscounts(data);
|
||||
|
||||
const dryRun = process.argv.includes('--dry-run') || process.argv.includes('-n');
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const dbUri = process.env.MONGODB_URI || process.env.MONGO_URL || 'mongodb://127.0.0.1:27017/cms';
|
||||
console.log('Using DB URI:', dbUri);
|
||||
|
||||
if (dryRun) {
|
||||
console.log('\nDRY RUN - preview of document to upsert:\n');
|
||||
console.log(JSON.stringify(data, null, 2));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
await mongoose.connect(dbUri, { useNewUrlParser: true, useUnifiedTopology: true });
|
||||
console.log('Connected to MongoDB');
|
||||
|
||||
const result = await Booking.findOneAndUpdate({}, data, {
|
||||
upsert: true,
|
||||
new: true,
|
||||
setDefaultsOnInsert: true,
|
||||
});
|
||||
|
||||
console.log('Upsert complete. Document id:', result._id.toString());
|
||||
console.log('Summary: programs=', (data.programs || []).length, 'camps=', (data.camps || []).length);
|
||||
|
||||
await mongoose.disconnect();
|
||||
process.exit(0);
|
||||
} catch (err) {
|
||||
console.error('Migration failed:', err && err.message ? err.message : err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
Reference in New Issue
Block a user