public void MakeNameMatchCase_NameIsMcdonald_Should_UpdateToMcDonald() { // // Arrange // var service = new LocalCrmDatabaseOrganizationService(LocalCrmDatabaseInfo.Create<CrmContext>()); var id = service.Create(new Contact {LastName = "Mcdonald"}); // // Act // MakeNameMatchCase(service, "McDonald"); // // Assert // Assert.AreEqual("McDonald", service.GetEntity<Contact>(id).LastName); }
public static EntityCollection ReadEntities <T>(LocalCrmDatabaseOrganizationService service, QueryExpression qe) where T : Entity { var query = SchemaGetOrCreate <T>(service.Info).AsQueryable <T>(); HandleFilterExpressionsWithAliases(qe, qe.Criteria).ToList(); query = qe.LinkEntities.Aggregate(query, (q, e) => CallJoin(service.Info, q, e)); query = ApplyFilter(query, qe.Criteria); var entities = query.ToList(); if (qe.Orders.Any()) { // Sort var ordered = entities.Order(qe.Orders[0]); entities = qe.Orders.Skip(1).Aggregate(ordered, (current, t) => current.Order(t)).ToList(); } if (!qe.ColumnSet.AllColumns) { foreach (var entity in entities) { foreach (var key in entity.Attributes.Keys.Where(k => !qe.ColumnSet.Columns.Contains(k) && !(entity[k] is AliasedValue)).ToList()) { entity.Attributes.Remove(key); } } } foreach (var entity in entities) { service.RemoveFieldsCrmDoesNotReturn(entity); PopulateFormattedValues <T>(entity); } var result = new EntityCollection(); result.Entities.AddRange(entities); return(result); }
private static void AddToFilter(LocalCrmDatabaseOrganizationService service, Type entityType, Dictionary <String, LinkEntity> links, FilterExpression criteria, condition condition) { string entityName = null; if (!String.IsNullOrWhiteSpace(condition.entityname)) { entityName = condition.entityname; entityType = service.GetType(links[condition.entityname].LinkToEntityName); } var property = entityType.GetProperty(condition.attribute) ?? entityType.GetProperty(condition.attribute, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); if (property == null) { throw new Exception("No Property '" + condition.attribute + "' found for entity type: " + entityType.Name); } var op = Convert(condition.@operator); criteria.AddCondition(entityName, condition.attribute, op, GetConditionValue(condition, property.PropertyType, op)); }
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 EntityCollection ReadEntitiesByAttribute <T>(LocalCrmDatabaseOrganizationService service, QueryByAttribute query, DelayedException delay) where T : Entity { if (AssertValidQueryByAttribute(query, delay)) { return(null); } var qe = new QueryExpression(query.EntityName) { ColumnSet = query.ColumnSet, PageInfo = query.PageInfo, TopCount = query.TopCount, }; qe.Orders.AddRange(query.Orders); for (var i = 0; i < query.Attributes.Count; i++) { qe.WhereEqual(query.Attributes[i], query.Values[i]); } return(ReadEntities <T>(service, qe)); }
// ReSharper disable once UnusedParameter.Local private static void ProcessFetchXmlItem(LocalCrmDatabaseOrganizationService service, LinkEntity entityLink, FetchLinkEntityType link) { var joinType = link.linktype == "outer" ? JoinOperator.LeftOuter : JoinOperator.Inner; var childLink = new LinkEntity(entityLink.LinkToEntityName, link.name, link.@from, link.to, joinType) { EntityAlias = link.alias, }; entityLink.LinkEntities.Add(childLink); var items = link.Items; if (items == null) { return; } foreach (dynamic item in items) { ProcessFetchXmlItem(service, childLink, item); } }
private static void CreateActivityPartiesFromPartyLists <T>(LocalCrmDatabaseOrganizationService service, T entity) where T : Entity { foreach (var att in entity.Attributes.Where(a => a.Value is EntityCollection)) { var entities = (EntityCollection)att.Value; foreach (var party in entities.Entities.Where(p => p.LogicalName == ActivityParty.EntityLogicalName)) { if (party.GetAttributeValue <EntityReference>(ActivityParty.Fields.PartyId) == null) { throw new NullReferenceException("Activity Party PartyId was null"); } party[ActivityParty.Fields.ActivityId] = entity.ToEntityReference(); if (party.GetAttributeValue <object>(ActivityParty.Fields.ParticipationTypeMask) == null) { party[ActivityParty.Fields.ParticipationTypeMask] = MapFieldToParticipation(att.Key); } service.CreateActivityParty(party); } } }
/// <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 { switch (entity.LogicalName) { case Incident.EntityLogicalName: #if Xrm2015 break; #else 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); } break; #endif case Connection.EntityLogicalName: AssertConnectionRolesArePopulated(entity, true, exception); AssertConnectionRolesAreAssociated(service, entity, true, exception); break; } return(exception.Exception != null); }
public static Guid Create <T>(LocalCrmDatabaseOrganizationService service, T entity) where T : Entity { // Clone entity so no changes will affect actual entity entity = entity.Serialize().DeserializeEntity <T>(); AssertTypeContainsColumns <T>(entity.Attributes.Keys); AssertEntityReferencesExists(service, entity); ConvertEntityArrayToEntityCollection(entity); var table = SchemaGetOrCreate <T>(service.Info); service.PopulateAutoPopulatedAttributes(entity, true); if (entity.Id == Guid.Empty) { entity.Id = Guid.NewGuid(); } table.Insert(entity); CreateActivityPointer(service, entity); return(entity.Id); }
/// <summary> /// This is a hackish method but no time to improve... /// </summary> /// <typeparam name="T"></typeparam> /// <param name="service"></param> /// <param name="fe"></param> /// <returns></returns> public static EntityCollection ReadFetchXmlEntities <T>(LocalCrmDatabaseOrganizationService service, FetchType fe) where T : Entity { var entities = ReadEntities <T>(service, ConvertFetchToQueryExpression(service, fe)); return(fe.aggregateSpecified ? PerformAggregation <T>(entities, fe) : entities); }
/// <summary> /// Contact and Account Ids are populated by the customer id property. Handle hydrating values. /// </summary> private static void AutoPopulateOpportunityFields <T>(LocalCrmDatabaseOrganizationService service, T entity, bool isCreate) where T : Entity { if (entity.LogicalName != Opportunity.EntityLogicalName) { return; } var customer = entity.GetAttributeValue <EntityReference>(Opportunity.Fields.CustomerId); var opp = isCreate ? new Entity() : service.Retrieve(Opportunity.EntityLogicalName, entity.Id, new ColumnSet(Opportunity.Fields.ParentAccountId, Opportunity.Fields.ParentContactId)); var parentName = "parent" + customer?.LogicalName + "id"; // Customer was set, set correct parent field to customer if (customer != null && !entity.Contains(parentName)) { entity[parentName] = customer; } var hadAccount = opp.GetAttributeValue <EntityReference>(Opportunity.Fields.ParentAccountId) != null; var hadContact = opp.GetAttributeValue <EntityReference>(Opportunity.Fields.ParentContactId) != null; // Customer was cleared, set correct parent field to null; if (entity.ContainsNullValue("customerid")) { if (hadAccount) { entity[Opportunity.Fields.ParentAccountId] = null; } else if (hadContact) { entity[Opportunity.Fields.ParentContactId] = null; } } var hasAccount = entity.GetAttributeValue <EntityReference>(Opportunity.Fields.ParentAccountId) != null; var hasContact = entity.GetAttributeValue <EntityReference>(Opportunity.Fields.ParentContactId) != null; var willHaveAccount = hasAccount || hadAccount && !entity.ContainsNullValue(Opportunity.Fields.ParentAccountId); var willHaveContact = hasContact || hadContact && !entity.ContainsNullValue(Opportunity.Fields.ParentContactId); if (hasAccount) { entity[Opportunity.Fields.CustomerId] = entity[Opportunity.Fields.ParentAccountId]; } else if (hasContact && !willHaveAccount) { entity[Opportunity.Fields.CustomerId] = entity[Opportunity.Fields.ParentContactId]; } if (!willHaveAccount && willHaveContact) { entity[Opportunity.Fields.CustomerId] = entity.GetAttributeValue <EntityReference>(Opportunity.Fields.ParentContactId) ?? opp.GetAttributeValue <EntityReference>(Opportunity.Fields.ParentContactId); } else if (!willHaveAccount) { entity[Opportunity.Fields.CustomerId] = null; } }
private static void ProcessFetchXmlItem(LocalCrmDatabaseOrganizationService service, LinkEntity entityLink, object item) { throw new NotSupportedException("Item type " + item.GetType().Name + " Not Supported"); }
// ReSharper disable UnusedParameter.Local // ReSharper disable once UnusedMember.Local private static void ProcessFetchXmlItem(LocalCrmDatabaseOrganizationService service, LinkEntity entityLink, FetchOrderType order) { // Ignore }
private static void AddToFilter(LocalCrmDatabaseOrganizationService service, Type entityType, Dictionary <String, LinkEntity> links, FilterExpression criteria, filter item) { criteria.AddFilter(GetFilterExpression(service, entityType, links, item)); }
// ReSharper disable UnusedParameter.Local private static void AddToFilter(LocalCrmDatabaseOrganizationService service, Type entityType, Dictionary <String, LinkEntity> links, FilterExpression criteria, object item) // ReSharper restore UnusedParameter.Local { // Do nothing. Should this error? }
private static IClientSideOrganizationService GetLocalCrmDatabaseOrganizationService(string organizationName, Guid impersonationUserId) { // Create a unique Database for each Unit Test by looking up the first method in the stack trace that has a TestMethodAttribute, // and using it's method handle, combined with the OrganizationName, as a unqiue Key var method = GetUnitTestMethod() ?? MethodBase.GetCurrentMethod(); string databaseKey = String.Format("UnitTest {0}:{1}:{2}", method.Name, organizationName, method.MethodHandle); var info = LocalCrmDatabaseInfo.Create(TestSettings.EarlyBound.Assembly, TestSettings.EarlyBound.Namespace, databaseKey, impersonationUserId); var service = new LocalCrmDatabaseOrganizationService(info); // Create BU and SystemUser for currently executing user var bu = new Entity(BusinessUnit.EntityLogicalName) { [BusinessUnit.Fields.Name] = "Currently Executing BusinessUnit" }; bu.Id = service.Create(bu); var id = service.Create(new Entity(SystemUser.EntityLogicalName) { [SystemUser.Fields.FirstName] = Environment.UserDomainName.Split('/').First(), [SystemUser.Fields.LastName] = Environment.UserName, [SystemUser.Fields.BusinessUnitId] = bu.ToEntityReference(), }.ToSdkEntity()); info = LocalCrmDatabaseInfo.Create(TestSettings.EarlyBound.Assembly, TestSettings.EarlyBound.Namespace, databaseKey, id, impersonationUserId, bu.Id); return new LocalCrmDatabaseOrganizationService(info); }