Skip to content

Instantly share code, notes, and snippets.

@kuzmik
Created August 8, 2017 03:30
Show Gist options
  • Save kuzmik/351ebc1416cca2aad6c89f4124be8ffc to your computer and use it in GitHub Desktop.
Save kuzmik/351ebc1416cca2aad6c89f4124be8ffc to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;
using Cotdom.Cobalt;
using Cotdom.Cobalt.Components;
using CsvHelper;
using CsvHelper.Configuration;
using System.Collections;
public partial class Members_Imports_Import : System.Web.UI.Page
{
/// <summary>
/// Fields that are either in the main surgical log table or composite fields
/// </summary>
private string[] staticFieldNames = new string[] {
"dob", "sex", "ssn", "surgerydate",
"fullnameLF", "fullnameFML", "fullnameFL", "lastname", "middlename", "firstname",
"surgeonfullnameLF", "surgeonfullnameFML", "surgeonfullnameFL", "surgeonlastname", "surgeonmiddlename", "surgeonfirstname", "surgeonsuffix"
};
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
Trace.IsEnabled = true;
this.ddlFormats.DataBound += delegate(object ddl, EventArgs args)
{
DropDownList d = ddl as DropDownList;
d.Items.Insert(0, new ListItem("", ""));
d.SelectedIndex = d.Items.Count - 1;
};
}
/// <summary>
/// Submits the form, saving the uploaded file to a temp directory (FIXME) and runs the parse method
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnUpload_Click(object sender, EventArgs e)
{
if (!this.flSource.HasFile)
{
Master.AddFlash("error", "Please select a file to upload.");
return;
}
if (this.ddlFormats.SelectedIndex == 0)
{
Master.AddFlash("error", "Please select a format for that data that you are uploading.");
return;
}
string filename = string.Format(@"C:\temp\{0}.txt", DateTime.Now.Ticks.ToString());
try
{
this.flSource.SaveAs(filename);
Session["file"] = filename;
}
catch (Exception ex)
{
Master.AddFlash("error", "There was an error in your file: " + ex.Message);
Elmah.ErrorLog.GetDefault(this.Context).Log(new Elmah.Error(ex));
Trace.Write(ex.Message);
}
this.parseFile();
}
/// <summary>
/// Run the logic to parse the import and add the data to the database
/// </summary>
private void parseFile()
{
//affected[0] = created, affected[1] = updated, affected[2] = skipped
int[] affected = { 0, 0, 0 };
int id = Convert.ToInt32(this.ddlFormats.SelectedValue);
var reader = new CsvReader(new StreamReader(Session["file"].ToString()));
reader.Configuration.HasHeaderRecord = false;
CobaltDB db = new CobaltDB();
var group = db.Users.First(u => u.Username == HttpContext.Current.User.Identity.Name).Group;
var import = group.CustomImports.First(f => f.ID == id);
JavaScriptSerializer s = new JavaScriptSerializer();
Dictionary<string, string> encodedFields = s.Deserialize(import.Format, typeof(Dictionary<string, string>)) as Dictionary<string, string>;
if (encodedFields == null)
{
Master.AddFlash("error", "Unable to load the custom import, please contact support.");
return;
}
while (reader.Read())
{
SurgicalLog entry = new SurgicalLog();
entry.Status = (char)SurgicalLogStatus.ImportHold;
entry.GroupID = 3;
Hashtable surgeon = new Hashtable();
#region fields
foreach (var d in encodedFields)
{
int idx = Convert.ToInt32(d.Key);
if (this.staticFieldNames.Contains(d.Value))
{
#region static
//straight static surgical log field, so run a switch on the value to find out which field it is.
switch (d.Value)
{
case "firstname":
entry.Firstname = reader.GetField<string>(idx);
break;
case "middlename":
entry.Middlename = reader.GetField<string>(idx);
break;
case "lastname":
entry.Lastname = reader.GetField<string>(idx);
break;
case "surgerydate":
try
{
entry.SurgeryDate = reader.GetField<DateTime?>(idx);
}
catch (FormatException fex)
{
Trace.Warn(fex.Message);
Trace.Warn(fex.StackTrace);
}
break;
case "sex":
//FIXME: sex is stored as M or F in the schema, who knows how they are going to be uploading files.
entry.Sex = reader.GetField<string>(idx)[0];
break;
case "dob":
try
{
entry.Birthdate = reader.GetField<DateTime?>(idx);
}
catch (FormatException fex)
{
Trace.Warn(fex.Message);
Trace.Warn(fex.StackTrace);
}
break;
case "ssn":
entry.SSN = reader.GetField<string>(idx);
break;
case "fullnameFL":
try
{
string[] name = d.Value.Replace(",", "").Split(' ');
entry.Firstname = name[0];
entry.Lastname = name[1];
}
catch (IndexOutOfRangeException iex)
{
Trace.Warn("fullnameLF issue: " + d.Value);
Trace.Warn(iex.Message);
Trace.Warn(iex.StackTrace);
}
break;
case "fullnameFML":
try
{
string[] name = d.Value.Replace(",", "").Split(' ');
entry.Firstname = name[0];
entry.Middlename = name[1];
entry.Lastname = name[2];
}
catch (IndexOutOfRangeException iex)
{
Trace.Warn("fullnameFML issue: " + d.Value);
Trace.Warn(iex.Message);
Trace.Warn(iex.StackTrace);
}
break;
case "fullnameLF":
try
{
string[] name = d.Value.Replace(",", "").Split(' ');
entry.Firstname = name[1];
entry.Lastname = name[0];
}
catch (IndexOutOfRangeException iex)
{
Trace.Warn("fullnameLF issue: " + d.Value);
Trace.Warn(iex.Message);
Trace.Warn(iex.StackTrace);
}
break;
//surgeon
case "surgeonfirstname":
surgeon["first"] = reader.GetField<string>(idx);
break;
case "surgeonmiddlename":
surgeon["middle"] = reader.GetField<string>(idx);
break;
case "surgeonlastname":
surgeon["last"] = reader.GetField<string>(idx);
break;
case "surgeonsuffix":
surgeon["suffix"] = reader.GetField<string>(idx);
break;
case "surgeonfullnameFL":
try
{
string[] name = d.Value.Replace(",", "").Split(' ');
surgeon["first"] = name[0];
surgeon["last"] = name[1];
}
catch (IndexOutOfRangeException iex)
{
Trace.Warn("fullnameLF issue: " + d.Value);
Trace.Warn(iex.Message);
Trace.Warn(iex.StackTrace);
}
break;
case "surgeonfullnameFML":
try
{
string[] name = d.Value.Replace(",", "").Split(' ');
surgeon["first"] = name[0];
surgeon["middle"] = name[1];
surgeon["last"] = name[2];
}
catch (IndexOutOfRangeException iex)
{
Trace.Warn("fullnameFML issue: " + d.Value);
Trace.Warn(iex.Message);
Trace.Warn(iex.StackTrace);
}
break;
case "surgeonfullnameLF":
try
{
string[] name = d.Value.Replace(",", "").Split(' ');
surgeon["first"] = name[1];
surgeon["last"] = name[0];
}
catch (IndexOutOfRangeException iex)
{
Trace.Warn("fullnameLF issue: " + d.Value);
Trace.Warn(iex.Message);
Trace.Warn(iex.StackTrace);
}
break;
default:
Trace.Write(d.Value + " not parsed");
break;
}
#endregion
}
else if (d.Value.IndexOf("#") != -1)
{
//multi-part custom
string[] split = d.Value.Split('#');
int fieldid = Convert.ToInt32(split[0]);
int order = Convert.ToInt32(split[1]);
SurgicalLogCustomField cf = db.SurgicalLogCustomFields.FirstOrDefault(slcf => slcf.ID == fieldid);
var cv = entry.SurgicalLogCustomValues.FirstOrDefault(slcv => slcv.CustomFieldID == cf.ID);
if (cv == null)
{
entry.SurgicalLogCustomValues.Add(new SurgicalLogCustomValue()
{
SurgicalLogCustomField = cf,
Value = reader.GetField<string>(idx)
});
}
else
{
//im clever.
var a = cv.Value.Split(' ').ToList();
a.Insert(order - 1, reader.GetField<string>(idx));
cv.Value = string.Join(" ", a.ToArray());
}
}
else
{
//regular custom field
SurgicalLogCustomField f = db.SurgicalLogCustomFields.FirstOrDefault(sl => sl.ID == Convert.ToInt32(d.Value));
//single select needs to be cleared out if there are values already
if (f.Type == (char)SurgicalLogCustomFieldTypes.SingleSelect)
{
var e = entry.SurgicalLogCustomValues.Where(vs => vs.CustomFieldID == f.ID);
db.SurgicalLogCustomValues.DeleteAllOnSubmit(e);
}
SurgicalLogCustomValue cv = new SurgicalLogCustomValue()
{
SurgicalLog = entry,
SurgicalLogCustomField = f,
Value = reader.GetField<string>(idx)
};
entry.SurgicalLogCustomValues.Add(cv);
}
} //end foreach(field)
#endregion
//NOTE: this is how we did it at the old company
var extant = db.SurgicalLogs.FirstOrDefault(sl => sl.Firstname == entry.Firstname && sl.Lastname == entry.Lastname && sl.SurgeryDate == entry.SurgeryDate);
//sl.SurgicalLogCustomValues.First(slcv => slcv.SurgicalLogCustomField.ID == 34).Value == entry.SurgicalLogCustomValues.First(slcv2 => slcv2.SurgicalLogCustomField.ID == 34).Value
if (extant != null)// && (extant.Status == (char)SurgicalLogStatus.Completed || extant.Status == (char)SurgicalLogStatus.Pending))
{
affected[2]++;
entry.Status = 'E';
continue;
}
//else if (extant != null && (extant.Status == (char)SurgicalLogStatus.Deleted || extant.Status == (char)SurgicalLogStatus.ImportHold))
//{
// affected[1]++;
// db.SurgicalLogs.DeleteOnSubmit(extant);
// db.SurgicalLogs.InsertOnSubmit(entry);
// //group.SurgicalLogs.Add(entry);
//}
else
{
affected[0]++;
//group.SurgicalLogs.Add(entry);
db.SurgicalLogs.InsertOnSubmit(entry);
int did = this.guessDoctor(surgeon);
if (did > 0)
{
entry.DoctorID = did;
}
try
{
db.SubmitChanges();
}
catch (Exception ex)
{
Master.AddFlash("error", ex.Message);
Elmah.ErrorLog.GetDefault(this.Context).Log(new Elmah.Error(ex));
}
}
} //end while(read)
db.Dispose();
Master.AddFlash("success", string.Format("Created: {0}, Updated: {1}, Skipped: {2}", affected[0], affected[1], affected[2]));
this.gvImports.DataBind();
this.tools.Visible = affected[0] > 0 || affected[1] > 0;
}
private int guessDoctor(Hashtable surgeon)
{
string name = "";
if (surgeon["first"] != null)
{
name = surgeon["first"].ToString();
}
if (surgeon["middle"] != null)
{
name += " " + surgeon["middle"];
}
if (surgeon["last"] != null)
{
name += " " + surgeon["last"].ToString();
}
if (surgeon["suffix"] != null)
{
name += ", " + surgeon["suffix"].ToString();
}
using (CobaltDB db = new CobaltDB())
{
var group = db.Users.First(u => u.Username == HttpContext.Current.User.Identity.Name).Group;
var dr = group.Doctors.FirstOrDefault(s => s.Name == name);
if (dr == null)
{
Doctor d = new Doctor()
{
Name = name,
Active = true,
};
try
{
group.Doctors.Add(d);
db.SubmitChanges();
return d.ID;
}
catch (Exception ex)
{
Trace.Warn(ex.Message);
Trace.Warn(ex.StackTrace);
return -1;
}
}
else
{
return dr.ID;
}
}
}
protected void cbSelectAll_Checked(object sender, EventArgs e)
{
CheckBox header = sender as CheckBox;
foreach (GridViewRow row in this.gvImports.Rows)
{
CheckBox cb = row.FindControl("cbSelect") as CheckBox;
if (cb == null) return;
cb.Checked = header.Checked;
}
}
protected void btnTools_Command(object sender, CommandEventArgs e)
{
switch (e.CommandName)
{
case "approveall":
var i = SurgicalLog.ApproveImports();
Master.AddFlash("notice", "Approved " + i.ToString() + " records.");
this.gvImports.DataBind();
break;
case "approvechk":
var r = this.approveChecked();
Master.AddFlash("notice", "Approved " + r.ToString() + " records.");
break;
default:
break;
}
this.gvImports.DataBind();
}
/// <summary>
///
/// </summary>
/// <remarks>
/// Documentation
/// </remarks>
protected int approveChecked()
{
int res = -1;
this.gvImports.ActOnCheckedRows("cbSelect", false, checkedRows =>
{
if (checkedRows.Count() <= 0)
{
Master.AddFlash("error", "Please check an entry to approve");
return;
}
res = checkedRows.Count();
using (CobaltDB db = new CobaltDB())
{
foreach (int id in checkedRows)
{
var item = db.SurgicalLogs.FirstOrDefault(i => i.GroupID == Convert.ToInt32(this.Session["groupID"]) && i.ID == id);
item.Status = (char)SurgicalLogStatus.Pending;
}
db.SubmitChanges();
}
});
return res;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment