diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..f193735 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,7 @@ +{ + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\CrmCodeGenerator.sln", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..c99339b Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/CrmCodeGenerator.VSPackage/CrmCodeGenerator.VSPackage.csproj b/CrmCodeGenerator.VSPackage/CrmCodeGenerator.VSPackage.csproj index e7fcfce..9f31f4f 100644 --- a/CrmCodeGenerator.VSPackage/CrmCodeGenerator.VSPackage.csproj +++ b/CrmCodeGenerator.VSPackage/CrmCodeGenerator.VSPackage.csproj @@ -89,7 +89,7 @@ True - + @@ -325,5 +325,4 @@ --> - \ No newline at end of file diff --git a/CrmCodeGenerator.VSPackage/Mapper.cs b/CrmCodeGenerator.VSPackage/Mapper.cs index 11322df..6d3b73f 100644 --- a/CrmCodeGenerator.VSPackage/Mapper.cs +++ b/CrmCodeGenerator.VSPackage/Mapper.cs @@ -42,9 +42,11 @@ protected void OnMessage(string message, string extendedMessage = "") public Context MapContext() { + var connection = GetConnection(); var context = new Context(); - context.Entities = GetEntities(GetConnection()); + context.Entities = GetEntities(connection); SortEntities(context); + context.Enums = GetGlobalEnums(connection); return context; } @@ -93,7 +95,7 @@ public void SortEntities(Context context) internal MappingEntity[] GetEntities(IOrganizationService service) { - var entities = GetMetadataFromServer(service); + var entities = GetEntitiesMetadata(service); var selectedEntities = entities .Where(r => this.Settings.EntitiesSelected.Contains(r.LogicalName)) @@ -135,12 +137,23 @@ internal MappingEntity[] GetEntities(IOrganizationService service) return mappedEntities.ToArray(); } - private EntityMetadata[] GetMetadataFromServer(IOrganizationService service) + internal MappingEnum[] GetGlobalEnums(IOrganizationService service) + { + var enums = RetrieveGlobalOptionSetsMetadataFromServer(service); + + OnMessage(string.Format("Found {0} option sets", enums.Count())); + + var mappedEnums = enums.Select(e => MappingEnum.Parse(e)).OrderBy(e => e.DisplayName).ToList(); + + return mappedEnums.ToArray(); + } + + private EntityMetadata[] GetEntitiesMetadata(IOrganizationService service) { OnMessage("Gathering metadata, this may take a few minutes..."); if (this.Settings.EntitiesSelected.Count > 20) { - return GetAllMetadataFromServer(service); + return RetrieveEntityMetadataFromServer(service); } var entitiesToRetreive = this.Settings.EntitiesSelected.Select(x => x).ToList(); @@ -148,8 +161,6 @@ private EntityMetadata[] GetMetadataFromServer(IOrganizationService service) { entitiesToRetreive.Add("activityparty"); } - - var results = new List(); foreach (var entity in entitiesToRetreive) @@ -164,7 +175,7 @@ private EntityMetadata[] GetMetadataFromServer(IOrganizationService service) return results.ToArray(); } - private EntityMetadata[] GetAllMetadataFromServer(IOrganizationService service) + private EntityMetadata[] RetrieveEntityMetadataFromServer(IOrganizationService service) { //TODO should change this to early binding RetrieveAllEntitiesRequest OrganizationRequest request = new OrganizationRequest("RetrieveAllEntities"); @@ -176,6 +187,37 @@ private EntityMetadata[] GetAllMetadataFromServer(IOrganizationService service) var entities = results["EntityMetadata"] as EntityMetadata[]; return entities; } + private OptionSetMetadata[] RetrieveGlobalOptionSetsMetadataFromServer(IOrganizationService service) + { + var results = new List(); + // Use RetrieveAllOptionSetsRequest to retrieve all global option sets. + // Create the request. + RetrieveAllOptionSetsRequest retrieveAllOptionSetsRequest = new RetrieveAllOptionSetsRequest(); + + // Execute the request + RetrieveAllOptionSetsResponse retrieveAllOptionSetsResponse = (RetrieveAllOptionSetsResponse)service.Execute(retrieveAllOptionSetsRequest); + + //return retrieveAllOptionSetsResponse.OptionSetMetadata; + // Now you can use RetrieveAllOptionSetsResponse.OptionSetMetadata property to + // work with all retrieved option sets. + if (retrieveAllOptionSetsResponse.OptionSetMetadata.Count() > 0) + { + Console.WriteLine("All the global option sets retrieved as below:"); + foreach (OptionSetMetadataBase optionSetMetadata in retrieveAllOptionSetsResponse.OptionSetMetadata) + { + if (!optionSetMetadata.IsManaged.Value && optionSetMetadata.IsGlobal.Value) + { + RetrieveOptionSetRequest retrieveOptionSetRequest = new RetrieveOptionSetRequest { Name = optionSetMetadata.Name }; + // Execute the request. + RetrieveOptionSetResponse retrieveOptionSetResponse = (RetrieveOptionSetResponse)service.Execute(retrieveOptionSetRequest); + results.Add((OptionSetMetadata)retrieveOptionSetResponse.OptionSetMetadata); + } + } + } + + return results.ToArray(); + } + private static void ExcludeRelationshipsNotIncluded(List mappedEntities) { foreach (var ent in mappedEntities) diff --git a/CrmCodeGenerator.VSPackage/Model/Context.cs b/CrmCodeGenerator.VSPackage/Model/Context.cs index 9ad285d..89f3532 100644 --- a/CrmCodeGenerator.VSPackage/Model/Context.cs +++ b/CrmCodeGenerator.VSPackage/Model/Context.cs @@ -11,5 +11,7 @@ public class Context public string Namespace { get; set; } public MappingEntity[] Entities { get; set; } + + public MappingEnum[] Enums { get; set; } } } diff --git a/CrmCodeGenerator.VSPackage/Model/MappingEnum.cs b/CrmCodeGenerator.VSPackage/Model/MappingEnum.cs index 78a18f3..fc939f1 100644 --- a/CrmCodeGenerator.VSPackage/Model/MappingEnum.cs +++ b/CrmCodeGenerator.VSPackage/Model/MappingEnum.cs @@ -21,6 +21,9 @@ public static MappingEnum Parse(object attribute ) if (attribute is BooleanAttributeMetadata) return Parse(attribute as BooleanAttributeMetadata); + if (attribute is OptionSetMetadata) + return Parse(attribute as OptionSetMetadata); + return null; } @@ -58,6 +61,29 @@ public static MappingEnum Parse(BooleanAttributeMetadata twoOption) return enm; } + public static MappingEnum Parse(OptionSetMetadata optionSet) + { + var enm = new MappingEnum + { + DisplayName = Naming.GetProperVariableName(Naming.GetProperVariableName(optionSet.Name)), + Items = + optionSet.Options.Select( + o => new MapperEnumItem + { + Attribute = new CrmPicklistAttribute + { + DisplayName = o.Label.UserLocalizedLabel.Label, + Value = o.Value ?? 1 + }, + Name = Naming.GetProperVariableName(o.Label.UserLocalizedLabel.Label) + } + ).ToArray() + }; + + RenameDuplicates(enm); + + return enm; + } private static void RenameDuplicates(MappingEnum enm) { Dictionary duplicates = new Dictionary(); diff --git a/CrmCodeGenerator.VSPackage/Resources/Templates/CSharp.tt b/CrmCodeGenerator.VSPackage/Resources/Templates/CSharp.tt index 29151f1..3699cec 100644 --- a/CrmCodeGenerator.VSPackage/Resources/Templates/CSharp.tt +++ b/CrmCodeGenerator.VSPackage/Resources/Templates/CSharp.tt @@ -8,6 +8,19 @@ using System.ComponentModel.DataAnnotations; namespace <#= Context.Namespace #> { + public static class Enums + { +<#foreach (var enm in Context.Enums) {#> + [DataContractAttribute] + public enum <#=enm.DisplayName#> + { +<#foreach(var item in enm.Items){#> + [EnumMemberAttribute] + <#= item.Name #> = <#= item.Value #>, +<#}#> + } +<#}#> + } <# foreach (var entity in Context.Entities) { #> diff --git a/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtil.tt b/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtil.tt index 727691e..45f286e 100644 --- a/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtil.tt +++ b/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtil.tt @@ -11,6 +11,19 @@ using Microsoft.Xrm.Sdk.Client; [assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()] namespace <#= Context.Namespace #> { + public static class Enums + { +<#foreach (var enm in Context.Enums) {#> + [DataContractAttribute] + public enum <#=enm.DisplayName#> + { +<#foreach(var item in enm.Items){#> + [EnumMemberAttribute] + <#= item.Name #> = <#= item.Value #>, +<#}#> + } +<#}#> + } <# foreach (var entity in Context.Entities) { #> <# if (entity.States != null) { #> diff --git a/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtilExtended.tt b/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtilExtended.tt index 8bbcd6f..00da9ea 100644 --- a/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtilExtended.tt +++ b/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtilExtended.tt @@ -11,6 +11,19 @@ using Microsoft.Xrm.Sdk.Client; [assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()] namespace <#= Context.Namespace #> { + public static class Enums + { +<#foreach (var enm in Context.Enums) {#> + [DataContractAttribute] + public enum <#=enm.DisplayName#> + { +<#foreach(var item in enm.Items){#> + [EnumMemberAttribute] + <#= item.Name #> = <#= item.Value #>, +<#}#> + } +<#}#> + } <# foreach (var entity in Context.Entities) { #> <# if (entity.States != null) { #> diff --git a/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtilExtendedV2.tt b/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtilExtendedV2.tt index e60f1a7..46a50d4 100644 --- a/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtilExtendedV2.tt +++ b/CrmCodeGenerator.VSPackage/Resources/Templates/CrmSvcUtilExtendedV2.tt @@ -11,6 +11,19 @@ using Microsoft.Xrm.Sdk.Client; [assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()] namespace <#= Context.Namespace #> { + public static class Enums + { +<#foreach (var enm in Context.Enums) {#> + [DataContractAttribute] + public enum <#=enm.DisplayName#> + { +<#foreach(var item in enm.Items){#> + [EnumMemberAttribute] + <#= item.Name #> = <#= item.Value #>, +<#}#> + } +<#}#> + } <# foreach (var entity in Context.Entities) { #> <# if (entity.States != null) { #> diff --git a/CrmCodeGenerator.VSPackage/bin/Debug/CrmCodeGenerator.vsix b/CrmCodeGenerator.VSPackage/bin/Debug/CrmCodeGenerator.vsix index 521f364..b24f759 100644 Binary files a/CrmCodeGenerator.VSPackage/bin/Debug/CrmCodeGenerator.vsix and b/CrmCodeGenerator.VSPackage/bin/Debug/CrmCodeGenerator.vsix differ