Skip to content

Instantly share code, notes, and snippets.

@jeremyjs
Last active April 26, 2017 02:56
Show Gist options
  • Save jeremyjs/1d5509350d3cae69d0e83f1d6478eeb2 to your computer and use it in GitHub Desktop.
Save jeremyjs/1d5509350d3cae69d0e83f1d6478eeb2 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
/* eslint-disable global-require */
const Promise = require('bluebird');
const moment = require('moment');
const mongoose = require('mongoose');
// const ObjectId = require('mongodb').ObjectID;
const commandLineArgs = require('command-line-args');
const libPhone = require('../src/lib/libPhone');
const keyMap = require('../src/lib/keyMap');
const logErr = require('../lib/logErr');
const Make = Promise.promisifyAll(require('../src/services/make/make-model'));
const Nameplate = Promise.promisifyAll(require('../src/services/nameplate/nameplate-model'));
const Profile = Promise.promisifyAll(require('../src/services/profile/profile-model'));
const Vehicle = Promise.promisifyAll(require('../src/services/vehicle/vehicle-model'));
const Ticket = Promise.promisifyAll(require('../src/services/ticket/ticket-model'));
/* eslint-disable no-console */
const logFirstValues = (obj, label) => (
Object.keys(obj).forEach(key => {
if (!obj[key]) return;
if (Array.isArray(obj[key])) {
console.log(`${label || 'obj'}.${key}[0]:`, obj[key][0]);
} else {
console.log(`${label || 'obj'}.${key}:`, obj[key]);
}
})
);
/* eslint-enable no-console */
// const uniq = (iter) => Array.from(new Set(iter));
// const sortAsc = (ary) => ary.sort((a, b) => a - b);
const join = (arys) => arys.reduce((newAry, ary) => newAry.concat(ary), []);
const TYPES = {
TECHNICIAN: 'Technician',
SERVICE_ADVISOR: 'ServiceWriter',
OWNER: 'Manager',
};
const LOCAL_UTC_OFFSET = '08:00';
const commandLineOptions = [
{ name: 'src', type: String, defaultOption: true },
];
const commandLineArguments = commandLineArgs(commandLineOptions);
const inputPath = commandLineArguments.src;
const mitchellData = require(inputPath);
// console.log('mitchellData.nameplates:', mitchellData.nameplates);
const makesFromSql = (data) => data.makes.map(
({ MakeId, Name }) => ({ sqlMakeId: MakeId, title: Name })
);
const nameplatesFromSql = (data) => data.nameplates.map(
({ MakeId, ModelId, SubModelId, ModelName, SubModelName }) => ({
sqlMakeId: MakeId,
sqlModelId: ModelId,
sqlSubModelId: SubModelId,
title: `${ModelName}${SubModelName.length > 1 ? ` ${SubModelName}` : ''}`,
})
);
const phone = (sqlPhoneNum) => (
(sqlPhoneNum.replace(/\D/g, '').length === 10) ? libPhone.parse(sqlPhoneNum) : undefined
);
const motoristProfilesFromSql = (data) => (
data.motorists.map(
({ CustId, FirstName, LastName, EmailAddress, PhoneNum }) => ({
sqlCustId: CustId,
givenName: FirstName,
familyName: LastName,
email: EmailAddress,
phone: PhoneNum ? phone(PhoneNum) : undefined,
roles: ['motorist'],
})
)
);
const roles = (type) => keyMap(type, {
[TYPES.TECHNICIAN]: ['technician'],
[TYPES.SERVICE_ADVISOR]: ['serviceAdvisor'],
[TYPES.OWNER]: ['owner', 'serviceAdvisor'],
});
const employeeProfilesFromSql = (data) => (
data.employees.map(
({ EmployeeId, FirstName, LastName, EmployeeType, PhoneNum }) => ({
sqlEmployeeId: EmployeeId,
givenName: FirstName,
familyName: LastName,
phone: PhoneNum ? phone(PhoneNum) : undefined,
roles: roles(EmployeeType),
})
)
);
const dateStr = (isoStr) => moment(isoStr).format('YYYY/MM/DD');
const vehiclesFromSql = (data) => (
data.vehicles.map(
({
VehicleId,
CustId,
Year,
MakeId,
SubModelId,
Vin,
InspDate,
LastInDate,
License,
LicenseState,
EngineType,
}) => ({
sqlVehicleId: VehicleId,
sqlCustId: CustId,
year: String(Year),
sqlMakeId: MakeId,
sqlSubModelId: SubModelId,
vin: Vin,
inspDate: dateStr(InspDate),
lastInDate: dateStr(LastInDate),
license: License,
licenseState: LicenseState,
engineNotes: EngineType,
})
)
);
const time = (isoStr) => {
const m = moment(isoStr).utcOffset(LOCAL_UTC_OFFSET);
return {
hours: m.hours(),
minutes: m.minutes(),
};
};
const ticketsFromSql = (data) => (
data.tickets.map(
({
RepairOrderId,
CustId,
VehicleId,
StatusDescription,
ScheduleDate,
ScheduledHours,
PromiseDate,
TimeIn,
TimeOut,
Hat,
DatePosted,
Notes,
TechnicianId,
}) => ({
sqlRepairOrderId: RepairOrderId,
sqlCustId: CustId,
sqlVehicleId: VehicleId,
statusDescription: StatusDescription,
_eventStartDate: dateStr(ScheduleDate),
_eventStartTime: time(TimeIn),
servicesDuration: ScheduledHours,
promiseDate: dateStr(PromiseDate),
timeIn: new Date(TimeIn),
timeOut: new Date(TimeOut),
hat: Hat,
datePosted: new Date(DatePosted),
notes: Notes,
sqlTechnicianId: TechnicianId,
})
)
);
// TODO
// const shopSqlIds = (data) => {
// return data.subModels;
// };
const intermediateData = {
makes: makesFromSql(mitchellData),
nameplates: nameplatesFromSql(mitchellData),
dmvVehicles: mitchellData.dmvVehicles,
profiles: join([
motoristProfilesFromSql(mitchellData),
employeeProfilesFromSql(mitchellData),
]),
vehicles: vehiclesFromSql(mitchellData),
tickets: ticketsFromSql(mitchellData),
};
logFirstValues(intermediateData, 'intermediateData');
console.log(
intermediateData.vehicles.filter(
v1 => (
intermediateData.vehicles.filter(
v2 => v2.sqlVehicleId === v1.sqlVehicleId
).length > 1
)
)
);
// console.log(mitchellData.employees.filter(e => e.EmployeeType !== 'Technician'));
const logger = console.info;
const handleErr = (callback) => (
(err, res) => {
if (err) throw err;
callback(res);
}
);
mongoose.connect('mongodb://localhost:27017/SchedulerMVP');
mongoose.connection.on('open', (connectionError) => {
if (connectionError) throw connectionError;
const { makes, nameplates, profiles, vehicles, tickets } = intermediateData;
Promise.resolve(
mongoose.connection.db.dropDatabase()
)
.then(() => (
Promise.all(
makes.map(make => (
Make.create(make).then(_makeRes => logger(`Created make ${make.title}`))
))
)),
logErr
)
.catch(logErr)
.then(() => (
Promise.all(
nameplates.map(nameplate => {
const { sqlMakeId, sqlModelId, sqlSubModelId } = nameplate;
return Make.find({ sqlMakeId })
.then(makeRes => {
if (makeRes.length !== 1) {
const type = makeRes.length === 0 ? 'non-existent' : 'duplicate';
throw new Error(`${type} key for make.sqlMakeId: ${sqlMakeId}`);
}
const finalNameplate = Object.assign({}, nameplate, { makeId: makeRes[0]._id });
return Nameplate.create(finalNameplate);
})
.then(_nameplateRes => {
logger(`Created nameplate ${nameplate.title}`);
});
})
)),
logErr
)
.catch(logErr)
// TODO: dmvVehicles
.then(() => (
Promise.all(
profiles.map(profile => {
const normalizedProfile = (p => {
if (p.email !== '' && p.phone !== '') return p;
const newP = Object.assign({}, p);
if (p.email === '') delete newP.email;
if (p.phone === '') delete newP.phone;
return newP;
})(profile);
// TODO: set shopAccountId for employees
return Profile.create(normalizedProfile)
.then(_profileRes => {
logger(`Created profile ${
normalizedProfile.email
|| normalizedProfile.phone
|| `${normalizedProfile.givenName} ${normalizedProfile.familyName}`
}`);
});
})
)),
logErr
)
.catch(logErr)
.then(() => (
Promise.all(
vehicles.map(vehicle => {
const { sqlVehicleId, sqlCustId, sqlMakeId, sqlSubModelId } = vehicle;
const extraParams = {};
return Profile.find({ sqlCustId })
.then(motoristRes => {
if (motoristRes.length === 0) {
console.error(`
sqlId inconsistency for sqlVehicleId: ${sqlVehicleId}, profile.sqlCustId: ${sqlCustId}
`);
}
if (motoristRes.length > 1) {
console.error(`
sqlId collision for sqlVehicleId: ${sqlVehicleId}, profile.sqlCustId: ${sqlCustId}
`);
}
extraParams.motoristId = motoristRes[0]._id;
return Make.find({ sqlMakeId });
})
.then(makeRes => {
if (makeRes.length === 0) {
console.error(`
sqlId inconsistency for sqlVehicleId: ${sqlVehicleId}, sqlMakeId: ${sqlMakeId}
`);
}
if (makeRes.length > 1) {
console.error(`
sqlId collision for sqlVehicleId: ${sqlVehicleId}, sqlMakeId: ${sqlMakeId}
`);
}
extraParams.makeId = makeRes[0]._id;
return Nameplate.find({ sqlSubModelId });
})
.then(nameplateRes => {
if (nameplateRes.length === 0) {
console.error(`
sqlId inconsistency for sqlVehicleId: ${sqlVehicleId},
sqlSubModelId: ${sqlSubModelId}
`);
}
if (nameplateRes.length > 1) {
console.error(`
sqlId collision for sqlVehicleId: ${sqlVehicleId},
sqlSubModelId: ${sqlSubModelId}
`);
}
extraParams.nameplateId = nameplateRes[0]._id;
const finalVehicle = Object.assign({}, vehicle, extraParams);
return Vehicle.create(finalVehicle);
})
.then(_vehicleRes => {
logger(`Created vehicle ${vehicle.sqlVehicleId}`);
});
})
)),
logErr
)
.catch(logErr)
.then(() => (
Promise.all(
tickets.map(ticket => {
const { sqlRepairOrderId, sqlVehicleId, sqlTechnicianId } = ticket;
const extraParams = {};
return Vehicle.find({ sqlVehicleId })
.then(vehicleRes => {
if (vehicleRes.length === 0) {
console.error(`
sqlId inconsistency for sqlRepairOrderId: ${sqlRepairOrderId},
sqlVehicleId: ${sqlVehicleId}
`);
}
if (vehicleRes.length > 1) {
console.error(`
sqlId collision for sqlRepairOrderId: ${sqlRepairOrderId},
sqlVehicleId: ${sqlVehicleId}
`);
}
extraParams.vehicleId = vehicleRes[0]._id;
return Profile.find({ sqlTechnicianId });
})
.then(technicianRes => {
if (technicianRes.length === 0) {
console.error(`
sqlId inconsistency for sqlRepairOrderId: ${sqlRepairOrderId},
sqlTechnicianId: ${sqlTechnicianId}
`);
}
if (technicianRes.length > 1) {
console.error(`
sqlId collision for sqlRepairOrderId: ${sqlRepairOrderId},
sqlTechnicianId: ${sqlTechnicianId}
`);
}
extraParams.technicianId = technicianRes[0]._id;
const finalTicket = Object.assign({}, ticket, extraParams);
return Ticket.create(finalTicket);
})
.then(_ticketRes => {
logger(`Created ticket ${ticket.title}`);
});
})
)),
logErr
)
.catch(logErr);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment