Skip to content

Instantly share code, notes, and snippets.

@efjacobson
Created June 23, 2016 20:07
Show Gist options
  • Save efjacobson/852f3714be678cfdf787bf29eea90ef1 to your computer and use it in GitHub Desktop.
Save efjacobson/852f3714be678cfdf787bf29eea90ef1 to your computer and use it in GitHub Desktop.
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
}
<div class="content-heading" id="topPage">
<!-- START Language list-->
<div class="pull-right">
<div class="btn-group">
<button type="button" data-toggle="dropdown" class="btn btn-default">English</button>
<ul role="menu" class="dropdown-menu dropdown-menu-right animated fadeInUpShort">
<li>
<a href="#" data-set-lang="en">English</a>
</li>
<li>
<a href="#" data-set-lang="es">Spanish</a>
</li>
</ul>
</div>
</div>
<!-- END Language list -->
<i class="icon-docs"></i> Import Data
</div>
<div class="container">
<div class="row">
<div class="panel panel-default col-lg-9">
<h2>Parse Providers</h2>
<h4>CSVs of the type from http://download.cms.gov/nppes/NPI_Files.html</h4>
<input type="file" id="providerParse" name="files[]" multiple />
<output id="list"></output>
<hr />
<h2>Parse Medical Schools and Hospital Affiliations</h2>
<h4>CSVs of the type from https://data.medicare.gov/Physician-Compare/National-Downloadable-File-Extended-View/3uxj-hea6</h4>
<input type="file" id="schoolHospitalParse" name="files[]" multiple />
<output id="list"></output>
<hr />
<h2>Parse Medical Schools</h2>
<input type="file" id="medicalSchoolParse" name="files[]" multiple />
<output id="list"></output>
<hr />
<h2>Parse Health Plans</h2>
<input type="file" id="healthPlansParse" name="files[]" multiple />
<output id="list"></output>
<hr />
<h2>Parse Carriers</h2>
<input type="file" id="carriersParse" name="files[]" multiple />
<output id="list"></output>
<hr />
<h2>Update Individual Providers:</h2>
<ol>
<li><a id="weeklyFileDownload">Download this file</a> (it is the current weekly update file from http://download.cms.gov/nppes/NPI_Files.html)</li>
<li>Unzip that File</li>
<li>Press the button below and select the large csv that was unzipped</li>
</ol>
<input type="file" id="individualProvidersUpdate" name="files[]" multiple />
<output id="list"></output>
<hr />
<h2>Hospitals Geo Code</h2>
<div>Press start to geo code 10 hospitals</div>
<button type="button" id="geocodeHospitals" class="btn btn-success col-sm-1">
Client
</button>
<div class="col-sm-11">
Return status : <span id="geoOutput"></span>
</div>
<div class="col-sm-12"><hr class="col-sm-4" /></div>
<button type="button" id="geocodeHospitalsServer" class="btn btn-info col-sm-1">Server</button>
<div class="col-sm-11">
Return status : <span id="geoOutputServer"></span>
</div>
<label class="col-sm-12 "></label>
<div id="parseResults"></div>
</div>
</div>
</div>
@section Scripts {
<script src="~/Scripts/healswift.hospitalsLocation.services.js"></script>
<script src="~/Scripts/papaparse.js"></script>
<script type="text/javascript">
healswift.page.startUp = function () {
$('#providerParse').on('change', healswift.page.handlers.onParseProvider);
$('#schoolHospitalParse').on('change', healswift.page.handlers.onParseSchoolHospital);
$('#medicalSchoolParse').on('change', healswift.page.handlers.onParseMedicalSchool);
$('#healthPlansParse').on('change', healswift.page.handlers.onParseHealthPlans);
$('#carriersParse').on('change', healswift.page.handlers.onParseCarriers);
$('#individualProvidersUpdate').on('change', healswift.page.handlers.onUpdateIndividualProviders);
$('#geocodeHospitals').on('click', healswift.page.handlers.onGeocodeHospitals);
$('#geocodeHospitalsServer').on('click', healswift.page.handlers.onGeocodeHospitalsServer);
_assignDownloadHref();
};
healswift.page.handlers = {};
healswift.page.handlers.onParseProvider = function (event) {
healswift.page.handlers.onParse(1, '/api/parse/provider');
};
healswift.page.handlers.onParseSchoolHospital = function (event) {
healswift.page.handlers.onParse(2, '/api/parse/schoolhospital');
};
healswift.page.handlers.onParseMedicalSchool = function (event) {
healswift.page.handlers.onParse(3, '/api/parse/medicalschools');
};
healswift.page.handlers.onParseHealthPlans = function (event) {
healswift.page.handlers.onParse(4, '/api/parse/healthplans');
};
healswift.page.handlers.onParseCarriers = function (event) {
healswift.page.handlers.onParse(5, '/api/parse/carriers');
};
healswift.page.handlers.onUpdateIndividualProviders = function (event) {
healswift.page.handlers.onParse(6, '/api/parse/individualproviderupdate');
};
function _assignDownloadHref() {
// gets current weekly NPI update file download URL
var Dates = new Date().getWeek();
var begin = Dates[0];
var end = Dates[1];
var weeklyFileDownloadUrl = 'http://download.cms.gov/nppes/NPPES_Data_Dissemination_' + _weekDateString(begin) + '_' + _weekDateString(end) + '_Weekly.zip';
$('#weeklyFileDownload').attr('href', weeklyFileDownloadUrl)
}
function _padWithZero(number) {
if (number < 10) {
number = '0' + number;
}
return number;
}
// from http://stackoverflow.com/questions/8381427/get-start-date-and-end-date-of-current-week-week-start-from-monday-and-end-with
Date.prototype.getWeek = function (start) {
//Calcing the starting point
start = start || -6;
var today = new Date(this.setHours(0, 0, 0, 0));
var day = today.getDay() - start;
var date = today.getDate() - day;
// Grabbing Start/End Dates
var StartDate = new Date(today.setDate(date));
var EnddBeginate = new Date(today.setDate(date + 6));
return [StartDate, EnddBeginate];
}
function _weekDateString(date) {
var dd = date.getDate();
dd = _padWithZero(dd);
var mm = date.getMonth() + 1; //January is 0
mm = _padWithZero(mm);
var yyyy = date.getFullYear().toString();
return mm.toString() + dd.toString() + yyyy.substring(2, 4);
}
healswift.page.handlers.onParse = function (type, apiUrl) {
healswift.page.parse.files = event.target.files; // List of files selected by button dialog
healswift.page.parse.parseConfig = healswift.page.parse.getConfig(type, apiUrl); // 1 for provider, 2 for schools/hospitals
healswift.page.parse.parse(healswift.page.parse.files[healswift.page.parse.numSent]); //numSent is index of array of files, not rows/records
};
healswift.page.parse = {
parseObjectArray: []
, files: null
, numSent: 0
, numSuccess: 0
, parse: function (file) {
Papa.parse(file, {
worker: true,
skipEmptyLines: true,
complete: healswift.page.parse.process
})
}
, process: function (parseResult) {
if (healswift.page.parse.parseConfig.individualProvider) {
healswift.page.parse.parseConfig.individualProvider(parseResult);
}
if (healswift.page.parse.parseConfig.schoolHospital) {
healswift.page.parse.parseConfig.schoolHospital(parseResult);
}
if (healswift.page.parse.parseConfig.medicalSchool) {
healswift.page.parse.parseConfig.medicalSchool(parseResult);
}
if (healswift.page.parse.parseConfig.healthPlans) {
healswift.page.parse.parseConfig.healthPlans(parseResult);
}
if (healswift.page.parse.parseConfig.carriers) {
healswift.page.parse.parseConfig.carriers(parseResult);
}
}
, inputParseProvider: function (parseObject, apiUrl) {
var url = apiUrl;
var settings = {
cache: false
, contentType: "application/json"
, data: JSON.stringify(parseObject)
, dataType: "json"
, success: healswift.page.parse.onParseSuccess
, error: healswift.page.parse.onParseError
, type: "POST"
};
$.ajax(url, settings);
}
, onParseSuccess: function (data, status, xhr) {
healswift.page.parse.numSuccess++;
console.log("numSuccess" + healswift.page.parse.numSuccess);
healswift.page.parse.parse(healswift.page.parse.files[healswift.page.parse.numSent]); //numSent is index of array of files, not rows/records
}
, onParseError: function (jqXHR, textStatus, errorThrown) {
console.error(jqXHR);
console.error(textStatus);
console.error(errorThrown);
}
, sendAndResetParseArray: function () {
healswift.page.parse.inputParseProvider(healswift.page.parse.parseObjectArray, healswift.page.parse.parseConfig.apiUrl);
healswift.page.parse.numSent++;
console.log("numSent" + healswift.page.parse.numSent);
healswift.page.parse.parseObjectArray = [];
}
, getConfig: function (num, apiUrl) {
if (num == 1 || num == 6) { //for file of type received from http://download.cms.gov/nppes/NPI_Files.html
healswift.page.parse.ParseObject = function () {
this.npi = null;
this.lastName = null;
this.middleName = null;
this.namePrefix = null;
this.nameSuffix = null;
this.credential = null;
this.practiceAddr1 = null;
this.practiceAddr2 = null;
this.practiceCity = null;
this.practiceState = null;
this.practicePostalCode = null;
this.practiceCountry = null;
this.practicePhoneNumber = null;
this.practiceFaxNumber = null;
this.enumerationDate = null;
this.npiDeactivationReason = null;
this.npiDeactivationDate = null;
this.npiReactivationReason = null;
this.gender = null;
this.primaryTaxonomy = {
state: null
, license: null
, code: null
};
this.auxiliaryTaxonomy = [
{ //0
state: null
, license: null
, code: null
}
, { //1
state: null
, license: null
, code: null
}
, { //2
state: null
, license: null
, code: null
}
, { //3
state: null
, license: null
, code: null
}
, { //4
state: null
, license: null
, code: null
}
, { //5
state: null
, license: null
, code: null
}
, { //6
state: null
, license: null
, code: null
}
, { //7
state: null
, license: null
, code: null
}
, { //8
state: null
, license: null
, code: null
}
, { //9
state: null
, license: null
, code: null
}
, { //10
state: null
, license: null
, code: null
}
, { //11
state: null
, license: null
, code: null
}
, { //12
state: null
, license: null
, code: null
}
, { //13
state: null
, license: null
, code: null
}
]
}
return {
apiUrl: apiUrl
, npi: 0
, entityType: 1
, lastName: 5
, firstName: 6
, middleName: 7
, namePrefix: 8
, nameSuffix: 9
, credential: 10
, practiceAddress1: 28
, practiceAddress2: 29
, practiceCity: 30
, practiceState: 31
, practicePostalCode: 32
, practiceCountry: 33
, practicePhoneNumber: 34
, practiceFaxNumber: 35
, enumerationDate: 36
, npiDeactivationReason: 38
, npiDeactivationDate: 39
, npiReactivationReason: 40
, gender: 41
, firstTaxonomy: 50
, lastTaxonomy: 106
, numberOfTaxonomyFields: 4
, taxonomyStateOffset: 1
, taxonomyLicenseOffset: 2
, taxonomyCodeOffset: 3
, individualProvider: function (parseResult) {
var resultArray = parseResult.data; //drill into array in result of papaParse
var parseObject; //individual parse object: one distinct record constructed with healswift.page.parse.ParseObject()
var isPrimarySet; //there is only one primary taxonomy per record, this flag tracks if set
var auxTaxIndex; //there may be up to 14 auxiliary taxonomies
var colCount; //columns correspond to header names
var currentRecord; //current record in resultArray
var primaryTaxonomy; //shorthand: parseObject.primaryTaxonomy
var currentTaxonomySwitch; //switch value indicates primary taxonomy
var currentAuxiliaryTaxonomy; //shorthand: parseObject.auxiliaryTaxonomy[auxTaxIndex]
for (row = 0; row < resultArray.length; row++) {
currentRecord = resultArray[row];
var thisConfig = this;
if (currentRecord[thisConfig.entityType] == 1) { //currently only getting individuals, any value other than 1 is not an individual
parseObject = new healswift.page.parse.ParseObject(); //must consruct a new blank parseObject or values from previous records will flood over
parseObject.npi = currentRecord[thisConfig.npi];
parseObject.lastName = currentRecord[thisConfig.lastName];
parseObject.firstName = currentRecord[thisConfig.firstName];
parseObject.middleName = currentRecord[thisConfig.middleName];
parseObject.namePrefix = currentRecord[thisConfig.namePrefix];
parseObject.nameSuffix = currentRecord[thisConfig.nameSuffix];
parseObject.credential = currentRecord[thisConfig.credential];
parseObject.practiceAddress1 = currentRecord[thisConfig.practiceAddress1];
parseObject.practiceAddress2 = currentRecord[thisConfig.practiceAddress2];
parseObject.practiceCity = currentRecord[thisConfig.practiceCity];
parseObject.practiceState = currentRecord[thisConfig.practiceState];
parseObject.practicePostalCode = currentRecord[thisConfig.practicePostalCode].substring(0, 5);
parseObject.practiceCountry = currentRecord[thisConfig.practiceCountry];
parseObject.practicePhoneNumber = currentRecord[thisConfig.practicePhoneNumber];
parseObject.practiceFaxNumber = currentRecord[thisConfig.practiceFaxNumber];
parseObject.enumerationDate = currentRecord[thisConfig.enumerationDate];
parseObject.npiDeactivationReason = currentRecord[thisConfig.npiDeactivationReason];
parseObject.npiDeactivationDate = currentRecord[thisConfig.npiDeactivationDate];
parseObject.npiReactivationReason = currentRecord[thisConfig.npiReactivationReason];
parseObject.gender = currentRecord[thisConfig.gender];
isPrimarySet = false;
auxTaxIndex = 0;
colCount = thisConfig.firstTaxonomy;
while (!isPrimarySet && colCount <= thisConfig.lastTaxonomy && colCount >= thisConfig.firstTaxonomy) {
currentTaxonomySwitch = currentRecord[colCount];
if (currentTaxonomySwitch == "N") {
currentAuxiliaryTaxonomy = parseObject.auxiliaryTaxonomy[auxTaxIndex];
currentAuxiliaryTaxonomy.state = currentRecord[colCount - thisConfig.taxonomyStateOffset];
currentAuxiliaryTaxonomy.license = currentRecord[colCount - thisConfig.taxonomyLicenseOffset];
currentAuxiliaryTaxonomy.code = currentRecord[colCount - thisConfig.taxonomyCodeOffset];
auxTaxIndex++;
} else if (currentTaxonomySwitch == "Y" || currentTaxonomySwitch == "X") {
primaryTaxonomy = parseObject.primaryTaxonomy;
primaryTaxonomy.state = currentRecord[colCount - thisConfig.taxonomyStateOffset];
primaryTaxonomy.license = currentRecord[colCount - thisConfig.taxonomyLicenseOffset];
primaryTaxonomy.code = currentRecord[colCount - thisConfig.taxonomyCodeOffset];
isPrimarySet = true;
}
colCount += thisConfig.numberOfTaxonomyFields;
};
for (var property in parseObject) { //if any value is an empty string, reset to null
if (parseObject.hasOwnProperty(property)) {
if (parseObject[property] == '') {
parseObject[property] = null;
}
}
}
if (parseObject.primaryTaxonomy.state && parseObject.primaryTaxonomy.license) { //above for loop does not check objects inside the object, this prevents empty license/state values
healswift.page.parse.parseObjectArray.push(parseObject);
}
};
};
healswift.page.parse.sendAndResetParseArray();
}
};
}
else if (num == 2) { //for file of type received from https://data.medicare.gov/Physician-Compare/National-Downloadable-File-Extended-View/3uxj-hea6
healswift.page.parse.ParseObject = function () {
this.npi = null;
this.medicalSchoolName = null;
this.graduationYear = null;
this.hospital0Number = null;
this.hospital0Name = null;
this.hospital1Number = null;
this.hospital1Name = null;
this.hospital2Number = null;
this.hospital2Name = null;
this.hospital3Number = null;
this.hospital3Name = null;
this.hospital4Number = null;
this.hospital4Name = null;
}
return {
apiUrl: apiUrl
, npi: 0
, medicalSchoolName: 9
, graduationYear: 10
, hospital0Number: 22
, hospital0Name: 23
, hospital1Number: 24
, hospital1Name: 25
, hospital2Number: 26
, hospital2Name: 27
, hospital3Number: 28
, hospital3Name: 29
, hospital4Number: 30
, hospital4Name: 31
, schoolHospital: function (parseResult) {
var resultArray = parseResult.data; //drill into array in result of papaParse
var parseObject; //individual parse object: one distinct record constructed with healswift.page.parse.ParseObject()
var currentRecord; //current record in resultArray
for (row = 0; row < resultArray.length; row++) {
currentRecord = resultArray[row];
var thisConfig = this;
parseObject = new healswift.page.parse.ParseObject(); //must consruct a new blank parseObject or values from previous records will flood over
parseObject.npi = currentRecord[thisConfig.npi];
parseObject.medicalSchoolName = currentRecord[thisConfig.medicalSchoolName];
parseObject.graduationYear = currentRecord[thisConfig.graduationYear];
parseObject.hospital0Number = currentRecord[thisConfig.hospital0Number];
parseObject.hospital0Name = currentRecord[thisConfig.hospital0Name];
parseObject.hospital1Number = currentRecord[thisConfig.hospital1Number];
parseObject.hospital1Name = currentRecord[thisConfig.hospital1Name];
parseObject.hospital2Number = currentRecord[thisConfig.hospital2Number];
parseObject.hospital2Name = currentRecord[thisConfig.hospital2Name];
parseObject.hospital3Number = currentRecord[thisConfig.hospital3Number];
parseObject.hospital3Name = currentRecord[thisConfig.hospital3Name];
parseObject.hospital4Number = currentRecord[thisConfig.hospital4Number];
parseObject.hospital4Name = currentRecord[thisConfig.hospital4Name];
for (var property in parseObject) { //if any value is an empty string, reset to null
if (parseObject.hasOwnProperty(property)) {
if (parseObject[property] == '') {
parseObject[property] = null;
}
}
}
if (parseObject.medicalSchoolName == 'OTHER') { //if medical school not adequately identified, reset to null along with graduation year
parseObject.medicalSchoolName = null;
parseObject.graduationYear = null;
}
if (parseObject.medicalSchoolName || parseObject.hospital0Number) { //only push up parseObject if a school or hospital has been gathered
healswift.page.parse.parseObjectArray.push(parseObject);
}
};
healswift.page.parse.sendAndResetParseArray();
}
}
}
else if (num == 3) {
healswift.page.parse.parseObject = function () {
this.stateName = null;
this.name = null;
this.city = null;
}
return {
apiUrl: apiUrl
, stateName: 0
, name: 1
, city: 2
, medicalSchool: function (parseResult) {
var resultArray = parseResult.data;
var parseObject;
var currentSchool;
for (var row = 1; row < resultArray.length; row++) {
currentSchool = resultArray[row];
var thisConfig = this;
parseObject = new healswift.page.parse.parseObject();
parseObject.stateName = currentSchool[thisConfig.stateName];
parseObject.name = currentSchool[thisConfig.name];
parseObject.city = currentSchool[thisConfig.city];
healswift.page.parse.parseObjectArray.push(parseObject);
};
healswift.page.parse.sendAndResetParseArray();
}
}
}
else if (num == 4) {
healswift.page.parse.parseObject = function () {
this.planName = null;
this.name = null;
this.planTypeId = null;
}
return {
apiUrl: apiUrl
, planName: 2
, carrierName: 3
, planTypeId: 4
, healthPlans: function (parseResult) {
var resultArray = parseResult.data;
var parseObject;
var currentPlan;
for (var row = 1; row < resultArray.length; row++) {
currentPlan = resultArray[row];
var thisConfig = this;
parseObject = new healswift.page.parse.parseObject();
parseObject.planName = currentPlan[thisConfig.planName];
parseObject.carrierName = currentPlan[thisConfig.carrierName];
parseObject.planTypeId = currentPlan[thisConfig.planTypeId];
healswift.page.parse.parseObjectArray.push(parseObject);
};
healswift.page.parse.sendAndResetParseArray();
}
}
}
else if (num == 5) {
healswift.page.parse.parseObject = function () {
this.carrierName = null;
}
return {
apiUrl: apiUrl
, carrierName: 3
, carriers: function (parseResult) {
var resultArray = parseResult.data;
var parseObject;
var currentCarrier;
for (var row = 1; row < resultArray.length; row++) {
currentCarrier = resultArray[row];
var thisConfig = this;
parseObject = new healswift.page.parse.parseObject();
parseObject.carrierName = currentCarrier[thisConfig.carrierName];
healswift.page.parse.parseObjectArray.push(parseObject);
};
healswift.page.parse.sendAndResetParseArray();
}
}
};
}
}
</script>
<script>
healswift.page.handlers.onGeocodeHospitalsServer = function () {
$.ajax({
url: 'https://healswift.dev/api/hospitalsLocation/geocode'
, cache: false
, success: onGeoSuccess
, error: onGeoError
, type: "PUT"
})
}
function onGeoError(jqXHR, textStatus, errorThrown) {
var responTxt = jQuery.parseJSON(jqXHR.responseText);
$('#geoOutputServer').text(responTxt.message);
}
function onGeoSuccess(data, textStatus, xhr) {
var responTxt = jQuery.parseJSON(xhr.responseText);
$('#geoOutputServer').text(responTxt);
}
</script>
<script>
healswift.page.googleApiKey = "@System.Configuration.ConfigurationManager.AppSettings["GoogleApiKey"]";
// healswift.page.hospitals = null;
healswift.page.geoInit = true;
healswift.page.handlers.onGeocodeHospitals = function () {
if (healswift.page.geoInit) {
$.ajax({
url: 'https://maps.googleapis.com/maps/api/js?key=' + healswift.page.googleApiKey
, dataType: "script"
, success: myHospitalLocationfunction
, error: err
});
}
else {
myHospitalLocationfunction();
}
}
function err() {
concole.log("ajax error")
}
function myHospitalLocationfunction() {
healswift.page.geoInit = false;
healswift.hospitalsLocation.services.getHospitalsForLocationUpdate(onSuccessGetHospitals, onErrorGetHospitals);
}
function onErrorGetHospitals(jqXHR, textStatus, errorThrown) {
console.error(jqXHR);
console.error(textStatus);
console.error(errorThrown);
}
function onSuccessGetHospitals(data, status, xhr) {
if (data.items == null || data.items < 0) {
$('#geoOutput').append("<p>Geocoding done.</p>");
}
else {
var hospitals = data.items;
var hosUpdate = {};
if (typeof (_geocoder) == 'undefined') {
var _geocoder = new google.maps.Geocoder();
}
for (var i = 0 ; i < hospitals.length; i++) {
geo(hospitals[i], _geocoder, hosUpdate);
}
}
}
function geo(hos, _geocoder, hosUpdate) {
$('#geoOutput p').remove();
var address = hos.addressLine1 + ", " + hos.city + ", " + hos.stateProvinceCode;
_geocoder.geocode({ 'address': address }, function (results, status) {
if (status == 'OK') {
hos.latitude = results[0].geometry.location.lat();
hos.longitude = results[0].geometry.location.lng();
healswift.hospitalsLocation.services.update(hos, hos.id, status, onUpdateSuccess, onUpdateError);
}
else if (status == 'ZERO_RESULTS') {
console.log(status);
healswift.hospitalsLocation.services.update(hos, hos.id, status, onUpdateSuccess, onUpdateError);
}
else if (status == 'OVER_QUERY_LIMIT') {
overLimit(status, hos.id);
}
else {
console.log('Error on geo location: ' + status);
$('#geoOutput').append("<p>" + status + "</p>");
}
})
}
function onUpdateError(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
$('#geoOutput').append("<p>" + textStatus + "</p>");
}
function onUpdateSuccess(data, status, xhr) {
console.log(status);
$('#geoOutput').append("<p>" + status + "</p>");
}
function overLimit(status, id) {
console.log(status);
$('#geoOutput').append("<p>" + status + "</p>");
}
</script>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment