private static void AssertIncidentHasCustomer(Entity entity, DelayedException exception) { if (entity.GetAttributeValue <EntityReference>(Incident.Fields.CustomerId) == null) { exception.Exception = CrmExceptions.GetFaultException(ErrorCodes.unManagedidsincidentparentaccountandparentcontactnotpresent); } }
private static void AssertOpportunityProductHasUoM(Entity entity, DelayedException exception) { if (entity.GetAttributeValue <EntityReference>(OpportunityProduct.Fields.UoMId) == null) { exception.Exception = CrmExceptions.GetFaultException(ErrorCodes.MissingUomId); } }
private static T Read <T>(LocalCrmDatabaseOrganizationService service, Guid id, ColumnSet cs, DelayedException exception) where T : Entity { var query = SchemaGetOrCreate <T>(service.Info). Where("Id == @0", id); var entity = query.FirstOrDefault(); if (entity == null) { entity = Activator.CreateInstance <T>(); entity.Id = id; exception.Exception = CrmExceptions.GetEntityDoesNotExistException(entity); return(null); } if (!cs.AllColumns) { foreach (var key in entity.Attributes.Keys.Where(k => !cs.Columns.Contains(k)).ToList()) { entity.Attributes.Remove(key); } } service.RemoveFieldsCrmDoesNotReturn(entity); PopulateFormattedValues <T>(entity); return(entity); }
private static void Update <T>(LocalCrmDatabaseOrganizationService service, T entity, DelayedException exception) where T : Entity { AssertTypeContainsColumns <T>(entity.Attributes.Keys); AssertEntityReferencesExists(service, entity); SimulateCrmAttributeManipulations(entity); if (SimulateCrmUpdateActionPrevention(service, entity, exception)) { return; } // Get the Entity From the database var databaseValue = SchemaGetOrCreate <T>(service.Info).FirstOrDefault(e => e.Id == entity.Id); if (databaseValue == null) { exception.Exception = CrmExceptions.GetEntityDoesNotExistException(entity); return; } // Update all of the attributes from the entity passed in, to the database entity foreach (var attribute in entity.Attributes) { databaseValue[attribute.Key] = attribute.Value; } // Set all Autopopulated values service.PopulateAutoPopulatedAttributes(databaseValue, false); SchemaGetOrCreate <T>(service.Info).Update(databaseValue); UpdateActivityPointer(service, databaseValue); }
private static void AssertConnectionRolesAreAssociated(LocalCrmDatabaseOrganizationService service, Entity entity, bool isUpdate, DelayedException exception) { var role1 = entity.GetAttributeValue <EntityReference>(Connection.Fields.Record1RoleId); var role2 = entity.GetAttributeValue <EntityReference>(Connection.Fields.Record2RoleId); if (isUpdate) { if (role1 == null && role2 == null) { // Role never got set, exit return; } if (role1 == null || role2 == null) { // One is null, attempt to populate it var dbVersion = service.Retrieve(entity.LogicalName, entity.Id, new ColumnSet(true)); var dbRole1 = dbVersion.GetAttributeValue <EntityReference>(Connection.Fields.Record1RoleId); var dbRole2 = dbVersion.GetAttributeValue <EntityReference>(Connection.Fields.Record2RoleId); if (role1 == null) { role1 = role2.NullSafeEquals(dbRole1) ? dbRole2 : dbRole1; } else { role2 = role1.NullSafeEquals(dbRole2) ? dbRole1 : dbRole2; } } } if (role1 == null || role2 == null) { return; } var qe = new QueryExpression { ColumnSet = new ColumnSet(true), EntityName = ConnectionRoleAssociation.EntityLogicalName }; qe.First().WhereEqual( ConnectionRoleAssociation.Fields.ConnectionRoleId, role1.Id, ConnectionRoleAssociation.Fields.AssociatedConnectionRoleId, role2.Id, LogicalOperator.Or, ConnectionRoleAssociation.Fields.ConnectionRoleId, role2.Id, ConnectionRoleAssociation.Fields.AssociatedConnectionRoleId, role1.Id); if (!service.RetrieveMultiple(qe).Entities.Any()) { exception.Exception = CrmExceptions.GetFaultException(ErrorCodes.UnrelatedConnectionRoles); } }
private static void Delete <T>(LocalCrmDatabaseOrganizationService service, Guid id, DelayedException exception) where T : Entity { var entity = Activator.CreateInstance <T>(); entity.Id = id; if (!SchemaGetOrCreate <T>(service.Info).Any(e => e.Id == id)) { exception.Exception = CrmExceptions.GetEntityDoesNotExistException(entity); return; } SchemaGetOrCreate <T>(service.Info).Delete(entity); DeleteActivityPointer <T>(service, id); }
private static bool AssertValidQueryByAttribute(QueryByAttribute query, DelayedException delay) { if (!query.Attributes.Any()) { delay.Exception = CrmExceptions.GetFaultException(ErrorCodes.QueryBuilderByAttributeNonEmpty); return(true); } if (query.Attributes.Count != query.Values.Count) { delay.Exception = CrmExceptions.GetFaultException(ErrorCodes.QueryBuilderByAttributeMismatch); return(true); } return(false); }
private static T Read <T>(LocalCrmDatabaseOrganizationService service, Guid id, ColumnSet cs, DelayedException exception) where T : Entity { var query = SchemaGetOrCreate <T>(service.Info).Where("Id == @0", id); var entity = query.FirstOrDefault(); if (entity == null) { entity = Activator.CreateInstance <T>(); entity.Id = id; exception.Exception = CrmExceptions.GetEntityDoesNotExistException(entity); return(null); } return(ProcessEntityForReturn(service, cs, entity, false)); }
/// <summary> /// Gets the int value from int or string. /// </summary> /// <param name="condition">The condition expression.</param> /// <param name="index">The index of the value in the condition Values collection. Defaults to 0.</param> /// <returns></returns> public static int GetIntValueFromIntOrString(this ConditionExpression condition, int index = 0) { var value = condition.Values[index]; if (value is string) { return(int.Parse(value as string)); } if (value is int) { return((int)value); } throw CrmExceptions.GetIntShouldBeStringOrIntException(condition.GetQualifiedAttributeName()); }
/// <summary> /// Gets the Date value from Date or string. /// </summary> /// <param name="condition">The condition expression.</param> /// <param name="index">The index of the value in the condition Values collection. Defaults to 0.</param> /// <returns></returns> public static DateTime GetDateTimeValueFromDateOrString(this ConditionExpression condition, int index = 0) { var value = condition.Values[index]; if (value is string stringValue) { return(DateTime.Parse(stringValue)); } if (value is DateTime dateValue) { return(dateValue); } throw CrmExceptions.GetDateShouldBeStringOrDateException(condition.GetQualifiedAttributeName()); }
private static void AssertExpectedNumberOfValues(ConditionExpression condition) { if (!ExpectedValuesByConditionOperator.TryGetValue(condition.Operator, out var expectedCount)) { return; } if (condition.Values.Count != expectedCount) { throw CrmExceptions.GetConditionOperatorRequiresValuesException(condition, expectedCount); } if (expectedCount == 1 && condition.Values[0] == null) { condition = new ConditionExpression(condition.AttributeName, condition.Operator); throw CrmExceptions.GetConditionOperatorRequiresValuesException(condition, expectedCount); } }
/// <summary> /// Simulates CRM update action preventions. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="service">The service.</param> /// <param name="entity">The entity.</param> /// <param name="exception">The exception.</param> /// <returns></returns> private static bool SimulateCrmUpdateActionPrevention <T>(LocalCrmDatabaseOrganizationService service, T entity, DelayedException exception) where T : Entity { #if Xrm2015 return(false); #endif switch (entity.LogicalName) { case Incident.EntityLogicalName: if (service.CurrentRequestName != new CloseIncidentRequest().RequestName&& entity.GetAttributeValue <OptionSetValue>(Incident.Fields.StateCode).GetValueOrDefault() == (int)IncidentState.Resolved) { // Not executing as a part of a CloseIncidentRequest. Disallow updating the State Code to Resolved. exception.Exception = CrmExceptions.GetFaultException(ErrorCodes.UseCloseIncidentRequest); return(true); } break; } return(false); }
private static void Update <T>(LocalCrmDatabaseOrganizationService service, T entity, DelayedException exception) where T : Entity { AssertTypeContainsColumns <T>(entity.Attributes.Keys); AssertEntityReferencesExists(service, entity); SimulateCrmAttributeManipulations(entity); if (SimulateCrmUpdateActionPrevention(service, entity, exception)) { return; } var schema = SchemaGetOrCreate <T>(service.Info); // Get the Entity From the database var databaseValue = schema.FirstOrDefault(e => e.Id == entity.Id); if (databaseValue == null) { exception.Exception = CrmExceptions.GetEntityDoesNotExistException(entity); return; } // Clone Entity attributes so updating a non-primative attribute type does not cause changes to the database value entity = entity.Serialize().DeserializeEntity <T>(); // Update all of the attributes from the entity passed in, to the database entity foreach (var attribute in entity.Attributes) { databaseValue[attribute.Key] = attribute.Value; } // Set all Auto populated values PopulateAutoPopulatedAttributes(service, databaseValue, false); schema.Update(databaseValue); UpdateActivityPointer(service, databaseValue); CreateActivityParties(service, entity); SetCachePrimaryName(service, schema.FirstOrDefault(e => e.Id == entity.Id)); }
private static void AssertConnectionRolesArePopulated(Entity entity, bool isUpdate, DelayedException exception) { var record1Null = (entity.GetAttributeValue <EntityReference>(Connection.Fields.Record1RoleId) ?? entity.GetAttributeValue <EntityReference>(Connection.Fields.Record1Id)) == null; var record2Null = (entity.GetAttributeValue <EntityReference>(Connection.Fields.Record2RoleId) ?? entity.GetAttributeValue <EntityReference>(Connection.Fields.Record2Id)) == null; var aConnectionIsMissing = record1Null || record2Null; if (isUpdate) { var containsRecord1 = entity.Contains(Connection.Fields.Record1Id) || entity.Contains(Connection.Fields.Record1RoleId); var containsRecord2 = entity.Contains(Connection.Fields.Record2Id) || entity.Contains(Connection.Fields.Record2RoleId); aConnectionIsMissing = containsRecord1 && record1Null || containsRecord2 && record2Null; } if (aConnectionIsMissing) { exception.Exception = CrmExceptions.GetFaultException(ErrorCodes.BothConnectionSidesAreNeeded); } }
private static bool ConditionIsTrue <T>(T entity, ConditionExpression condition) where T : Entity { // Date Time Details: https://community.dynamics.com/crm/b/gonzaloruiz/archive/2012/07/29/date-and-time-operators-in-crm-explained int days; bool value; var name = condition.GetQualifiedAttributeName(); switch (condition.Operator) { case ConditionOperator.Equal: value = Compare(entity, name, condition.Values[0]) == 0; break; case ConditionOperator.NotEqual: value = Compare(entity, name, condition.Values[0]) != 0; break; case ConditionOperator.GreaterThan: value = Compare(entity, name, condition.Values[0]) > 0; break; case ConditionOperator.LessThan: value = Compare(entity, name, condition.Values[0]) < 0; break; case ConditionOperator.GreaterEqual: value = Compare(entity, name, condition.Values[0]) >= 0; break; case ConditionOperator.LessEqual: value = Compare(entity, name, condition.Values[0]) <= 0; break; case ConditionOperator.Like: var str = GetString(entity, name); if (str == null) { value = condition.Values[0] == null; } else { var likeCondition = (string)condition.Values[0]; // http://stackoverflow.com/questions/5417070/c-sharp-version-of-sql-like value = new Regex(@"\A" + new Regex(@"\.|\$|\^|\{|\[|\(|\||\)|\*|\+|\?|\\").Replace(likeCondition.ToUpper(), ch => @"\" + ch).Replace('_', '.').Replace("%", ".*") + @"\z", RegexOptions.Singleline).IsMatch(str.ToUpper()); } break; case ConditionOperator.NotLike: value = !ConditionIsTrue(entity, new ConditionExpression(condition.EntityName, condition.AttributeName, ConditionOperator.Like)); break; case ConditionOperator.In: value = condition.Values.Any(v => v.Equals(ConvertCrmTypeToBasicComparable(entity, name))); break; case ConditionOperator.NotIn: value = !condition.Values.Any(v => v.Equals(ConvertCrmTypeToBasicComparable(entity, name))); break; //case ConditionOperator.Between: // break; //case ConditionOperator.NotBetween: // break; case ConditionOperator.Null: value = Compare(entity, name, null) == 0; break; case ConditionOperator.NotNull: value = Compare(entity, name, null) != 0; break; case ConditionOperator.Yesterday: value = IsBetween(entity, condition, DateTime.UtcNow.Date.AddDays(-1), DateTime.UtcNow.Date); break; case ConditionOperator.Today: value = IsBetween(entity, condition, DateTime.UtcNow.Date, DateTime.UtcNow.Date.AddDays(1)); break; case ConditionOperator.Tomorrow: value = IsBetween(entity, condition, DateTime.UtcNow.Date.AddDays(1), DateTime.UtcNow.Date.AddDays(2)); break; case ConditionOperator.Last7Days: condition.Operator = ConditionOperator.LastXDays; condition.Values.Add(7); value = ConditionIsTrue(entity, condition); break; case ConditionOperator.Next7Days: condition.Operator = ConditionOperator.NextXDays; condition.Values.Add(7); value = ConditionIsTrue(entity, condition); break; //case ConditionOperator.LastWeek: // break; //case ConditionOperator.ThisWeek: // break; //case ConditionOperator.NextWeek: // break; //case ConditionOperator.LastMonth: // break; //case ConditionOperator.ThisMonth: // break; //case ConditionOperator.NextMonth: // break; //case ConditionOperator.On: // break; //case ConditionOperator.OnOrBefore: // break; //case ConditionOperator.OnOrAfter: // break; //case ConditionOperator.LastYear: // break; //case ConditionOperator.ThisYear: // break; //case ConditionOperator.NextYear: // break; //case ConditionOperator.LastXHours: // break; //case ConditionOperator.NextXHours: // break; case ConditionOperator.LastXDays: days = condition.GetIntValueFromIntOrString(); if (days <= 0) { throw CrmExceptions.GetConditionValueGreaterThan0Exception(); } value = IsBetween(entity, condition, DateTime.UtcNow.Date.AddDays(-1d * days), DateTime.UtcNow); break; case ConditionOperator.NextXDays: days = condition.GetIntValueFromIntOrString(); if (days <= 0) { throw CrmExceptions.GetConditionValueGreaterThan0Exception(); } value = IsBetween(entity, condition, DateTime.UtcNow, DateTime.UtcNow.Date.AddDays(days + 1)); break; //case ConditionOperator.LastXWeeks: // break; //case ConditionOperator.NextXWeeks: // break; //case ConditionOperator.LastXMonths: // break; //case ConditionOperator.NextXMonths: // break; //case ConditionOperator.LastXYears: // break; //case ConditionOperator.NextXYears: // break; //case ConditionOperator.EqualUserId: // break; //case ConditionOperator.NotEqualUserId: // break; //case ConditionOperator.EqualBusinessId: // break; //case ConditionOperator.NotEqualBusinessId: // break; //case ConditionOperator.ChildOf: // break; //case ConditionOperator.Mask: // break; //case ConditionOperator.NotMask: // break; //case ConditionOperator.MasksSelect: // break; //case ConditionOperator.Contains: // break; //case ConditionOperator.DoesNotContain: // break; //case ConditionOperator.EqualUserLanguage: // break; //case ConditionOperator.NotOn: // break; //case ConditionOperator.OlderThanXMonths: // break; //case ConditionOperator.BeginsWith: // break; //case ConditionOperator.DoesNotBeginWith: // break; //case ConditionOperator.EndsWith: // break; //case ConditionOperator.DoesNotEndWith: // break; //case ConditionOperator.ThisFiscalYear: // break; //case ConditionOperator.ThisFiscalPeriod: // break; //case ConditionOperator.NextFiscalYear: // break; //case ConditionOperator.NextFiscalPeriod: // break; //case ConditionOperator.LastFiscalYear: // break; //case ConditionOperator.LastFiscalPeriod: // break; //case ConditionOperator.LastXFiscalYears: // break; //case ConditionOperator.LastXFiscalPeriods: // break; //case ConditionOperator.NextXFiscalYears: // break; //case ConditionOperator.NextXFiscalPeriods: // break; //case ConditionOperator.InFiscalYear: // break; //case ConditionOperator.InFiscalPeriod: // break; //case ConditionOperator.InFiscalPeriodAndYear: // break; //case ConditionOperator.InOrBeforeFiscalPeriodAndYear: // break; //case ConditionOperator.InOrAfterFiscalPeriodAndYear: // break; //case ConditionOperator.EqualUserTeams: // break; default: throw new NotImplementedException(condition.Operator.ToString()); } return(value); }