diff --git a/Disco.Models/Disco.Models.csproj b/Disco.Models/Disco.Models.csproj index 8112b623..8abe84bf 100644 --- a/Disco.Models/Disco.Models.csproj +++ b/Disco.Models/Disco.Models.csproj @@ -171,6 +171,7 @@ + diff --git a/Disco.Models/UI/Config/DocumentTemplate/ConfigDocumentTemplateBulkGenerate.cs b/Disco.Models/UI/Config/DocumentTemplate/ConfigDocumentTemplateBulkGenerate.cs new file mode 100644 index 00000000..2f7900a6 --- /dev/null +++ b/Disco.Models/UI/Config/DocumentTemplate/ConfigDocumentTemplateBulkGenerate.cs @@ -0,0 +1,8 @@ +namespace Disco.Models.UI.Config.DocumentTemplate +{ + public interface ConfigDocumentTemplateBulkGenerate : BaseUIModel + { + Repository.DocumentTemplate DocumentTemplate { get; set; } + int TemplatePageCount { get; set; } + } +} diff --git a/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs b/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs index ca319bdd..3d58fda4 100644 --- a/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs +++ b/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs @@ -6,15 +6,21 @@ using Disco.Services.Authorization; using Disco.Services.Documents; using Disco.Services.Documents.ManagedGroups; using Disco.Services.Interop.ActiveDirectory; +using Disco.Services.Plugins; +using Disco.Services.Plugins.Features.DocumentHandlerProvider; using Disco.Services.Tasks; using Disco.Services.Users; using Disco.Services.Web; +using Disco.Web.Areas.API.Models.DocumentTemplate; using System; using System.Collections.Generic; +using System.Data.Entity; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using System.Web; using System.Web.Mvc; +using System.Web.UI.WebControls; namespace Disco.Web.Areas.API.Controllers { @@ -700,43 +706,416 @@ namespace Disco.Web.Areas.API.Controllers return File(stream, "application/pdf", fileName); } - public virtual ActionResult Generate(string id, string TargetId) [DiscoAuthorize(Claims.Config.DocumentTemplate.BulkGenerate)] public virtual ActionResult BulkGenerateDownload(string id, string fileName) { - if (string.IsNullOrWhiteSpace(id)) - throw new ArgumentNullException(nameof(id)); - if (string.IsNullOrWhiteSpace(TargetId)) - throw new ArgumentNullException(nameof(TargetId)); var stream = DocumentBulkGenerateTask.GetCached(Database, id); return File(stream, "application/pdf", fileName); } - // get template - var template = Database.DocumentTemplates.Find(id); - if (template == null) - throw new ArgumentException("Invalid document template id", nameof(id)); - // validate authorization - switch (template.Scope) + [DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult BulkGenerateAddUsers(string userIds) + { + if (string.IsNullOrWhiteSpace(userIds)) + return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest); + + var dataIds = userIds.Split(new string[] { Environment.NewLine, ",", ";" }, StringSplitOptions.RemoveEmptyEntries).Select(d => d.Trim()).Where(d => !string.IsNullOrEmpty(d)).ToList(); + var results = new List(dataIds.Count); + foreach (var dataId in dataIds) { - case DocumentTemplate.DocumentTemplateScopes.Device: - Authorization.Require(Claims.Device.Actions.GenerateDocuments); - break; - case DocumentTemplate.DocumentTemplateScopes.Job: - Authorization.Require(Claims.Job.Actions.GenerateDocuments); - break; - case DocumentTemplate.DocumentTemplateScopes.User: - Authorization.Require(Claims.User.Actions.GenerateDocuments); - break; - default: - throw new InvalidOperationException("Unknown DocumentType Scope"); + var accountId = ActiveDirectory.ParseDomainAccountId(dataId); + + if (UserService.TryGetUser(accountId, Database, true, out var user)) + { + results.Add(new BulkGenerateUserModel() + { + Id = user.UserId, + DisplayName = user.DisplayName, + Scope = $"Matched '{dataId}'", + IsError = false, + }); + continue; + } + else + { + var adObject = ActiveDirectory.RetrieveADObject(accountId, true); + + if (adObject == null) + { + results.Add(new BulkGenerateUserModel() + { + Id = dataId, + DisplayName = dataId, + Scope = $"Unknown User or Security Group '{dataId}'", + IsError = true, + }); + continue; + } + + if (adObject is ADGroup group) + { + foreach (var adUser in group.GetUserMembersRecursive()) + { + results.Add(new BulkGenerateUserModel() + { + Id = adUser.Id, + DisplayName = adUser.DisplayName, + Scope = $"Group Member '{group.Name}'", + IsError = false, + }); + } + continue; + } + else + { + results.Add(new BulkGenerateUserModel() + { + Id = dataId, + DisplayName = dataId, + Scope = $"Unexpected AD Object found at '{adObject.DistinguishedName}'", + IsError = true, + }); + continue; + } + } } - // resolve target - var target = template.ResolveScopeTarget(Database, TargetId); - if (target == null) - throw new ArgumentException("Target not found", nameof(TargetId)); + return Json(results); + } + + [DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult BulkGenerateAddGroupMembers(string groupId) + { + if (string.IsNullOrWhiteSpace(groupId)) + return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest); + + var results = new List(); + var accountId = ActiveDirectory.ParseDomainAccountId(groupId); + + var adObject = ActiveDirectory.RetrieveADObject(accountId, true); + + if (adObject == null) + { + results.Add(new BulkGenerateUserModel() + { + Id = groupId, + DisplayName = groupId, + Scope = $"Unknown Security Group '{groupId}'", + IsError = true, + }); + } + else if (adObject is ADGroup group) + { + foreach (var adUser in group.GetUserMembersRecursive()) + { + results.Add(new BulkGenerateUserModel() + { + Id = adUser.Id, + DisplayName = adUser.DisplayName, + Scope = $"Group Member '{group.Name}'", + IsError = false, + }); + } + } + else if (adObject is ADUserAccount user) + { + results.Add(new BulkGenerateUserModel() + { + Id = user.Id, + DisplayName = user.DisplayName, + Scope = $"Matched '{groupId}'", + IsError = false, + }); + } + else + { + results.Add(new BulkGenerateUserModel() + { + Id = groupId, + DisplayName = groupId, + Scope = $"Unexpected AD Object found at '{adObject.DistinguishedName}'", + IsError = true, + }); + } + + return Json(results); + } + + [DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult BulkGenerateAddUserFlag(int flagId) + { + if (flagId <= 0) + return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest); + + var results = new List(); + + var flag = Database.UserFlags.Include(f => f.UserFlagAssignments.Select(a => a.User)).FirstOrDefault(f => f.Id == flagId); + + if (flag == null) + { + results.Add(new BulkGenerateUserModel() + { + Id = flagId.ToString(), + DisplayName = flagId.ToString(), + Scope = $"Unknown User Flag '{flagId}'", + IsError = true, + }); + } + else + { + var assignments = flag.UserFlagAssignments.Where(a => a.RemovedDate == null).ToList(); + + if (assignments.Count == 0) + { + results.Add(new BulkGenerateUserModel() + { + Id = flag.Name, + DisplayName = flag.Name, + Scope = $"User Flag has no active assignments", + IsError = true, + }); + } + else + { + foreach (var assignment in assignments) + { + results.Add(new BulkGenerateUserModel() + { + Id = assignment.UserId, + DisplayName = assignment.User.DisplayName, + Scope = $"Assigned User Flag '{flag.Name}'", + IsError = false, + }); + } + } + } + + return Json(results); + } + + [DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult BulkGenerateAddDeviceProfile(int deviceProfileId) + { + if (deviceProfileId <= 0) + return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest); + + var results = new List(); + + var profile = Database.DeviceProfiles.Include(p => p.Devices.Select(a => a.AssignedUser)).FirstOrDefault(f => f.Id == deviceProfileId); + + if (profile == null) + { + results.Add(new BulkGenerateUserModel() + { + Id = deviceProfileId.ToString(), + DisplayName = deviceProfileId.ToString(), + Scope = $"Unknown Device Profile '{deviceProfileId}'", + IsError = true, + }); + } + else + { + var assignments = profile.Devices.Where(d => d.AssignedUser != null).ToList(); + + if (assignments.Count == 0) + { + results.Add(new BulkGenerateUserModel() + { + Id = profile.Name, + DisplayName = profile.Name, + Scope = $"Device Profile has no devices with active assignments", + IsError = true, + }); + } + else + { + foreach (var assignment in assignments) + { + results.Add(new BulkGenerateUserModel() + { + Id = assignment.AssignedUserId, + DisplayName = assignment.AssignedUser.DisplayName, + Scope = $"Device Profile '{profile.Name}' Matches Assigned Device '{assignment.SerialNumber}'", + IsError = false, + }); + } + } + } + + return Json(results); + } + + [DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult BulkGenerateAddDeviceBatch(int deviceBatchId) + { + if (deviceBatchId <= 0) + return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest); + + var results = new List(); + + var batch = Database.DeviceBatches.Include(p => p.Devices.Select(a => a.AssignedUser)).FirstOrDefault(f => f.Id == deviceBatchId); + + if (batch == null) + { + results.Add(new BulkGenerateUserModel() + { + Id = deviceBatchId.ToString(), + DisplayName = deviceBatchId.ToString(), + Scope = $"Unknown Device Batch '{deviceBatchId}'", + IsError = true, + }); + } + else + { + var assignments = batch.Devices.Where(d => d.AssignedUser != null).ToList(); + + if (assignments.Count == 0) + { + results.Add(new BulkGenerateUserModel() + { + Id = batch.Name, + DisplayName = batch.Name, + Scope = $"Device Batch has no devices with active assignments", + IsError = true, + }); + } + else + { + foreach (var assignment in assignments) + { + results.Add(new BulkGenerateUserModel() + { + Id = assignment.AssignedUserId, + DisplayName = assignment.AssignedUser.DisplayName, + Scope = $"Device Batch '{batch.Name}' Matches Assigned Device '{assignment.SerialNumber}'", + IsError = false, + }); + } + } + } + + return Json(results); + } + + [DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult BulkGenerateAddDocumentAttachment(string documentTemplateId, DateTime? threshold) + { + if (string.IsNullOrWhiteSpace(documentTemplateId)) + return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest); + + var results = new List(); + + var template = Database.DocumentTemplates.FirstOrDefault(f => f.Id == documentTemplateId); + + if (template == null) + { + results.Add(new BulkGenerateUserModel() + { + Id = documentTemplateId, + DisplayName = documentTemplateId, + Scope = $"Unknown Document Template '{documentTemplateId}'", + IsError = true, + }); + } + else + { + switch (template.AttachmentType) + { + case AttachmentTypes.Device: + var deviceAssignments = Database.DeviceAttachments + .Include(a => a.Device.AssignedUser) + .Where(a => a.DocumentTemplateId == template.Id && (threshold == null || a.Timestamp > threshold) && a.Device.AssignedUserId != null) + .ToList(); + foreach (var assignment in deviceAssignments) + { + results.Add(new BulkGenerateUserModel() + { + Id = assignment.Device.AssignedUserId, + DisplayName = assignment.Device.AssignedUser.DisplayName, + Scope = $"Document Template '{template.Id}' Attachment Matches Assigned Device '{assignment.Device.SerialNumber}'", + IsError = false, + }); + } + break; + case AttachmentTypes.Job: + var jobAssignments = Database.JobAttachments + .Include(a => a.Job.User) + .Where(a => a.DocumentTemplateId == template.Id && (threshold == null || a.Timestamp > threshold) && a.Job.UserId != null) + .ToList(); + foreach (var assignment in jobAssignments) + { + results.Add(new BulkGenerateUserModel() + { + Id = assignment.Job.UserId, + DisplayName = assignment.Job.User.DisplayName, + Scope = $"Document Template '{template.Id}' Attachment Matches Job '{assignment.Job.Id}'", + IsError = false, + }); + } + break; + case AttachmentTypes.User: + var userAssignments = Database.UserAttachments + .Include(a => a.User) + .Where(a => a.DocumentTemplateId == template.Id && (threshold == null || a.Timestamp > threshold) && a.UserId != null) + .ToList(); + foreach (var assignment in userAssignments) + { + results.Add(new BulkGenerateUserModel() + { + Id = assignment.UserId, + DisplayName = assignment.User.DisplayName, + Scope = $"Document Template '{template.Id}' Attachment Matches User", + IsError = false, + }); + } + break; + default: + throw new NotSupportedException(); + } + + if (results.Count == 0) + { + if (threshold.HasValue) + { + results.Add(new BulkGenerateUserModel() + { + Id = template.Id, + DisplayName = template.Id, + Scope = $"Document Template has no attachments with associated users after {threshold:yyyy-MM-dd}", + IsError = true, + }); + } + else + { + results.Add(new BulkGenerateUserModel() + { + Id = template.Id, + DisplayName = template.Id, + Scope = $"Document Template has no attachments with associated users", + IsError = true, + }); + } + } + else + { + var distinctSet = new HashSet(StringComparer.Ordinal); + results = results.Where(r => distinctSet.Add(r.Id)).ToList(); + } + } + + return Json(results); + } + + public virtual ActionResult Generate(string id, string TargetId) + { + Disco.Services.DocumentTemplateExtensions.GetTemplateAndTarget(Database, Authorization, id, TargetId, out var template, out var target, out _); // generate document var timestamp = DateTime.Now; diff --git a/Disco.Web/Areas/API/Models/DocumentTemplate/BulkGenerateUserModel.cs b/Disco.Web/Areas/API/Models/DocumentTemplate/BulkGenerateUserModel.cs new file mode 100644 index 00000000..e00d5526 --- /dev/null +++ b/Disco.Web/Areas/API/Models/DocumentTemplate/BulkGenerateUserModel.cs @@ -0,0 +1,10 @@ +namespace Disco.Web.Areas.API.Models.DocumentTemplate +{ + public class BulkGenerateUserModel + { + public string Id { get; set; } + public string DisplayName { get; set; } + public string Scope { get; set; } + public bool IsError { get; set; } + } +} \ No newline at end of file diff --git a/Disco.Web/Areas/Config/Controllers/DocumentTemplateController.cs b/Disco.Web/Areas/Config/Controllers/DocumentTemplateController.cs index 960dd320..4c172110 100644 --- a/Disco.Web/Areas/Config/Controllers/DocumentTemplateController.cs +++ b/Disco.Web/Areas/Config/Controllers/DocumentTemplateController.cs @@ -8,6 +8,8 @@ using Disco.Services.Documents.ManagedGroups; using Disco.Services.Expressions; using Disco.Services.Plugins.Features.UIExtension; using Disco.Services.Web; +using Disco.Web.Areas.Config.Models.DocumentTemplate; +using Disco.Web.Areas.Config.Views.DocumentTemplate; using System; using System.Collections.Generic; using System.Linq; @@ -214,6 +216,63 @@ namespace Disco.Web.Areas.Config.Controllers return View(model); } + [DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)] + public virtual ActionResult BulkGenerate(string id) + { + var m = new BulkGenerateModel() + { + DocumentTemplate = Database.DocumentTemplates.FirstOrDefault(at => at.Id == id), + }; + if (m.DocumentTemplate == null) + throw new ArgumentException("Invalid Document Template Id", nameof(id)); + + if (m.DocumentTemplate.Scope != DocumentTemplate.DocumentTemplateScopes.User) + throw new NotSupportedException("Only user-scoped document templates can be bulk generated using this method"); + + m.TemplatePageCount = m.DocumentTemplate.PdfPageHasAttachmentId(Database).Count; + m.UserFlags = Database.UserFlags.Select(f => new BulkGenerateModel.ItemWithCount() + { + Item = f, + Count = f.UserFlagAssignments.Where(a => a.RemovedDate == null).Count(), + }).ToList(); + m.DeviceProfiles = Database.DeviceProfiles.Select(p => new BulkGenerateModel.ItemWithCount() + { + Item = p, + Count = p.Devices.Where(d => d.AssignedUserId != null).Count(), + }).ToList(); + m.DeviceBatches = Database.DeviceBatches.Select(p => new BulkGenerateModel.ItemWithCount() + { + Item = p, + Count = p.Devices.Where(d => d.AssignedUserId != null).Count(), + }).ToList(); + m.DocumentTemplates = Database.DocumentTemplates.Select(dt => new BulkGenerateModel.ItemWithCount() + { + Item = dt, + }).ToList(); + foreach (var record in m.DocumentTemplates) + { + switch (record.Item.AttachmentType) + { + case AttachmentTypes.Device: + record.Count = Database.DeviceAttachments.Where(a => a.DocumentTemplateId == record.Item.Id).Select(a => a.Device.AssignedUser).Distinct().Count(); + break; + case AttachmentTypes.Job: + record.Count = Database.JobAttachments.Where(a => a.DocumentTemplateId == record.Item.Id).Select(a => a.Job.User).Distinct().Count(); + break; + case AttachmentTypes.User: + record.Count = Database.UserAttachments.Where(a => a.DocumentTemplateId == record.Item.Id).Select(a => a.User).Distinct().Count(); + break; + default: + throw new NotSupportedException(); + } + } + + // UI Extensions + UIExtensions.ExecuteExtensions(ControllerContext, m); + + return View(MVC.Config.DocumentTemplate.Views.BulkGenerate, m); + } + [DiscoAuthorize(Claims.Config.Show)] public virtual ActionResult ExpressionBrowser(string type, bool StaticDeclaredMembersOnly = false) { diff --git a/Disco.Web/Areas/Config/Models/DocumentTemplate/BulkGenerateModel.cs b/Disco.Web/Areas/Config/Models/DocumentTemplate/BulkGenerateModel.cs new file mode 100644 index 00000000..63aedbca --- /dev/null +++ b/Disco.Web/Areas/Config/Models/DocumentTemplate/BulkGenerateModel.cs @@ -0,0 +1,21 @@ +using Disco.Models.UI.Config.DocumentTemplate; +using System.Collections.Generic; + +namespace Disco.Web.Areas.Config.Models.DocumentTemplate +{ + public class BulkGenerateModel : ConfigDocumentTemplateBulkGenerate + { + public Disco.Models.Repository.DocumentTemplate DocumentTemplate { get; set; } + public int TemplatePageCount { get; set; } + public List> UserFlags { get; set; } + public List> DeviceProfiles { get; set; } + public List> DeviceBatches { get; set; } + public List> DocumentTemplates { get; set; } + + public class ItemWithCount + { + public T Item { get; set; } + public int Count { get; set; } + } + } +} \ No newline at end of file diff --git a/Disco.Web/Areas/Config/Views/DocumentTemplate/BulkGenerate.cshtml b/Disco.Web/Areas/Config/Views/DocumentTemplate/BulkGenerate.cshtml new file mode 100644 index 00000000..14a79f10 --- /dev/null +++ b/Disco.Web/Areas/Config/Views/DocumentTemplate/BulkGenerate.cshtml @@ -0,0 +1,209 @@ +@model Disco.Web.Areas.Config.Models.DocumentTemplate.BulkGenerateModel +@using Disco.Services.Interop.ActiveDirectory; +@{ + Authorization.RequireAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments); + + ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Document Templates", MVC.Config.DocumentTemplate.Index(null), Model.DocumentTemplate.Description, MVC.Config.DocumentTemplate.Index(Model.DocumentTemplate.Id), "Bulk Generate"); + Html.BundleDeferred("~/ClientScripts/Modules/Disco-DocumentBulkGenerate"); +} +
+
+ @using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerate(Model.DocumentTemplate.Id), FormMethod.Post)) + { + if (Model.TemplatePageCount > 1 && Model.TemplatePageCount % 2 != 0) + { + + } + + + @Html.AntiForgeryToken() + } +
+ + + @if (Model.UserFlags.Any(f => f.Count > 0)) + { + + } + @if (Model.DeviceProfiles.Any(b => b.Count > 0)) + { + + } + @if (Model.DeviceBatches.Any(b => b.Count > 0)) + { + + } + @if (Model.DocumentTemplates.Any(b => b.Count > 0)) + { + + } +
+ + + + + + + + + + + + + + +
 UsernameNameScope
