feature: expose custom details to expressions
custom details can now be easily retrieved from any expression
This commit is contained in:
@@ -218,7 +218,7 @@ namespace Disco.BI.Interop.Pdf
|
||||
pdfStamper.FormFlattening = FlattenFields;
|
||||
pdfStamper.Writer.CloseStream = false;
|
||||
|
||||
IDictionary expressionVariables = Expression.StandardVariables(dt, Database, CreatorUser, TimeStamp, State);
|
||||
IDictionary expressionVariables = Expression.StandardVariables(dt, Database, CreatorUser, TimeStamp, State, Data);
|
||||
|
||||
foreach (string pdfFieldKey in pdfStamper.AcroFields.Fields.Keys)
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Disco.Services
|
||||
//return Expressions.Expression.TokenizeSingleDynamic(null, deviceProfile.Configuration(context).ComputerNameTemplate, 0);
|
||||
return Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0);
|
||||
});
|
||||
var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null);
|
||||
var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null, device);
|
||||
string rendered;
|
||||
try
|
||||
{
|
||||
|
||||
@@ -235,7 +235,7 @@ namespace Disco.Services.Documents.AttachmentImport
|
||||
{
|
||||
try
|
||||
{
|
||||
var expressionResult = Identifier.DocumentTemplate.EvaluateOnAttachmentImportExpression(attachment, Database, creatorUser, Identifier.TimeStamp, PageIdentifiers);
|
||||
var expressionResult = Identifier.DocumentTemplate.EvaluateOnAttachmentImportExpression(attachment, Identifier.Target, Database, creatorUser, Identifier.TimeStamp, PageIdentifiers);
|
||||
DocumentsLog.LogImportAttachmentExpressionEvaluated(Identifier.DocumentTemplate, Identifier.Target, attachment, expressionResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -22,12 +22,12 @@ namespace Disco.Services
|
||||
ExpressionCache.InvalidateKey("DocumentTemplate_FilterExpression", dt.Id);
|
||||
}
|
||||
|
||||
public static bool FilterExpressionMatches(this DocumentTemplate dt, object Data, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState State)
|
||||
public static bool FilterExpressionMatches(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState State)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(dt.FilterExpression))
|
||||
{
|
||||
var compiledExpression = dt.FilterExpressionFromCache();
|
||||
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State);
|
||||
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State, Data);
|
||||
try
|
||||
{
|
||||
var er = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
|
||||
@@ -59,12 +59,12 @@ namespace Disco.Services
|
||||
ExpressionCache.InvalidateKey("DocumentTemplate_OnImportExpression", dt.Id);
|
||||
}
|
||||
|
||||
public static string EvaluateOnAttachmentImportExpression(this DocumentTemplate dt, IAttachment Data, DiscoDataContext Database, User User, DateTime TimeStamp, List<DocumentUniqueIdentifier> PageIdentifiers)
|
||||
public static string EvaluateOnAttachmentImportExpression(this DocumentTemplate dt, IAttachment Data, IAttachmentTarget AttachmentTarget, DiscoDataContext Database, User User, DateTime TimeStamp, List<DocumentUniqueIdentifier> PageIdentifiers)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(dt.OnImportAttachmentExpression))
|
||||
{
|
||||
var compiledExpression = dt.OnImportAttachmentExpressionFromCache();
|
||||
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, null);
|
||||
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, null, AttachmentTarget);
|
||||
evaluatorVariables.Add("PageIdentifiers", PageIdentifiers);
|
||||
var result = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
|
||||
if (result == null)
|
||||
@@ -85,12 +85,12 @@ namespace Disco.Services
|
||||
ExpressionCache.InvalidateKey("DocumentTemplate_OnGenerateExpression", dt.Id);
|
||||
}
|
||||
|
||||
public static string EvaluateOnGenerateExpression(this DocumentTemplate dt, object Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
|
||||
public static string EvaluateOnGenerateExpression(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(dt.OnGenerateExpression))
|
||||
{
|
||||
var compiledExpression = dt.OnGenerateExpressionFromCache();
|
||||
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State);
|
||||
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State, Data);
|
||||
|
||||
var result = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
|
||||
return result.ToString();
|
||||
|
||||
@@ -81,12 +81,12 @@ namespace Disco.Services
|
||||
ExpressionCache.InvalidateKey("DocumentTemplatePackage_FilterExpression", package.Id);
|
||||
}
|
||||
|
||||
public static bool FilterExpressionMatches(this DocumentTemplatePackage package, object Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
|
||||
public static bool FilterExpressionMatches(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(package.FilterExpression))
|
||||
{
|
||||
var compiledExpression = package.FilterExpressionFromCache();
|
||||
var evaluatorVariables = Expression.StandardVariables(null, Database, User, TimeStamp, State);
|
||||
var evaluatorVariables = Expression.StandardVariables(null, Database, User, TimeStamp, State, Data);
|
||||
evaluatorVariables.Add("Package", package);
|
||||
try
|
||||
{
|
||||
@@ -119,12 +119,12 @@ namespace Disco.Services
|
||||
ExpressionCache.InvalidateKey("DocumentTemplatePackage_OnGenerateExpression", package.Id);
|
||||
}
|
||||
|
||||
public static string EvaluateOnGenerateExpression(this DocumentTemplatePackage package, object Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
|
||||
public static string EvaluateOnGenerateExpression(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(package.OnGenerateExpression))
|
||||
{
|
||||
Expression compiledExpression = package.OnGenerateExpressionFromCache();
|
||||
System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, User, TimeStamp, State);
|
||||
System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, User, TimeStamp, State, Data);
|
||||
evaluatorVariables.Add("Package", package);
|
||||
try
|
||||
{
|
||||
|
||||
@@ -2,11 +2,13 @@ using Disco.Data.Repository;
|
||||
using Disco.Models.BI.Expressions;
|
||||
using Disco.Models.Repository;
|
||||
using Disco.Models.Services.Documents;
|
||||
using Disco.Services.Plugins.Features.DetailsProvider;
|
||||
using Spring.Core.TypeResolution;
|
||||
using Spring.Expressions;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Disco.Services.Expressions
|
||||
@@ -173,11 +175,31 @@ namespace Disco.Services.Expressions
|
||||
return e;
|
||||
}
|
||||
|
||||
public static IDictionary StandardVariables(DocumentTemplate AttachmentType, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState DocumentState)
|
||||
public static IDictionary StandardVariables(DocumentTemplate AttachmentType, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState DocumentState, IAttachmentTarget target = null)
|
||||
{
|
||||
return new Hashtable
|
||||
var detailsVariables = new Dictionary<string, object>();
|
||||
var detailsService = new DetailsProviderService(Database);
|
||||
if (target != null)
|
||||
{
|
||||
if (target is User targetUser)
|
||||
{
|
||||
detailsVariables.Add("UserDetails", new LazyDictionary(() => detailsService.GetDetails(targetUser).Details));
|
||||
detailsVariables.Add("AssignedDeviceDetails", targetUser.CurrentDeviceUserAssignments().Select(a => new { a.Device, Details = new LazyDictionary(() => detailsService.GetDetails(targetUser).Details) }).ToDictionary(d => d.Device.SerialNumber, d => d.Details, StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
else if (target is Job targetJob)
|
||||
{
|
||||
detailsVariables.Add("UserDetails", targetJob.User == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetJob.User).Details));
|
||||
detailsVariables.Add("DeviceDetails", targetJob.Device == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetJob.Device).Details));
|
||||
}
|
||||
else if (target is Device targetDevice)
|
||||
{
|
||||
detailsVariables.Add("DeviceDetails", new LazyDictionary(() => detailsService.GetDetails(targetDevice).Details));
|
||||
detailsVariables.Add("UserDetails", targetDevice.AssignedUser == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetDevice.AssignedUser).Details));
|
||||
}
|
||||
}
|
||||
|
||||
return new Hashtable(detailsVariables)
|
||||
{
|
||||
{
|
||||
"DataContext",
|
||||
Database
|
||||
@@ -232,7 +254,22 @@ namespace Disco.Services.Expressions
|
||||
{
|
||||
"#State",
|
||||
typeof(DocumentState).AssemblyQualifiedName
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"#UserDetails",
|
||||
typeof(Dictionary<string, string>).AssemblyQualifiedName
|
||||
},
|
||||
|
||||
{
|
||||
"#DeviceDetails",
|
||||
typeof(Dictionary<string, string>).AssemblyQualifiedName
|
||||
},
|
||||
|
||||
{
|
||||
"#AssignedDeviceDetails",
|
||||
typeof(Dictionary<string, Dictionary<string, string>>).AssemblyQualifiedName
|
||||
},
|
||||
};
|
||||
}
|
||||
public static Dictionary<string, string> ExtensionLibraryTypes()
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Disco.Services.Expressions
|
||||
{
|
||||
public class LazyDictionary : IDictionary<string, string>
|
||||
{
|
||||
private readonly Lazy<IDictionary<string, string>> dictionary;
|
||||
|
||||
public LazyDictionary(Func<IDictionary<string, string>> dictionaryFactory)
|
||||
{
|
||||
if (dictionaryFactory == null)
|
||||
throw new ArgumentNullException(nameof(dictionaryFactory));
|
||||
|
||||
dictionary = new Lazy<IDictionary<string, string>>(dictionaryFactory);
|
||||
}
|
||||
|
||||
public string this[string key]
|
||||
{
|
||||
get => dictionary.Value.TryGetValue(key, out var value) ? value : null;
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public ICollection<string> Keys => dictionary.Value.Keys;
|
||||
public ICollection<string> Values => dictionary.Value.Values;
|
||||
public int Count => dictionary.Value.Count;
|
||||
public bool IsReadOnly => true;
|
||||
|
||||
public void Add(string key, string value)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public void Add(KeyValuePair<string, string> item)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public void Clear()
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public bool Contains(KeyValuePair<string, string> item)
|
||||
=> dictionary.Value.Contains(item);
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
=> dictionary.Value.ContainsKey(key);
|
||||
|
||||
public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
|
||||
=> dictionary.Value.GetEnumerator();
|
||||
|
||||
public bool Remove(string key)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public bool Remove(KeyValuePair<string, string> item)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public bool TryGetValue(string key, out string value)
|
||||
=> dictionary.Value.TryGetValue(key, out value);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> dictionary.Value.GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -397,7 +397,7 @@ namespace Disco.Services
|
||||
if (!string.IsNullOrEmpty(Database.DiscoConfiguration.JobPreferences.OnCreateExpression))
|
||||
{
|
||||
Expression compiledExpression = Jobs.Jobs.OnCreateExpressionFromCache(Database);
|
||||
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null);
|
||||
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null, job);
|
||||
object result = compiledExpression.EvaluateFirst<object>(job, evaluatorVariables);
|
||||
if (result == null)
|
||||
return null;
|
||||
@@ -412,7 +412,7 @@ namespace Disco.Services
|
||||
if (!string.IsNullOrEmpty(Database.DiscoConfiguration.JobPreferences.OnCloseExpression))
|
||||
{
|
||||
Expression compiledExpression = Jobs.Jobs.OnCloseExpressionFromCache(Database);
|
||||
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null);
|
||||
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null, job);
|
||||
object result = compiledExpression.EvaluateFirst<object>(job, evaluatorVariables);
|
||||
if (result == null)
|
||||
return null;
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Disco.Services
|
||||
if (!string.IsNullOrEmpty(ufa.UserFlag.OnAssignmentExpression))
|
||||
{
|
||||
Expression compiledExpression = ufa.UserFlag.OnAssignmentExpressionFromCache();
|
||||
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, AddingUser, TimeStamp, null);
|
||||
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, AddingUser, TimeStamp, null, ufa.User);
|
||||
object result = compiledExpression.EvaluateFirst<object>(ufa, evaluatorVariables);
|
||||
if (result == null)
|
||||
return null;
|
||||
@@ -171,7 +171,7 @@ namespace Disco.Services
|
||||
if (!string.IsNullOrEmpty(ufa.UserFlag.OnUnassignmentExpression))
|
||||
{
|
||||
Expression compiledExpression = ufa.UserFlag.OnUnassignmentExpressionFromCache();
|
||||
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, RemovingUser, TimeStamp, null);
|
||||
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, RemovingUser, TimeStamp, null, ufa.User);
|
||||
object result = compiledExpression.EvaluateFirst<object>(ufa, evaluatorVariables);
|
||||
if (result == null)
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user