Skip to content

Commit c187fbb

Browse files
committed
Introduced interface for all tool specific properties and methods #12
1 parent 378c6e7 commit c187fbb

File tree

10 files changed

+262
-212
lines changed

10 files changed

+262
-212
lines changed

CAPIT/CAPIT.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@
162162
</ItemGroup>
163163
<ItemGroup>
164164
<Compile Include="CAPITPlugin.cs" />
165+
<Compile Include="CAPITTool.cs" />
165166
<Compile Include="Properties\AssemblyInfo.cs" />
166167
</ItemGroup>
167168
<ItemGroup>

CAPIT/CAPITPlugin.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Reflection;
77
using XrmToolBox.Extensibility;
88
using XrmToolBox.Extensibility.Interfaces;
9+
using Rappen.XTB.CAPIT;
910

1011
namespace Rappen.XTB.CAT
1112
{
@@ -25,7 +26,7 @@ public class CAPITPlugin : PluginBase
2526
{
2627
public override IXrmToolBoxPluginControl GetControl()
2728
{
28-
return new CustomActionTester(Tool.CAPIT);
29+
return new CustomActionTester(new CAPITTool());
2930
}
3031

3132
/// <summary>

CAPIT/CAPITTool.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using Microsoft.Xrm.Sdk;
2+
using Microsoft.Xrm.Sdk.Query;
3+
using Rappen.XTB.CAT;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
8+
namespace Rappen.XTB.CAPIT
9+
{
10+
class CAPITTool : ICATTool
11+
{
12+
public string Name => $"{Target} Tester";
13+
14+
public string Target => "Custom API";
15+
16+
public string MessageIdentifierColumn => Customapi.UniqueName;
17+
18+
public string ParameterIdentifierColumn => Customapirequestparameter.UniqueName;
19+
20+
public QueryExpression GetActionQuery(Guid solutionid)
21+
{
22+
var qx = new QueryExpression(Customapi.EntityName);
23+
qx.ColumnSet.AddColumns(
24+
Customapi.UniqueName,
25+
Customapi.PrimaryName,
26+
Customapi.DisplayName,
27+
Customapi.Description,
28+
Customapi.CreatedBy,
29+
Customapi.Isfunction,
30+
Customapi.IsPrivate,
31+
Customapi.ExecuteprivilegeName,
32+
Customapi.AllowedcustomProcessingStepType,
33+
Customapi.BoundEntityLogicalName,
34+
Customapi.BindingType);
35+
qx.AddOrder(Customapi.PrimaryName, OrderType.Ascending);
36+
if (!solutionid.Equals(Guid.Empty))
37+
{
38+
var solcomp = qx.AddLink(Solutioncomponent.EntityName, Customapi.PrimaryKey, Solutioncomponent.ObjectId);
39+
solcomp.LinkCriteria.AddCondition(Solutioncomponent.SolutionId, ConditionOperator.Equal, solutionid);
40+
}
41+
return qx;
42+
}
43+
44+
public QueryExpression GetInputQuery(Guid actionid)
45+
{
46+
var qx = new QueryExpression(Customapirequestparameter.EntityName);
47+
qx.ColumnSet.AddColumns(
48+
Customapirequestparameter.UniqueName,
49+
Customapirequestparameter.PrimaryName,
50+
Customapirequestparameter.DisplayName,
51+
Customapirequestparameter.Description,
52+
Customapirequestparameter.Isoptional,
53+
Customapirequestparameter.Type,
54+
Customapirequestparameter.LogicalEntityName);
55+
qx.AddOrder(Customapirequestparameter.Isoptional, OrderType.Ascending);
56+
qx.AddOrder(Customapirequestparameter.PrimaryName, OrderType.Ascending);
57+
qx.Criteria.AddCondition(Customapirequestparameter.CustomapiId, ConditionOperator.Equal, actionid);
58+
return qx;
59+
}
60+
61+
public QueryExpression GetOutputQuery(Guid actionid)
62+
{
63+
var qx = new QueryExpression(Customapiresponseproperty.EntityName);
64+
qx.ColumnSet.AddColumns(
65+
Customapiresponseproperty.UniqueName,
66+
Customapiresponseproperty.PrimaryName,
67+
Customapiresponseproperty.DisplayName,
68+
Customapiresponseproperty.Description,
69+
Customapiresponseproperty.Type,
70+
Customapiresponseproperty.LogicalEntityName);
71+
qx.AddOrder(Customapiresponseproperty.PrimaryName, OrderType.Ascending);
72+
qx.Criteria.AddCondition(Customapirequestparameter.CustomapiId, ConditionOperator.Equal, actionid);
73+
return qx;
74+
}
75+
76+
public void PreProcessParams(EntityCollection records, IEnumerable<EntityMetadataProxy> entities)
77+
{
78+
records.Entities.Where(e => e.Contains(Customapiresponseproperty.LogicalEntityName)).ToList().ForEach(e => e["entity"] =
79+
entities.FirstOrDefault(em => em.Metadata.LogicalName == e[Customapiresponseproperty.LogicalEntityName].ToString()));
80+
}
81+
}
82+
}

CAT/CAT.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
</Reference>
162162
</ItemGroup>
163163
<ItemGroup>
164+
<Compile Include="CATTool.cs" />
164165
<Compile Include="CATPlugin.cs" />
165166
<Compile Include="Properties\AssemblyInfo.cs" />
166167
</ItemGroup>

CAT/CATPlugin.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class CATPlugin : PluginBase
2525
{
2626
public override IXrmToolBoxPluginControl GetControl()
2727
{
28-
return new CustomActionTester(Tool.CAT);
28+
return new CustomActionTester(new CATTool());
2929
}
3030

3131
/// <summary>

CAT/CATTool.cs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using Microsoft.Xrm.Sdk;
2+
using Microsoft.Xrm.Sdk.Query;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
7+
namespace Rappen.XTB.CAT
8+
{
9+
class CATTool : ICATTool
10+
{
11+
public string Name => $"{Target} Tester";
12+
13+
public string Target => "Custom Action";
14+
15+
public string MessageIdentifierColumn => "M.name";
16+
17+
public string ParameterIdentifierColumn => "name";
18+
19+
public QueryExpression GetActionQuery(Guid solutionid)
20+
{
21+
var qx = new QueryExpression("workflow");
22+
qx.ColumnSet.AddColumns("name", "uniquename", "createdby", "primaryentity", "scope", "mode", "ismanaged", "iscustomizable", "istransacted", "iscustomprocessingstepallowedforotherpublishers", "inputparameters", "description");
23+
qx.AddOrder("ismanaged", OrderType.Descending);
24+
qx.AddOrder("name", OrderType.Ascending);
25+
qx.Criteria.AddCondition("category", ConditionOperator.Equal, 3);
26+
qx.Criteria.AddCondition("type", ConditionOperator.Equal, 1);
27+
qx.Criteria.AddCondition("componentstate", ConditionOperator.Equal, 0);
28+
qx.Criteria.AddCondition("statuscode", ConditionOperator.Equal, 2);
29+
var qxsdk = qx.AddLink("sdkmessage", "sdkmessageid", "sdkmessageid", JoinOperator.LeftOuter);
30+
qxsdk.EntityAlias = "M";
31+
qxsdk.Columns.AddColumns("name", "workflowsdkstepenabled");
32+
if (!solutionid.Equals(Guid.Empty))
33+
{
34+
var solcomp = qx.AddLink("solutioncomponent", "workflowid", "objectid");
35+
solcomp.LinkCriteria.AddCondition("solutionid", ConditionOperator.Equal, solutionid);
36+
}
37+
return qx;
38+
}
39+
40+
public QueryExpression GetInputQuery(Guid actionid)
41+
{
42+
var qx = new QueryExpression("sdkmessagerequestfield");
43+
qx.Distinct = true;
44+
qx.ColumnSet.AddColumns("name", "position", "parameterbindinginformation", "optional", "parser", "fieldmask");
45+
qx.AddOrder("position", OrderType.Ascending);
46+
var req = qx.AddLink("sdkmessagerequest", "sdkmessagerequestid", "sdkmessagerequestid");
47+
var pair = req.AddLink("sdkmessagepair", "sdkmessagepairid", "sdkmessagepairid");
48+
var msg = pair.AddLink("sdkmessage", "sdkmessageid", "sdkmessageid");
49+
var wf = msg.AddLink("workflow", "sdkmessageid", "sdkmessageid");
50+
wf.LinkCriteria.AddCondition("workflowid", ConditionOperator.Equal, actionid);
51+
return qx;
52+
}
53+
54+
public QueryExpression GetOutputQuery(Guid actionid)
55+
{
56+
var qx = new QueryExpression("sdkmessageresponsefield");
57+
qx.Distinct = true;
58+
qx.ColumnSet.AddColumns("name", "position", "parameterbindinginformation", "formatter", "publicname");
59+
qx.AddOrder("position", OrderType.Ascending);
60+
var resp = qx.AddLink("sdkmessageresponse", "sdkmessageresponseid", "sdkmessageresponseid");
61+
var req = resp.AddLink("sdkmessagerequest", "sdkmessagerequestid", "sdkmessagerequestid");
62+
var pair = req.AddLink("sdkmessagepair", "sdkmessagepairid", "sdkmessagepairid");
63+
var msg = pair.AddLink("sdkmessage", "sdkmessageid", "sdkmessageid");
64+
var wf = msg.AddLink("workflow", "sdkmessageid", "sdkmessageid");
65+
wf.LinkCriteria.AddCondition("workflowid", ConditionOperator.Equal, actionid);
66+
return qx;
67+
}
68+
69+
public void PreProcessParams(EntityCollection records, IEnumerable<EntityMetadataProxy> entities)
70+
{
71+
foreach (var record in records.Entities.Where(e => !e.Contains("type")))
72+
{
73+
var attribute = record.Contains("parser") ? "parser" : "formatter";
74+
if (record.TryGetAttributeValue(attribute, out string parser))
75+
{
76+
parser = parser.Split(',')[0];
77+
while (parser.Contains("."))
78+
{
79+
parser = parser.Substring(parser.IndexOf('.') + 1);
80+
}
81+
record["type"] = parser;
82+
}
83+
}
84+
var otcrecords = records.Entities.Where(r => r.Contains("parameterbindinginformation"));
85+
if (otcrecords.Count() > 0)
86+
{
87+
var siblingrecords = new List<Entity>();
88+
foreach (var otcrecord in otcrecords)
89+
{
90+
var siblingrecord = records.Entities.FirstOrDefault(r => r["name"].ToString() == otcrecord["name"].ToString() && !r.Contains("parameterbindinginformation"));
91+
if (siblingrecord == null)
92+
{
93+
continue;
94+
}
95+
var binding = otcrecord["parameterbindinginformation"].ToString();
96+
var otcstr = binding.Replace("OTC:", "").Trim();
97+
if (int.TryParse(otcstr, out int otc))
98+
{
99+
if (entities.FirstOrDefault(e => e.Metadata.ObjectTypeCode == otc) is EntityMetadataProxy meta)
100+
{
101+
otcrecord["entity"] = meta;
102+
}
103+
}
104+
siblingrecords.Add(siblingrecord);
105+
}
106+
siblingrecords.ForEach(s => records.Entities.Remove(s));
107+
}
108+
records.Entities.Where(e => !e.Contains("isoptional") && e.Contains("optional")).ToList().ForEach(e => e["isoptional"] = e["optional"]);
109+
}
110+
}
111+
}

CustomActionTester/CAT.Common.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
</Compile>
190190
<Compile Include="CustomAPI.Const.cs" />
191191
<Compile Include="EntityMetadataProxy.cs" />
192+
<Compile Include="ICATTool.cs" />
192193
<Compile Include="InputValue.cs">
193194
<SubType>Form</SubType>
194195
</Compile>

CustomActionTester/CAT.cs

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using McTools.Xrm.Connection;
22
using Microsoft.Xrm.Sdk;
33
using System;
4-
using System.Collections.Generic;
54
using System.Diagnostics;
65
using System.Reflection;
76
using System.Windows.Forms;
@@ -10,54 +9,33 @@
109

1110
namespace Rappen.XTB.CAT
1211
{
13-
public enum Tool
14-
{
15-
CAT,
16-
CAPIT
17-
}
18-
1912
public partial class CustomActionTester : PluginControlBase
2013
{
2114
#region Private Fields
2215

23-
private Tool tool;
16+
ICATTool catTool;
2417
private const string aiEndpoint = "https://dc.services.visualstudio.com/v2/track";
2518
private const string aiKey = "eed73022-2444-45fd-928b-5eebd8fa46a6"; // [email protected] tenant, XrmToolBox
2619
private AppInsights ai;
2720
private InputValue inputdlg;
28-
private static Dictionary<Tool, string> scopes = new Dictionary<Tool, string>()
29-
{
30-
[Tool.CAT] = "Custom Action",
31-
[Tool.CAPIT] = "Custom API"
32-
};
33-
private string scope => scopes[tool];
34-
private string toolname => scope + " Tester";
3521

3622
#endregion Private Fields
3723

3824
#region Public Constructors
3925

40-
public CustomActionTester(Tool tool)
26+
public CustomActionTester(ICATTool catinstance)
4127
{
42-
this.tool = tool;
43-
ai = new AppInsights(aiEndpoint, aiKey, Assembly.GetExecutingAssembly(), toolname);
28+
catTool = catinstance;
29+
ai = new AppInsights(aiEndpoint, aiKey, Assembly.GetExecutingAssembly(), catTool.Name);
4430
InitializeComponent();
4531
FixFormForTool();
4632
}
4733

4834
private void FixFormForTool()
4935
{
50-
gbCustomWhat.Text = scope;
51-
lblCustomWhat.Text = scope;
52-
switch (tool)
53-
{
54-
case Tool.CAT:
55-
txtMessageName.DisplayFormat = "M.name";
56-
break;
57-
case Tool.CAPIT:
58-
txtMessageName.DisplayFormat = "uniquename";
59-
break;
60-
}
36+
gbCustomWhat.Text = catTool.Target;
37+
lblCustomWhat.Text = catTool.Target;
38+
txtMessageName.DisplayFormat = catTool.MessageIdentifierColumn;
6139
}
6240

6341
#endregion Public Constructors

0 commit comments

Comments
 (0)