diff --git a/Disco.Models/Services/Devices/Importing/DeviceImportFieldTypes.cs b/Disco.Models/Services/Devices/Importing/DeviceImportFieldTypes.cs index 443dafae..fbe02c29 100644 --- a/Disco.Models/Services/Devices/Importing/DeviceImportFieldTypes.cs +++ b/Disco.Models/Services/Devices/Importing/DeviceImportFieldTypes.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; namespace Disco.Models.Services.Devices.Importing { @@ -11,6 +6,8 @@ namespace Disco.Models.Services.Devices.Importing { [Required, Display(Name = "Device Serial Number", Description = "The device serial number")] DeviceSerialNumber, + [Display(Name = "Device Computer Name", Description = "The device computer name")] + DeviceComputerName, [Display(Name = "Device Asset Number", Description = "The device asset number")] DeviceAssetNumber, [Display(Name = "Device Location", Description = "The device location")] diff --git a/Disco.Services/Devices/DeviceExtensions.cs b/Disco.Services/Devices/DeviceExtensions.cs index c69b39fa..35e288c9 100644 --- a/Disco.Services/Devices/DeviceExtensions.cs +++ b/Disco.Services/Devices/DeviceExtensions.cs @@ -65,6 +65,7 @@ namespace Disco.Services { // Just Include: // - Serial Number + // - Device Domain Id // - Asset Number // - Profile Id // - Assigned User Id @@ -102,6 +103,7 @@ namespace Disco.Services Device d2 = new Device() { SerialNumber = d.SerialNumber.ToUpper(), + DeviceDomainId = d.DeviceDomainId, AssetNumber = d.AssetNumber, Location = d.Location, CreatedDate = DateTime.Now, diff --git a/Disco.Services/Devices/Importing/BaseDeviceImportContext.cs b/Disco.Services/Devices/Importing/BaseDeviceImportContext.cs index 4387ca26..bccc5817 100644 --- a/Disco.Services/Devices/Importing/BaseDeviceImportContext.cs +++ b/Disco.Services/Devices/Importing/BaseDeviceImportContext.cs @@ -13,6 +13,7 @@ namespace Disco.Services.Devices.Importing return new Dictionary() { { DeviceImportFieldTypes.DeviceSerialNumber, typeof(DeviceSerialNumberImportField) }, + { DeviceImportFieldTypes.DeviceComputerName, typeof(DeviceComputerNameImportField) }, { DeviceImportFieldTypes.DeviceAssetNumber, typeof(DeviceAssetNumberImportField) }, { DeviceImportFieldTypes.DeviceLocation, typeof(DeviceLocationImportField) }, { DeviceImportFieldTypes.DeviceAllowUnauthenticatedEnrol, typeof(DeviceAllowUnauthenticatedEnrolImportField) }, diff --git a/Disco.Services/Devices/Importing/Fields/DeviceComputerNameImportField.cs b/Disco.Services/Devices/Importing/Fields/DeviceComputerNameImportField.cs new file mode 100644 index 00000000..1e5ef9a9 --- /dev/null +++ b/Disco.Services/Devices/Importing/Fields/DeviceComputerNameImportField.cs @@ -0,0 +1,88 @@ +using Disco.Data.Repository; +using Disco.Models.Repository; +using Disco.Models.Services.Devices.Importing; +using Disco.Services.Interop.ActiveDirectory; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; + +namespace Disco.Services.Devices.Importing.Fields +{ + internal class DeviceComputerNameImportField : DeviceImportFieldBase + { + private const int maxLength = 60; + private string parsedValue; + private string previousValue; + + public override DeviceImportFieldTypes FieldType { get { return DeviceImportFieldTypes.DeviceComputerName; } } + + public override object RawParsedValue { get { return parsedValue; } } + public override string FriendlyValue { get { return parsedValue; } } + public override string FriendlyPreviousValue { get { return previousValue; } } + + public override bool Parse(DiscoDataContext Database, IDeviceImportCache Cache, IDeviceImportContext Context, string DeviceSerialNumber, Device ExistingDevice, List PreviousRecords, IDeviceImportDataReader DataReader, int ColumnIndex) + { + var value = DataReader.GetString(ColumnIndex); + + if (string.IsNullOrWhiteSpace(value)) + parsedValue = null; + else + parsedValue = value.Trim(); + + if (string.IsNullOrEmpty(parsedValue)) + return Error("The Device Computer Name is required"); + + try + { + parsedValue = ActiveDirectory.ParseDomainAccountId(parsedValue); + } + catch (ArgumentException ex) when (ex.ParamName == "NetBiosName") + { + return Error(ex.Message); + } + + if (parsedValue.Length > maxLength) + return Error($"Cannot be more than {maxLength} characters"); + + if (ExistingDevice != null) + { + if (string.Equals(parsedValue, ExistingDevice.DeviceDomainId, StringComparison.OrdinalIgnoreCase)) + return Success(EntityState.Unchanged); + if (ExistingDevice.EnrolledDate.HasValue) + return Error("The Device Computer Name cannot be changed after a device has enrolled"); + else + { + previousValue = ExistingDevice.DeviceDomainId; + return Success(EntityState.Modified); + } + } + + return Success(EntityState.Added); + } + + public override bool Apply(DiscoDataContext Database, Device Device) + { + if (FieldAction == EntityState.Added || + FieldAction == EntityState.Modified) + { + Device.DeviceDomainId = parsedValue; + return true; + } + else + { + return false; + } + } + + public override int? GuessColumn(DiscoDataContext Database, IDeviceImportContext Context, IDeviceImportDataReader DataReader) + { + // column name + var possibleColumns = Context.Columns + .Where(h => h.Type == DeviceImportFieldTypes.IgnoreColumn && + h.Name.IndexOf("name", StringComparison.OrdinalIgnoreCase) >= 0); + + return possibleColumns.Select(h => (int?)h.Index).FirstOrDefault(); + } + } +} diff --git a/Disco.Services/Disco.Services.csproj b/Disco.Services/Disco.Services.csproj index 18aff68b..760c450a 100644 --- a/Disco.Services/Disco.Services.csproj +++ b/Disco.Services/Disco.Services.csproj @@ -265,6 +265,7 @@ + diff --git a/Disco.Web/Controllers/DeviceController.cs b/Disco.Web/Controllers/DeviceController.cs index 37f449cb..01c71ef9 100644 --- a/Disco.Web/Controllers/DeviceController.cs +++ b/Disco.Web/Controllers/DeviceController.cs @@ -5,6 +5,7 @@ using Disco.Models.UI.Device; using Disco.Services; using Disco.Services.Authorization; using Disco.Services.Devices.Exporting; +using Disco.Services.Interop.ActiveDirectory; using Disco.Services.Plugins.Features.DetailsProvider; using Disco.Services.Plugins.Features.UIExtension; using Disco.Services.Users; @@ -77,6 +78,16 @@ namespace Disco.Web.Controllers if (!string.IsNullOrEmpty(m.Device.SerialNumber) && Database.Devices.Count(d => d.SerialNumber == m.Device.SerialNumber) > 0) ModelState.AddModelError("Device.SerialNumber", "A Device what this Serial Number already exists"); } + if (string.IsNullOrWhiteSpace(m.Device.DeviceDomainId)) + m.Device.DeviceDomainId = null; + try + { + m.Device.DeviceDomainId = ActiveDirectory.ParseDomainAccountId(m.Device.DeviceDomainId); + } + catch (ArgumentException ex) + { + ModelState.AddModelError("Device.DeviceDomainId", ex.Message); + } if (ModelState.IsValid) { diff --git a/Disco.Web/Views/Device/AddOffline.cshtml b/Disco.Web/Views/Device/AddOffline.cshtml index 07772b95..b1d217d5 100644 --- a/Disco.Web/Views/Device/AddOffline.cshtml +++ b/Disco.Web/Views/Device/AddOffline.cshtml @@ -9,7 +9,7 @@ var hasDeviceBatch = Authorization.Has(Claims.Device.Properties.DeviceBatch); var hasDeviceProfile = Authorization.Has(Claims.Device.Properties.DeviceProfile); var hasAssignUser = Authorization.Has(Claims.Device.Actions.AssignUser); - + } @using (Html.BeginForm()) { @@ -17,19 +17,31 @@
- + + + + @if (hasAssetNumber) { - - @@ -37,9 +49,11 @@ @if (hasLocation) { - - @@ -47,7 +61,8 @@ @if (hasDeviceBatch) { - - -
Serial Number: + + Serial Number (required): @Html.TextBoxFor(model => model.Device.SerialNumber)
@Html.ValidationMessageFor(model => model.Device.SerialNumber)
+ Computer Name: + + @Html.TextBoxFor(model => model.Device.DeviceDomainId)
+ @Html.ValidationMessageFor(model => model.Device.DeviceDomainId) +
Asset Number: + + Asset Number: @Html.TextBoxFor(model => model.Device.AssetNumber)
+
+ @Html.TextBoxFor(model => model.Device.AssetNumber)
@Html.ValidationMessageFor(model => model.Device.AssetNumber)
Location: + + Location: @Html.TextBoxFor(model => model.Device.Location)
+
+ @Html.TextBoxFor(model => model.Device.Location)
@Html.ValidationMessageFor(model => model.Device.Location)
Device Batch: + + Device Batch: @Html.DropDownListFor(model => model.Device.DeviceBatchId, Model.DeviceBatches.ToSelectListItems()) @@ -59,7 +74,8 @@ @if (hasDeviceProfile) {
Device Profile: + + Device Profile: @Html.DropDownListFor(model => model.Device.DeviceProfileId, Model.DeviceProfiles.ToSelectListItems(Model.DefaultDeviceProfileId))
@@ -70,7 +86,8 @@ @if (hasAssignUser) {
Assigned User: + + Assigned User: @Html.TextBoxFor(model => model.Device.AssignedUserId)
@@ -87,13 +104,20 @@

- + } diff --git a/Disco.Web/Views/Device/AddOffline.generated.cs b/Disco.Web/Views/Device/AddOffline.generated.cs index 709e523b..f5a88175 100644 --- a/Disco.Web/Views/Device/AddOffline.generated.cs +++ b/Disco.Web/Views/Device/AddOffline.generated.cs @@ -2,7 +2,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34014 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -27,7 +27,6 @@ namespace Disco.Web.Views.Device using System.Web.UI; using System.Web.WebPages; using Disco; - using Disco.BI.Extensions; using Disco.Models.Repository; using Disco.Services; using Disco.Services.Authorization; @@ -56,7 +55,7 @@ namespace Disco.Web.Views.Device var hasDeviceBatch = Authorization.Has(Claims.Device.Properties.DeviceBatch); var hasDeviceProfile = Authorization.Has(Claims.Device.Properties.DeviceProfile); var hasAssignUser = Authorization.Has(Claims.Device.Actions.AssignUser); - + #line default @@ -91,13 +90,13 @@ WriteLiteral(" class=\"form\""); WriteLiteral(" style=\"width: 450px\""); -WriteLiteral(">\r\n \r\n \r\n \r\n
Serial Number:\r\n " + -" \r\n"); +WriteLiteral(">\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n Computer Name:\r\n \r\n \r\n"); + +WriteLiteral(" "); + + + #line 33 "..\..\Views\Device\AddOffline.cshtml" + Write(Html.TextBoxFor(model => model.Device.DeviceDomainId)); + + + #line default + #line hidden +WriteLiteral("
\r\n"); + +WriteLiteral(" "); + + + #line 34 "..\..\Views\Device\AddOffline.cshtml" + Write(Html.ValidationMessageFor(model => model.Device.DeviceDomainId)); + + #line default #line hidden WriteLiteral("\r\n \r\n
\r\n"); - #line 27 "..\..\Views\Device\AddOffline.cshtml" + #line 37 "..\..\Views\Device\AddOffline.cshtml" #line default #line hidden - #line 27 "..\..\Views\Device\AddOffline.cshtml" + #line 37 "..\..\Views\Device\AddOffline.cshtml" if (hasAssetNumber) { #line default #line hidden -WriteLiteral(" \r\n \r\n \r\n \r\n \r\n \r\n"); - #line 36 "..\..\Views\Device\AddOffline.cshtml" + #line 48 "..\..\Views\Device\AddOffline.cshtml" } @@ -163,18 +188,20 @@ WriteLiteral("\r\n \r\n \r\n"); WriteLiteral(" "); - #line 37 "..\..\Views\Device\AddOffline.cshtml" + #line 49 "..\..\Views\Device\AddOffline.cshtml" if (hasLocation) { #line default #line hidden -WriteLiteral(" \r\n \r\n \r\n \r\n \r\n"); - #line 46 "..\..\Views\Device\AddOffline.cshtml" + #line 60 "..\..\Views\Device\AddOffline.cshtml" } @@ -203,20 +230,20 @@ WriteLiteral("\r\n \r\n \r\n"); WriteLiteral(" "); - #line 47 "..\..\Views\Device\AddOffline.cshtml" + #line 61 "..\..\Views\Device\AddOffline.cshtml" if (hasDeviceBatch) { #line default #line hidden -WriteLiteral(" \r\n \r\n \r\n \r\n \r\n \r\n"); - #line 58 "..\..\Views\Device\AddOffline.cshtml" + #line 73 "..\..\Views\Device\AddOffline.cshtml" } @@ -245,20 +272,20 @@ WriteLiteral("\r\n \r\n \r\n"); WriteLiteral(" "); - #line 59 "..\..\Views\Device\AddOffline.cshtml" + #line 74 "..\..\Views\Device\AddOffline.cshtml" if (hasDeviceProfile) { #line default #line hidden -WriteLiteral(" \r\n \r\n \r\n \r\n \r\n \r\n"); - #line 69 "..\..\Views\Device\AddOffline.cshtml" + #line 85 "..\..\Views\Device\AddOffline.cshtml" } @@ -287,20 +314,20 @@ WriteLiteral("\r\n \r\n \r\n"); WriteLiteral(" "); - #line 70 "..\..\Views\Device\AddOffline.cshtml" + #line 86 "..\..\Views\Device\AddOffline.cshtml" if (hasAssignUser) { #line default #line hidden -WriteLiteral(" \r\n \r\n \r\n \r\n \r\n \r\n"); - #line 80 "..\..\Views\Device\AddOffline.cshtml" + #line 97 "..\..\Views\Device\AddOffline.cshtml" } @@ -333,13 +360,13 @@ WriteLiteral(" class=\"actions\""); WriteLiteral(">\r\n"); - #line 83 "..\..\Views\Device\AddOffline.cshtml" + #line 100 "..\..\Views\Device\AddOffline.cshtml" #line default #line hidden - #line 83 "..\..\Views\Device\AddOffline.cshtml" + #line 100 "..\..\Views\Device\AddOffline.cshtml" if (!hasDeviceProfile) { @@ -347,14 +374,14 @@ WriteLiteral(">\r\n"); #line default #line hidden - #line 85 "..\..\Views\Device\AddOffline.cshtml" + #line 102 "..\..\Views\Device\AddOffline.cshtml" Write(Html.Hidden("Device.DeviceProfileId", Model.DefaultDeviceProfileId)); #line default #line hidden - #line 85 "..\..\Views\Device\AddOffline.cshtml" + #line 102 "..\..\Views\Device\AddOffline.cshtml" } @@ -369,40 +396,53 @@ WriteLiteral(" class=\"button\""); WriteLiteral(" value=\"Add\""); -WriteLiteral(" />\r\n

\r\n \r\n

\r\n \r\n $(function () {\r\n var $SerialNumber = $(\'#D" + -"evice_SerialNumber\').focus();\r\n\r\n"); +WriteLiteral(@"> + $(function () { + var $SerialNumber = $('#Device_SerialNumber').focus(); + + $SerialNumber.keydown(function (e) { + if (e.which == 13) { + $('#Device_DeviceDomainId').focus(); + return false; + } + }); + +"); - #line 94 "..\..\Views\Device\AddOffline.cshtml" + #line 118 "..\..\Views\Device\AddOffline.cshtml" #line default #line hidden - #line 94 "..\..\Views\Device\AddOffline.cshtml" + #line 118 "..\..\Views\Device\AddOffline.cshtml" if (hasAssignUser) { #line default #line hidden -WriteLiteral("\r\n $SerialNumber.keydown(function (e) {\r\n if (e" + -".which == 13) {\r\n $(\'#Device_AssignedUserId\').focus();\r\n " + -" return false;\r\n }\r\n });" + -""); +WriteLiteral(@" + $('#Device_DeviceDomainId').keydown(function (e) { + if (e.which == 13) { + $('#Device_AssignedUserId').focus(); + return false; + } + });"); - #line 101 "..\..\Views\Device\AddOffline.cshtml" + #line 125 "..\..\Views\Device\AddOffline.cshtml" } #line default #line hidden - #line 102 "..\..\Views\Device\AddOffline.cshtml" + #line 126 "..\..\Views\Device\AddOffline.cshtml" if (hasAssetNumber) { @@ -412,13 +452,13 @@ WriteLiteral("\r\n $(\'#Device_AssetNumber\').keydown(functio " if (e.which == 13) {\r\n"); - #line 106 "..\..\Views\Device\AddOffline.cshtml" + #line 130 "..\..\Views\Device\AddOffline.cshtml" #line default #line hidden - #line 106 "..\..\Views\Device\AddOffline.cshtml" + #line 130 "..\..\Views\Device\AddOffline.cshtml" if (hasLocation) { @@ -427,7 +467,7 @@ WriteLiteral("\r\n $(\'#Device_AssetNumber\').keydown(functio WriteLiteral("$(\'#Device_Location\').focus(); return false;"); - #line 107 "..\..\Views\Device\AddOffline.cshtml" + #line 131 "..\..\Views\Device\AddOffline.cshtml" } else if (hasAssignUser) { @@ -437,7 +477,7 @@ WriteLiteral("$(\'#Device_Location\').focus(); return false;"); WriteLiteral("$(\'#Device_AssignedUserId\').focus(); return false;"); - #line 109 "..\..\Views\Device\AddOffline.cshtml" + #line 133 "..\..\Views\Device\AddOffline.cshtml" } @@ -446,14 +486,14 @@ WriteLiteral("$(\'#Device_AssignedUserId\').focus(); return false;"); WriteLiteral(" }\r\n });\r\n "); - #line 112 "..\..\Views\Device\AddOffline.cshtml" + #line 136 "..\..\Views\Device\AddOffline.cshtml" } #line default #line hidden - #line 113 "..\..\Views\Device\AddOffline.cshtml" + #line 137 "..\..\Views\Device\AddOffline.cshtml" if (hasLocation && hasAssignUser) { @@ -469,7 +509,7 @@ WriteLiteral(@" "); - #line 121 "..\..\Views\Device\AddOffline.cshtml" + #line 145 "..\..\Views\Device\AddOffline.cshtml" } @@ -478,7 +518,7 @@ WriteLiteral(@" WriteLiteral(" "); - #line 122 "..\..\Views\Device\AddOffline.cshtml" + #line 146 "..\..\Views\Device\AddOffline.cshtml" if (hasAssignUser) { @@ -493,7 +533,7 @@ WriteLiteral(@" source: '"); - #line 129 "..\..\Views\Device\AddOffline.cshtml" + #line 153 "..\..\Views\Device\AddOffline.cshtml" Write(Url.Action(MVC.API.Search.UsersUpstream())); @@ -518,16 +558,16 @@ WriteLiteral(@"', "); - #line 145 "..\..\Views\Device\AddOffline.cshtml" + #line 169 "..\..\Views\Device\AddOffline.cshtml" } #line default #line hidden -WriteLiteral(" });\r\n \r\n \r\n"); +WriteLiteral(" });\r\n \r\n \r\n"); - #line 149 "..\..\Views\Device\AddOffline.cshtml" + #line 173 "..\..\Views\Device\AddOffline.cshtml" }
\r\n S" + +"erial Number (required):\r\n \r\n"); WriteLiteral(" "); - #line 23 "..\..\Views\Device\AddOffline.cshtml" + #line 24 "..\..\Views\Device\AddOffline.cshtml" Write(Html.TextBoxFor(model => model.Device.SerialNumber)); @@ -108,33 +107,59 @@ WriteLiteral("
\r\n"); WriteLiteral(" "); - #line 24 "..\..\Views\Device\AddOffline.cshtml" + #line 25 "..\..\Views\Device\AddOffline.cshtml" Write(Html.ValidationMessageFor(model => model.Device.SerialNumber)); + #line default + #line hidden +WriteLiteral("\r\n
Asset Number:\r\n " + -""); +WriteLiteral("
\r\n Asset Num" + +"ber:\r\n \r\n"); + +WriteLiteral(" "); - #line 32 "..\..\Views\Device\AddOffline.cshtml" + #line 44 "..\..\Views\Device\AddOffline.cshtml" Write(Html.TextBoxFor(model => model.Device.AssetNumber)); @@ -145,7 +170,7 @@ WriteLiteral("
\r\n"); WriteLiteral(" "); - #line 33 "..\..\Views\Device\AddOffline.cshtml" + #line 45 "..\..\Views\Device\AddOffline.cshtml" Write(Html.ValidationMessageFor(model => model.Device.AssetNumber)); @@ -154,7 +179,7 @@ WriteLiteral(" "); WriteLiteral("\r\n
Location:\r\n \r\n "); +WriteLiteral("
\r\n Location:" + +"\r\n \r\n"); + +WriteLiteral(" "); - #line 42 "..\..\Views\Device\AddOffline.cshtml" + #line 56 "..\..\Views\Device\AddOffline.cshtml" Write(Html.TextBoxFor(model => model.Device.Location)); @@ -185,7 +212,7 @@ WriteLiteral("
\r\n"); WriteLiteral(" "); - #line 43 "..\..\Views\Device\AddOffline.cshtml" + #line 57 "..\..\Views\Device\AddOffline.cshtml" Write(Html.ValidationMessageFor(model => model.Device.Location)); @@ -194,7 +221,7 @@ WriteLiteral(" "); WriteLiteral("\r\n
Device Batch:\r\n " + -"\r\n"); +WriteLiteral("
\r\n Device Ba" + +"tch:\r\n \r\n"); WriteLiteral(" "); - #line 53 "..\..\Views\Device\AddOffline.cshtml" + #line 68 "..\..\Views\Device\AddOffline.cshtml" Write(Html.DropDownListFor(model => model.Device.DeviceBatchId, Model.DeviceBatches.ToSelectListItems())); @@ -227,7 +254,7 @@ WriteLiteral("\r\n
\r\n"); WriteLiteral(" "); - #line 55 "..\..\Views\Device\AddOffline.cshtml" + #line 70 "..\..\Views\Device\AddOffline.cshtml" Write(Html.ValidationMessageFor(model => model.Device.DeviceBatchId)); @@ -236,7 +263,7 @@ WriteLiteral(" "); WriteLiteral("\r\n
Device Profile:\r\n " + -" \r\n"); +WriteLiteral("
\r\n Device Pr" + +"ofile:\r\n \r\n"); WriteLiteral(" "); - #line 65 "..\..\Views\Device\AddOffline.cshtml" + #line 81 "..\..\Views\Device\AddOffline.cshtml" Write(Html.DropDownListFor(model => model.Device.DeviceProfileId, Model.DeviceProfiles.ToSelectListItems(Model.DefaultDeviceProfileId))); @@ -269,7 +296,7 @@ WriteLiteral("
\r\n"); WriteLiteral(" "); - #line 66 "..\..\Views\Device\AddOffline.cshtml" + #line 82 "..\..\Views\Device\AddOffline.cshtml" Write(Html.ValidationMessageFor(model => model.Device.DeviceProfileId)); @@ -278,7 +305,7 @@ WriteLiteral(" "); WriteLiteral("\r\n
Assigned User:\r\n " + -" \r\n"); +WriteLiteral("
\r\n Assigned " + +"User:\r\n \r\n"); WriteLiteral(" "); - #line 76 "..\..\Views\Device\AddOffline.cshtml" + #line 93 "..\..\Views\Device\AddOffline.cshtml" Write(Html.TextBoxFor(model => model.Device.AssignedUserId)); @@ -311,7 +338,7 @@ WriteLiteral("
\r\n"); WriteLiteral(" "); - #line 77 "..\..\Views\Device\AddOffline.cshtml" + #line 94 "..\..\Views\Device\AddOffline.cshtml" Write(Html.ValidationMessageFor(model => model.Device.AssignedUserId)); @@ -320,7 +347,7 @@ WriteLiteral(" "); WriteLiteral("\r\n