Add Users
+
+ +
+
+
+ Enter multiple User Ids separated by <new line>, commas (,) or semicolons (;). +
+
+ Security Groups can also be included. Members will be resolved and added. +
+
+

Examples:

+
+ user6
+ smi0099
+ @(ActiveDirectory.Context.PrimaryDomain.NetBiosName)\rsmith
+ Domain Admins +
+
user6,smi0099,@(ActiveDirectory.Context.PrimaryDomain.NetBiosName)\rsmith,Domain Admins
+
user6;smi0099;@(ActiveDirectory.Context.PrimaryDomain.NetBiosName)\rsmith;Domain Admins
+
+
+ @using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddUsers(), FormMethod.Post)) + { +
+ + @Html.AntiForgeryToken() + } +
+ +
+
+
+ Add all members of a group (including recursive members) to the bulk generation. +
+
+ @using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddGroupMembers(), FormMethod.Post)) + { + + + + + + + +
+ + + +
+ @Html.AntiForgeryToken() + } +
+ +@if (Model.UserFlags.Any(f => f.Count > 0)) +{ +
+
+
+ Add all users associated with the flag to the bulk generation. +
+
+ @using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddUserFlag(), FormMethod.Post)) + { + +
+ @foreach (var flag in Model.UserFlags) + { +
+ @flag.Item.Name (@flag.Count.ToString("N0") user@(flag.Count == 1 ? null : "s")) +
+ + } +
+ @Html.AntiForgeryToken() + } +
+} + +@if (Model.DeviceProfiles.Any(b => b.Count > 0)) +{ +
+
+
+ Add all users associated with a device in the selected profile to the bulk generation. +
+
+ @using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddDeviceProfile(), FormMethod.Post)) + { + +
+ @foreach (var profile in Model.DeviceProfiles) + { +
+ @profile.Item.Name (@profile.Count.ToString("N0") user@(profile.Count == 1 ? null : "s")) +
+ } +
+ @Html.AntiForgeryToken() + } +
+} + +@if (Model.DeviceBatches.Any(b => b.Count > 0)) +{ +
+
+
+ Add all users associated with a device in the selected batch to the bulk generation. +
+
+ @using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddDeviceBatch(), FormMethod.Post)) + { + +
+ @foreach (var batch in Model.DeviceBatches) + { +
+ @batch.Item.Name (@batch.Count.ToString("N0") user@(batch.Count == 1 ? null : "s")) +
+ } +
+ @Html.AntiForgeryToken() + } +
+} + +@if (Model.DocumentTemplates.Any(b => b.Count > 0)) +{ +
+
+
+ Add all users associated with an attachment of the selected document template to the bulk generation. +
+
+ @using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddDocumentAttachment(), FormMethod.Post)) + { + +
+ @foreach (var template in Model.DocumentTemplates) + { +
+ @template.Item.Id: @template.Item.Description (@template.Count.ToString("N0") user@(template.Count == 1 ? null : "s")) +
+ } +
+
+ + +
+ @Html.AntiForgeryToken() + } +
+} diff --git a/Disco.Web/Areas/Config/Views/DocumentTemplate/BulkGenerate.generated.cs b/Disco.Web/Areas/Config/Views/DocumentTemplate/BulkGenerate.generated.cs new file mode 100644 index 00000000..95866272 --- /dev/null +++ b/Disco.Web/Areas/Config/Views/DocumentTemplate/BulkGenerate.generated.cs @@ -0,0 +1,1281 @@ +#pragma warning disable 1591 +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Disco.Web.Areas.Config.Views.DocumentTemplate +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using System.Web; + using System.Web.Helpers; + using System.Web.Mvc; + using System.Web.Mvc.Ajax; + using System.Web.Mvc.Html; + using System.Web.Routing; + using System.Web.Security; + using System.Web.UI; + using System.Web.WebPages; + using Disco; + using Disco.Models.Repository; + using Disco.Services; + using Disco.Services.Authorization; + + #line 2 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + using Disco.Services.Interop.ActiveDirectory; + + #line default + #line hidden + using Disco.Services.Web; + using Disco.Web; + using Disco.Web.Extensions; + + [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")] + [System.Web.WebPages.PageVirtualPathAttribute("~/Areas/Config/Views/DocumentTemplate/BulkGenerate.cshtml")] + public partial class BulkGenerate : Disco.Services.Web.WebViewPage + { + public BulkGenerate() + { + } + public override void Execute() + { + + #line 3 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + Authorization.RequireAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments); + + ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Document Templates", MVC.Config.DocumentTemplate.Index(null), Model.DocumentTemplate.Description, MVC.Config.DocumentTemplate.Index(Model.DocumentTemplate.Id), "Bulk Generate"); + Html.BundleDeferred("~/ClientScripts/Modules/Disco-DocumentBulkGenerate"); + + + #line default + #line hidden +WriteLiteral("\r\n\r\n \r\n"); + + + #line 11 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + + #line default + #line hidden + + #line 11 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerate(Model.DocumentTemplate.Id), FormMethod.Post)) + { + if (Model.TemplatePageCount > 1 && Model.TemplatePageCount % 2 != 0) + { + + + #line default + #line hidden +WriteLiteral(" "); + +WriteLiteral("Insert Blank Pages for Double-Sided Printing\r\n"); + + + #line 16 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" Bulk Generate\r\n"); + + + #line 19 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + + #line default + #line hidden + + #line 19 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + Write(Html.AntiForgeryToken()); + + + #line default + #line hidden + + #line 19 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + } + + + #line default + #line hidden +WriteLiteral("
\r\n Add Users\r\n Add Group Members\r\n"); + + + #line 24 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + + #line default + #line hidden + + #line 24 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + if (Model.UserFlags.Any(f => f.Count > 0)) + { + + + #line default + #line hidden +WriteLiteral(" Add With User Flag\r\n"); + + + #line 27 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 28 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + if (Model.DeviceProfiles.Any(b => b.Count > 0)) + { + + + #line default + #line hidden +WriteLiteral(" Add With Device Profile\r\n"); + + + #line 31 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 32 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + if (Model.DeviceBatches.Any(b => b.Count > 0)) + { + + + #line default + #line hidden +WriteLiteral(" Add With Device Batch\r\n"); + + + #line 35 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 36 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + if (Model.DocumentTemplates.Any(b => b.Count > 0)) + { + + + #line default + #line hidden +WriteLiteral(" Add With Document Attachment\r\n"); + + + #line 39 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n \r\n \r\n  \r\n " + +" Username\r\n Name\r\n Scop" + +"e\r\n \r\n \r\n \r\n \r\n Add Users\r\n \r\n \r\n \r\n\r\n\r\n(Model.DocumentTemplate.Description + + #line default + #line hidden +, 2757), false) +, Tuple.Create(Tuple.Create("", 2794), Tuple.Create(":", 2794), true) +, Tuple.Create(Tuple.Create(" ", 2795), Tuple.Create("Add", 2796), true) +, Tuple.Create(Tuple.Create(" ", 2799), Tuple.Create("Users", 2800), true) +); + +WriteLiteral(">\r\n \r\n
\r\n Enter multiple User Ids separated by <new line>, commas (,) or semicolons (;). +
+
+ Security Groups can also be included. Members will be resolved and added. +
+ \r\n

