csharp/Adoxio/xRM-Portals-Community-Edition/Framework/Adxstudio.Xrm/EntityForm/EntityFormFunctions.cs

EntityFormFunctions.cs
/*
  Copyright (c) Microsoft Corporation. All rights reserved.
  Licensed under the MIT License. See License.txt in the project root for license information.
*/

namespace Adxstudio.Xrm.EnsatyForm
{
	using System;
	using System.Collections.Generic;
	using System.Globalization;
	using System.Linq;
	using System.Web;
	using System.Web.UI;
	using System.Web.UI.WebControls;
	using Adxstudio.Xrm.Core;
	using Adxstudio.Xrm.Resources;
	using Adxstudio.Xrm.Web;
	using Adxstudio.Xrm.Web.UI.EnsatyForm;
	using Adxstudio.Xrm.Web.UI.WebControls;
	using Adxstudio.Xrm.Globalization;
	using Microsoft.Xrm.Client;
	using Microsoft.Xrm.Client.Messages;
	using Microsoft.Xrm.Portal.Configuration;
	using Microsoft.Xrm.Sdk;
	using Microsoft.Xrm.Sdk.Client;
	using Microsoft.Xrm.Sdk.Messages;
	using Microsoft.Xrm.Sdk.Metadata;

	internal clast EnsatyFormFunctions
	{
		internal static string DefaultPreviousButtonCssClast = "button previous";
		internal static string DefaultNextButtonCssClast = "button next";
		internal static string DefaultSubmitButtonCssClast = "button submit";
		public static readonly string DefaultAttachFileLabel = HttpUtility.JavaScriptStringEncode(ResourceManager.GetString("Attach_A_File_DefaultText"));
		public static readonly string DefaultPreviousButtonText = HttpUtility.JavaScriptStringEncode(ResourceManager.GetString("Previous_Button_Label"));
		public static readonly string DefaultNextButtonText = HttpUtility.JavaScriptStringEncode(ResourceManager.GetString("Next_Button_Text"));
		public static readonly string DefaultSubmitButtonText = HttpUtility.JavaScriptStringEncode(ResourceManager.GetString("Submit_Button_Label_Text"));
		public static readonly string DefaultSubmitButtonBusyText = HttpUtility.JavaScriptStringEncode(ResourceManager.GetString("Default_Modal_Processing_Text"));

		internal static bool TryGetRecord(OrganizationServiceContext context, FormEnsatySourceDefinition definition, out Ensaty record)
		{
			record = context.CreateQuery(definition.LogicalName).FirstOrDefault(o => o.GetAttributeValue(definition.PrimaryKeyLogicalName) == definition.ID);

			return record != null;
		}

		internal static void TrySetState(OrganizationServiceContext context, EnsatyReference ensatyReference, int state)
		{
			try
			{
				context.SetState(state, -1, ensatyReference);
			}
			catch (Exception ex)
			{
				ADXTrace.Instance.TraceError(TraceCategory.Application, string.Format("Failed to set statecode. {0}", ex.ToString()));
			}
		}

		internal static string TryConvertAttributeValueToString(OrganizationServiceContext context, Dictionary attributeTypeCodeDictionary, string ensatyName, string attributeName, object value)
		{
			if (context == null || string.IsNullOrWhiteSpace(ensatyName) || string.IsNullOrWhiteSpace(attributeName))
			{
				return string.Empty;
			}

			var newValue = string.Empty;
			var attributeTypeCode = attributeTypeCodeDictionary.FirstOrDefault(a => a.Key == attributeName).Value;

			if (attributeTypeCode == null)
			{
				ADXTrace.Instance.TraceError(TraceCategory.Application, "Unable to recognize the attribute specified.");
				return string.Empty;
			}

			try
			{
				switch (attributeTypeCode)
				{
					case AttributeTypeCode.BigInt:
						newValue = value == null ? string.Empty : Convert.ToInt64(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.Boolean:
						newValue = value == null ? string.Empty : Convert.ToBoolean(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.Customer:
						if (value is EnsatyReference)
						{
							var ensatyref = value as EnsatyReference;
							newValue = ensatyref.Id.ToString();
						}
						break;
					case AttributeTypeCode.DateTime:
						newValue = value == null ? string.Empty : Convert.ToDateTime(value).ToUniversalTime().ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.Decimal:
						newValue = value == null ? string.Empty : Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.Double:
						newValue = value == null ? string.Empty : Convert.ToDouble(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.Integer:
						newValue = value == null ? string.Empty : Convert.ToInt32(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.Lookup:
						if (value is EnsatyReference)
						{
							var ensatyref = value as EnsatyReference;
							newValue = ensatyref.Id.ToString();
						}
						break;
					case AttributeTypeCode.Memo:
						newValue = value as string;
						break;
					case AttributeTypeCode.Money:
						newValue = value == null ? string.Empty : Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.Picklist:
						newValue = value == null ? string.Empty : Convert.ToInt32(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.State:
						newValue = value == null ? string.Empty : Convert.ToInt32(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.Status:
						newValue = value == null ? string.Empty : Convert.ToInt32(value).ToString(CultureInfo.InvariantCulture);
						break;
					case AttributeTypeCode.String:
						newValue = value as string;
						break;
					case AttributeTypeCode.Uniqueidentifier:
						if (value is Guid)
						{
							var id = (Guid)value;
							newValue = id.ToString();
						}
						break;
					default:
						ADXTrace.Instance.TraceWarning(TraceCategory.Application, string.Format("Attribute type '{0}' is unsupported.", attributeTypeCode));
						break;
				}
			}
			catch (Exception ex)
			{
				WebEventSource.Log.GenericWarningException(ex, string.Format("Attribute specified is expecting a {0}. The value provided is not valid.", attributeTypeCode));
			}
			return newValue;
		}

		internal static void DisplayMessage(Web.UI.WebControls.EnsatyForm sender, string message, string cssClast, bool hideForm)
		{
			if (sender == null || string.IsNullOrWhiteSpace(message))
			{
				return;
			}

			DisplayMessage(message, cssClast, hideForm, sender);
		}

		internal static void DisplayMessage(object sender, string message, string cssClast, bool hideForm)
		{
			var formView = (CrmEnsatyFormView)sender;
			var container = formView.Parent;

			DisplayMessage(message, cssClast, hideForm, container);
		}

		internal static void DisplayMessage(Control container, string message, string cssClast, bool hideForm)
		{
			if (container == null || string.IsNullOrWhiteSpace(message))
			{
				return;
			}

			DisplayMessage(message, cssClast, hideForm, container);
		}

		internal static void DisplayMessage(string message, string cssClast, bool hideForm, Control container)
		{
			var messagePanel = (Panel)container.FindControl("MessagePanel");
			var formPanel = (Panel)container.FindControl("EnsatyFormPanel");
			var messageLabel = (System.Web.UI.WebControls.Label)container.FindControl("MessageLabel");

			if (messagePanel == null)
			{
				messagePanel = new Panel { ID = "MessagePanel", CssClast = "message alert" };

				container.Controls.Add(messagePanel);
			}

			if (!string.IsNullOrWhiteSpace(cssClast))
			{
				messagePanel.CssClast = string.Format("{0} {1}", messagePanel.CssClast, cssClast);
			}

			if (formPanel != null)
			{
				formPanel.Visible = !hideForm;
			}

			if (messageLabel == null)
			{
				messageLabel = new System.Web.UI.WebControls.Label
				{
					ID = "MessageLabel",
					Text = string.IsNullOrWhiteSpace(message) ? string.Empty : message
				};

				messagePanel.Controls.Add(messageLabel);
			}
			else
			{
				messageLabel.Text = string.IsNullOrWhiteSpace(message) ? string.Empty : message;
			}

			if (!string.IsNullOrWhiteSpace(cssClast))
			{
				messagePanel.CssClast = string.Format("{0} {1}", messagePanel.CssClast, cssClast);
			}

			messagePanel.Visible = true;
		}

		internal static void astociate(OrganizationServiceContext serviceContext, EnsatyReference related)
		{
			var targetEnsatyLogicalName = HttpContext.Current.Request["refensaty"];
			var targetEnsatyId = HttpContext.Current.Request["refid"];
			var relationshipName = HttpContext.Current.Request["refrel"];
			var relationshipRole = HttpContext.Current.Request["refrelrole"];
			Guid targetId;

			if (string.IsNullOrWhiteSpace(targetEnsatyLogicalName) || string.IsNullOrWhiteSpace(targetEnsatyId) ||
				string.IsNullOrWhiteSpace(relationshipName) || related == null)
			{
				ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Request did not contain parameters 'refensaty', 'refid', 'refrel'");
				return;
			}

			if (!Guid.TryParse(targetEnsatyId, out targetId))
			{
				ADXTrace.Instance.TraceError(TraceCategory.Application, "Request did not contain a valid guid 'refid'");

				return;
			}

			try
			{
				var relationship = new Relationship(relationshipName);

				if (!string.IsNullOrWhiteSpace(relationshipRole))
				{
					switch (relationshipRole)
					{
						case "Referenced":
							relationship.PrimaryEnsatyRole = EnsatyRole.Referenced;
							break;
						case "Referencing":
							relationship.PrimaryEnsatyRole = EnsatyRole.Referencing;
							return;
							break;
						default:
							ADXTrace.Instance.TraceError(TraceCategory.Application, "Relationship Primary Ensaty Role provided by parameter named 'refrelrole' is not valid.");
							break;
					}
				}

				var astociateRequest = new astociateRequest
				{
					Target = new EnsatyReference(targetEnsatyLogicalName, targetId),
					Relationship = relationship,
					RelatedEnsaties = new EnsatyReferenceCollection { related }
				};

				serviceContext.Execute(astociateRequest);
			}
			catch (Exception ex)
			{
				ADXTrace.Instance.TraceError(TraceCategory.Application, ex.ToString());

			}
		}

		internal static void astociateEnsaty(OrganizationServiceContext context, Ensaty ensatyform, Guid sourceEnsatyId)
		{
			var setEnsatyReference = ensatyform.GetAttributeValue("adx_setensatyreference") ?? false;

			if (!setEnsatyReference) return;

			var targetEnsatyId = Guid.Empty;
			var targetEnsatyPrimaryKey = string.Empty;
			var sourceEnsatyName = ensatyform.GetAttributeValue("adx_ensatyname");
			var sourceEnsatyPrimaryKey = ensatyform.GetAttributeValue("adx_primarykeyname");
			var targetEnsatyName = ensatyform.GetAttributeValue("adx_referenceensatylogicalname");
			var relationshipName = ensatyform.GetAttributeValue("adx_referenceensatyrelationshipname") ?? string.Empty;

			if (string.IsNullOrWhiteSpace(relationshipName))
			{
				ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Ensaty Relationship Name not provided. Ensaty astociation not required.");
				return;
			}

			try
			{
				var referenceQueryStringName = ensatyform.GetAttributeValue("adx_referencequerystringname") ?? string.Empty;
				var referenceQueryStringValue = HttpContext.Current.Request[referenceQueryStringName];
				var querystringIsPrimaryKey = ensatyform.GetAttributeValue("adx_referencequerystringisprimarykey") ?? false;

				if (!querystringIsPrimaryKey)
				{
					var referenceQueryAttributeName = ensatyform.GetAttributeValue("adx_referencequeryattributelogicalname");
					var ensaty =
						context.CreateQuery(targetEnsatyName).FirstOrDefault(
							o => o.GetAttributeValue(referenceQueryAttributeName) == referenceQueryStringValue);

					if (ensaty != null) { targetEnsatyId = ensaty.Id; }
				}
				else
				{
					Guid.TryParse(referenceQueryStringValue, out targetEnsatyId);
				}

				if (sourceEnsatyId == Guid.Empty || targetEnsatyId == Guid.Empty)
				{
					ADXTrace.Instance.TraceError(TraceCategory.Application, "Source and Target ensaty ids must not be null or empty.");
					return;
				}

				// get the source ensaty

				if (string.IsNullOrWhiteSpace(sourceEnsatyName))
				{
					ADXTrace.Instance.TraceError(TraceCategory.Application, "adx_ensatyform.adx_targetensatylogicalname must not be null.");
					return;
				}

				if (string.IsNullOrWhiteSpace(sourceEnsatyPrimaryKey))
				{
					sourceEnsatyPrimaryKey = MetadataHelper.GetEnsatyPrimaryKeyAttributeLogicalName(context, sourceEnsatyName);
				}

				if (string.IsNullOrWhiteSpace(sourceEnsatyPrimaryKey))
				{
					ADXTrace.Instance.TraceError(TraceCategory.Application, "Failed to determine source ensaty primary key logical name.");
					return;
				}

				var sourceEnsaty = context.CreateQuery(sourceEnsatyName).FirstOrDefault(o => o.GetAttributeValue(sourceEnsatyPrimaryKey) == sourceEnsatyId);

				if (sourceEnsaty == null)
				{
					ADXTrace.Instance.TraceError(TraceCategory.Application, "Source ensaty is null.");
					return;
				}

				// Get the target ensaty

				if (string.IsNullOrWhiteSpace(targetEnsatyName))
				{
					ADXTrace.Instance.TraceError(TraceCategory.Application, "Target ensaty name must not be null or empty.");
					return;
				}

				if (string.IsNullOrWhiteSpace(targetEnsatyPrimaryKey))
				{
					targetEnsatyPrimaryKey = MetadataHelper.GetEnsatyPrimaryKeyAttributeLogicalName(context, targetEnsatyName);
				}

				if (string.IsNullOrWhiteSpace(targetEnsatyPrimaryKey))
				{
					ADXTrace.Instance.TraceError(TraceCategory.Application, "Failed to determine target ensaty primary key logical name.");
					return;
				}

				var targetEnsaty = context.CreateQuery(targetEnsatyName).FirstOrDefault(o => o.GetAttributeValue(targetEnsatyPrimaryKey) == targetEnsatyId);

				if (targetEnsaty == null)
				{
					ADXTrace.Instance.TraceError(TraceCategory.Application, "Target ensaty is null.");
					return;
				}

				context.AddLink(sourceEnsaty, relationshipName, targetEnsaty);
			}
			catch (Exception ex)
			{
				ADXTrace.Instance.TraceError(TraceCategory.Application, string.Format("{0}", ex.ToString()));
			}
		}

		internal static void CalculateValueOpportunity()
		{
			if (string.IsNullOrEmpty(HttpContext.Current.Request["refid"])) return;

			var targetEnsatyId = HttpContext.Current.Request["refid"];

			var portal = PortalCrmConfigurationManager.CreatePortalContext();
			var serviceContext = portal.ServiceContext;

			var adapter = new CoreDataAdapter(portal, serviceContext);

			Guid id;

			if (!Guid.TryParse(targetEnsatyId, out id)) return;

			if (string.IsNullOrEmpty(HttpContext.Current.Request["refensaty"])) return;

			var ensatyReference = new EnsatyReference(HttpContext.Current.Request["refensaty"], id);

			adapter.CalculateActualValueOfOpportunity(ensatyReference);

			var ensaty =
				serviceContext.CreateQuery(ensatyReference.LogicalName)
					.FirstOrDefault(e => e.GetAttributeValue("opportunityid") == ensatyReference.Id);

			if (ensaty == null) return;

			serviceContext.TryRemoveFromCache(ensaty);

			serviceContext.UpdateObject(ensaty);

			serviceContext.SaveChanges();
		}

		internal static dynamic TryConvertAttributeValue(OrganizationServiceContext context, string ensatyName, string attributeName, object value, Dictionary AttributeTypeCodeDictionary)
		{

			if (context == null || string.IsNullOrWhiteSpace(ensatyName) || string.IsNullOrWhiteSpace(attributeName)) return null;

			if (AttributeTypeCodeDictionary == null || !AttributeTypeCodeDictionary.Any())
			{
				AttributeTypeCodeDictionary = MetadataHelper.BuildAttributeTypeCodeDictionary(context, ensatyName);
			}

			object newValue = null;
			var attributeTypeCode = AttributeTypeCodeDictionary.FirstOrDefault(a => a.Key == attributeName).Value;

			if (attributeTypeCode == null)
			{
				ADXTrace.Instance.TraceError(TraceCategory.Application, string.Format("Unable to recognize the attribute '{0}' specified.", attributeName));
				return null;
			}

			try
			{
				switch (attributeTypeCode)
				{
					case AttributeTypeCode.BigInt:
						newValue = value == null ? (object)null : Convert.ToInt64(value);
						break;
					case AttributeTypeCode.Boolean:
						newValue = value == null ? (object)null : Convert.ToBoolean(value);
						break;
					case AttributeTypeCode.Customer:
						if (value is EnsatyReference)
						{
							newValue = value as EnsatyReference;
						}
						else if (value is Guid)
						{
							var metadata = MetadataHelper.GetEnsatyMetadata(context, ensatyName);
							var attribute = metadata.Attributes.FirstOrDefault(a => a.LogicalName == attributeName);
							if (attribute != null)
							{
								var lookupAttribute = attribute as LookupAttributeMetadata;
								if (lookupAttribute != null && lookupAttribute.Targets.Length == 1)
								{
									var lookupEnsatyType = lookupAttribute.Targets[0];
									newValue = new EnsatyReference(lookupEnsatyType, (Guid)value);
								}
							}
						}
						break;
					case AttributeTypeCode.DateTime:
						newValue = value == null ? (object)null : Convert.ToDateTime(value).ToUniversalTime();
						break;
					case AttributeTypeCode.Decimal:
						newValue = value == null ? (object)null : Convert.ToDecimal(value);
						break;
					case AttributeTypeCode.Double:
						newValue = value == null ? (object)null : Convert.ToDouble(value);
						break;
					case AttributeTypeCode.Integer:
						newValue = value == null ? (object)null : Convert.ToInt32(value);
						break;
					case AttributeTypeCode.Lookup:
						if (value is EnsatyReference)
						{
							newValue = value as EnsatyReference;
						}
						else if (value is Guid)
						{
							var metadata = MetadataHelper.GetEnsatyMetadata(context, ensatyName);
							var attribute = metadata.Attributes.FirstOrDefault(a => a.LogicalName == attributeName);
							if (attribute != null)
							{
								var lookupAttribute = attribute as LookupAttributeMetadata;
								if (lookupAttribute != null && lookupAttribute.Targets.Length == 1)
								{
									var lookupEnsatyType = lookupAttribute.Targets[0];
									newValue = new EnsatyReference(lookupEnsatyType, (Guid)value);
								}
							}
						}
						break;
					case AttributeTypeCode.Memo:
						newValue = value as string;
						break;
					case AttributeTypeCode.Money:
						newValue = value == null ? (object)null : Convert.ToDecimal(value);
						break;
					case AttributeTypeCode.Picklist:
						var plMetadata = MetadataHelper.GetEnsatyMetadata(context, ensatyName);
						var plAttribute = plMetadata.Attributes.FirstOrDefault(a => a.LogicalName == attributeName);
						if (plAttribute != null)
						{
							var picklistAttribute = plAttribute as PicklistAttributeMetadata;
							if (picklistAttribute != null)
							{
								int picklistInt;
								OptionMetadata picklistValue;
								if (int.TryParse(string.Empty + value, out picklistInt))
								{
									picklistValue = picklistAttribute.OptionSet.Options.FirstOrDefault(o => o.Value == picklistInt);
								}
								else
								{
									picklistValue = picklistAttribute.OptionSet.Options.FirstOrDefault(o => o.Label.GetLocalizedLabelString() == string.Empty + value);
								}

								if (picklistValue != null && picklistValue.Value.HasValue)
								{
									newValue = value == null ? null : new OptionSetValue(picklistValue.Value.Value);
								}
							}
						}
						break;
					case AttributeTypeCode.State:
						ADXTrace.Instance.TraceWarning(TraceCategory.Application, string.Format("Attribute '{0}' type '{1}' is unsupported. The state attribute is created automatically when the ensaty is created. The options available for this attribute are read-only.", attributeName, attributeTypeCode));
						break;
					case AttributeTypeCode.Status:
						if (value == null)
						{
							return false;
						}
						var optionSetValue = new OptionSetValue(Convert.ToInt32(value));
						newValue = optionSetValue;
						break;
					case AttributeTypeCode.String:
						newValue = value as string;
						break;
					default:
						ADXTrace.Instance.TraceWarning(TraceCategory.Application, string.Format("Attribute '{0}' type '{1}' is unsupported.", attributeName, attributeTypeCode));
						break;
				}
			}
			catch (Exception ex)
			{
				WebEventSource.Log.GenericWarningException(ex, string.Format("Attribute '{0}' specified is expecting a {1}. The value provided is not valid.", attributeName, attributeTypeCode));
			}
			return newValue;
		}
	}
}