Feature: Device Importing & Exporting

This commit is contained in:
Gary Sharp
2013-07-25 17:46:20 +10:00
parent a3aaed1d13
commit ad6b1b19b6
67 changed files with 3058 additions and 266 deletions
+102
View File
@@ -0,0 +1,102 @@
using Disco.Models.BI.Device;
using Disco.Models.Repository;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Disco.BI.DeviceBI.Importing
{
public static class Export
{
private const string ExportHeader = "Serial Number,Device Model,Device Profile,Device Batch,Assigned User,Location,Asset Number";
public static MemoryStream GenerateExport(IQueryable<Device> Devices)
{
var devices = Devices.Select(d => new ImportDevice()
{
SerialNumber = d.SerialNumber,
DeviceModelId = d.DeviceModelId,
DeviceProfileId = d.DeviceProfileId,
DeviceBatchId = d.DeviceBatchId,
AssignedUserId = d.AssignedUserId,
Location = d.Location,
AssetNumber = d.AssetNumber
});
MemoryStream exportStream = new MemoryStream();
StreamWriter exportWriter = new StreamWriter(exportStream);
// Write Header
exportWriter.WriteLine(ExportHeader);
foreach (var device in devices)
device.ExportCsv(exportWriter);
exportWriter.Flush();
exportStream.Position = 0;
return exportStream;
}
private static void ExportCsv(this ImportDevice device, StreamWriter writer)
{
// SERIAL NUMBER
writer.Write('"');
writer.Write(device.SerialNumber.Replace("\"", "\"\""));
writer.Write('"');
writer.Write(',');
// DEVICE MODEL
if (device.DeviceModelId.HasValue)
writer.Write(device.DeviceModelId.Value);
writer.Write(',');
// DEVICE PROFILE
writer.Write(device.DeviceProfileId);
writer.Write(',');
// DEVICE BATCH
if (device.DeviceBatchId.HasValue)
writer.Write(device.DeviceBatchId.Value);
writer.Write(',');
// ASSIGNED USER
if (device.AssignedUserId != null)
{
writer.Write('"');
writer.Write(device.AssignedUserId.Replace("\"", "\"\""));
writer.Write('"');
}
writer.Write(',');
// LOCATION
if (!string.IsNullOrWhiteSpace(device.Location))
{
writer.Write('"');
writer.Write(device.Location.Replace("\"", "\"\""));
writer.Write('"');
}
writer.Write(',');
// ASSET NUMBER
if (!string.IsNullOrWhiteSpace(device.AssetNumber))
{
writer.Write('"');
writer.Write(device.AssetNumber.Replace("\"", "\"\""));
writer.Write('"');
}
writer.WriteLine();
}
}
}
+45 -7
View File
@@ -8,14 +8,23 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using PopulateRecordReferences = System.Tuple<System.Collections.Generic.Dictionary<int, Disco.Models.Repository.DeviceModel>, System.Collections.Generic.Dictionary<int, Disco.Models.Repository.DeviceProfile>, System.Collections.Generic.Dictionary<int, Disco.Models.Repository.DeviceBatch>>;
namespace Disco.BI.DeviceBI.Importing
{
internal static class Import
public static class Import
{
internal const string ImportParseCacheKey = "ImportParseResults_{0}";
internal static void ImportRecord(this ImportDevice device, DiscoDataContext dbContext, PopulateRecordReferences references)
public static ImportDeviceSession GetSession(string ImportParseTaskId)
{
string parseKey = string.Format(ImportParseCacheKey, ImportParseTaskId);
return (ImportDeviceSession)HttpRuntime.Cache.Get(parseKey);
}
internal static bool ImportRecord(this ImportDevice device, DiscoDataContext dbContext, PopulateRecordReferences references)
{
// Skips If Errors
if (device.Errors == null || device.Errors.Count == 0)
@@ -38,11 +47,16 @@ namespace Disco.BI.DeviceBI.Importing
dbContext.Devices.Add(discoDevice);
}
discoDevice.DeviceModelId = device.DeviceModelId;
discoDevice.DeviceProfileId = device.DeviceProfileId;
discoDevice.DeviceBatchId = device.DeviceBatchId;
discoDevice.Location = device.Location;
discoDevice.AssetNumber = device.AssetNumber;
if (discoDevice.DeviceModelId != device.DeviceModelId)
discoDevice.DeviceModelId = device.DeviceModelId;
if (discoDevice.DeviceProfileId != device.DeviceProfileId)
discoDevice.DeviceProfileId = device.DeviceProfileId;
if (discoDevice.DeviceBatchId != device.DeviceBatchId)
discoDevice.DeviceBatchId = device.DeviceBatchId;
if (discoDevice.Location != device.Location)
discoDevice.Location = device.Location;
if (discoDevice.AssetNumber != device.AssetNumber)
discoDevice.AssetNumber = device.AssetNumber;
if (discoDevice.AssignedUserId != device.AssignedUserId)
{
@@ -50,8 +64,11 @@ namespace Disco.BI.DeviceBI.Importing
}
dbContext.SaveChanges();
return true;
}
}
return false;
}
internal static PopulateRecordReferences GetPopulateRecordReferences(DiscoDataContext dbContext)
@@ -72,7 +89,12 @@ namespace Disco.BI.DeviceBI.Importing
// SERIAL NUMBER - Existing Device
if (!device.Errors.ContainsKey("SerialNumber"))
{
device.Device = dbContext.Devices.Find(device.SerialNumber);
if (device.Device != null && device.Device.DecommissionedDate.HasValue)
device.Errors.Add("SerialNumber", "The device is decommissioned");
}
// DEVICE MODEL
if (!device.Errors.ContainsKey("DeviceModelId"))
@@ -223,5 +245,21 @@ namespace Disco.BI.DeviceBI.Importing
Errors = errors
};
}
#region ImportDevice Extensions
public static string ImportStatus(this ImportDevice device)
{
if (device.Errors.Count > 0)
return "Error";
if (device.Device != null)
return "Update";
return "New";
}
#endregion
}
}
@@ -22,10 +22,9 @@ namespace Disco.BI.DeviceBI.Importing
public override bool SingleInstanceTask { get { return false; } }
public override bool CancelInitiallySupported { get { return false; } }
internal const string ImportParseCacheKey = "ImportParseResults_{0}";
protected override void ExecuteTask()
{
string csvFilename = (string)this.ExecutionContext.JobDetail.JobDataMap["CsvFilename"];
MemoryStream csvStream = (MemoryStream)this.ExecutionContext.JobDetail.JobDataMap["CsvImport"];
this.Status.UpdateStatus(0, "Parsing CSV File", "Loading Records");
@@ -64,12 +63,20 @@ namespace Disco.BI.DeviceBI.Importing
}
}
// Create Session Result
ImportDeviceSession session = new ImportDeviceSession()
{
ImportParseTaskId = this.Status.SessionId,
ImportFilename = csvFilename,
ImportDevices = records
};
// Set Results to Cache
string key = string.Format(ImportParseCacheKey, this.Status.SessionId);
HttpRuntime.Cache.Insert(key, records, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(60), CacheItemPriority.NotRemovable, null);
string key = string.Format(Import.ImportParseCacheKey, this.Status.SessionId);
HttpRuntime.Cache.Insert(key, session, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(60), CacheItemPriority.NotRemovable, null);
}
public static ScheduledTaskStatus Run(Stream CsvImport)
public static ScheduledTaskStatus Run(Stream CsvImport, String CsvFilename)
{
MemoryStream csvStream = new MemoryStream();
@@ -77,7 +84,7 @@ namespace Disco.BI.DeviceBI.Importing
csvStream.Position = 0;
var task = new ImportParseTask();
JobDataMap taskData = new JobDataMap() { { "CsvImport", csvStream } };
JobDataMap taskData = new JobDataMap() { { "CsvImport", csvStream }, { "CsvFilename", CsvFilename } };
return task.ScheduleTask(taskData);
}
}
@@ -20,18 +20,19 @@ namespace Disco.BI.DeviceBI.Importing
protected override void ExecuteTask()
{
string parseKey = (string)this.ExecutionContext.JobDetail.JobDataMap["ParseKey"];
string importParseTaskId = (string)this.ExecutionContext.JobDetail.JobDataMap["ImportParseTaskId"];
if (string.IsNullOrWhiteSpace(parseKey))
throw new ArgumentNullException("ParseKey");
if (string.IsNullOrWhiteSpace(importParseTaskId))
throw new ArgumentNullException("ImportParseTaskId");
parseKey = string.Format(ImportParseTask.ImportParseCacheKey, parseKey);
ImportDeviceSession session = Import.GetSession(importParseTaskId);
List<ImportDevice> records = (List<ImportDevice>)HttpRuntime.Cache.Get(parseKey);
if (records == null)
if (session == null)
throw new InvalidOperationException("The session timed out (60 minutes), try importing again");
List<ImportDevice> records = session.ImportDevices;
int recordsImported = 0;
this.Status.UpdateStatus(0, "Processing Device Import", "Importing Devices");
using (DiscoDataContext dbContext = new DiscoDataContext())
@@ -41,7 +42,8 @@ namespace Disco.BI.DeviceBI.Importing
DateTime lastUpdate = DateTime.Now;
foreach (var record in records)
{
record.ImportRecord(dbContext, populateReferences);
if (record.ImportRecord(dbContext, populateReferences))
recordsImported++;
if (DateTime.Now.Subtract(lastUpdate).TotalSeconds > 1)
{
@@ -52,15 +54,16 @@ namespace Disco.BI.DeviceBI.Importing
}
}
this.Status.SetFinishedMessage(string.Format("Imported {0} of {1} Devices", recordsImported, records.Count));
}
public static ScheduledTaskStatus Run(string ParseTaskSessionKey)
public static ScheduledTaskStatus Run(string ImportParseTaskId)
{
if (string.IsNullOrWhiteSpace(ParseTaskSessionKey))
throw new ArgumentNullException("ParseTaskSessionKey");
if (string.IsNullOrWhiteSpace(ImportParseTaskId))
throw new ArgumentNullException("ImportParseTaskId");
var task = new ImportProcessTask();
JobDataMap taskData = new JobDataMap() { { "ParseKey", ParseTaskSessionKey } };
JobDataMap taskData = new JobDataMap() { { "ImportParseTaskId", ImportParseTaskId } };
return task.ScheduleTask(taskData);
}
}
+2 -3
View File
@@ -123,6 +123,7 @@
<Compile Include="BI\AttachmentBI\Utilities.cs" />
<Compile Include="BI\DeviceBI\BatchUtilities.cs" />
<Compile Include="BI\DeviceBI\DeviceModelBI.cs" />
<Compile Include="BI\DeviceBI\Importing\Export.cs" />
<Compile Include="BI\DeviceBI\Importing\Import.cs" />
<Compile Include="BI\DeviceBI\Importing\ImportParseTask.cs" />
<Compile Include="BI\DeviceBI\Importing\ImportProcessTask.cs" />
@@ -251,9 +252,7 @@
<ItemGroup>
<None Include="Resources\MimeType-unknown48.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="BI\CertificateBI\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0722.2112")]
[assembly: AssemblyFileVersion("1.2.0722.2112")]
[assembly: AssemblyVersion("1.2.0725.1725")]
[assembly: AssemblyFileVersion("1.2.0725.1725")]