Examples:

\r\n \r\n user6
\r\n smi0099
\r\n"); + +WriteLiteral(" "); + + + #line 71 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); + + + #line default + #line hidden +WriteLiteral("\\rsmith
\r\n Domain Admins\r\n \r\n user6,smi0099,"); + + + #line 74 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); + + + #line default + #line hidden +WriteLiteral("\\rsmith,Domain Admins\r\n user6;smi0099;"); + + + #line 75 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); + + + #line default + #line hidden +WriteLiteral("\\rsmith;Domain Admins\r\n \r\n \r\n"); + + + #line 78 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + + #line default + #line hidden + + #line 78 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddUsers(), FormMethod.Post)) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" \r\n"); + + + #line 82 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + + #line default + #line hidden + + #line 82 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + Write(Html.AntiForgeryToken()); + + + #line default + #line hidden + + #line 82 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + } + + + #line default + #line hidden +WriteLiteral("\r\n\r\n(Model.DocumentTemplate.Description + + #line default + #line hidden +, 4277), false) +, Tuple.Create(Tuple.Create("", 4314), Tuple.Create(":", 4314), true) +, Tuple.Create(Tuple.Create(" ", 4315), Tuple.Create("Add", 4316), true) +, Tuple.Create(Tuple.Create(" ", 4319), Tuple.Create("Group", 4320), true) +, Tuple.Create(Tuple.Create(" ", 4325), Tuple.Create("Members", 4326), true) +); + +WriteLiteral(">\r\n \r\n
\r\n Add all members of a group (including recursive mem" + +"bers) to the bulk generation.\r\n
\r\n \r\n"); + + + #line 92 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + + + #line default + #line hidden + + #line 92 "..\..\Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml" + using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddGroupMembers(), FormMethod.Post)) + { + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n \r\n \r\n " + +" Group:\r\n \r\n \r\n " + +"