diff --git a/src/XrmMockupShared/Core.cs b/src/XrmMockupShared/Core.cs index 3c6fe401..6890d18b 100644 --- a/src/XrmMockupShared/Core.cs +++ b/src/XrmMockupShared/Core.cs @@ -145,6 +145,7 @@ private void InitializeDB() { new RetrieveAllOptionSetsRequestHandler(this, db, metadata, security), new RetrieveOptionSetRequestHandler(this, db, metadata, security), new RetrieveExchangeRateRequestHandler(this, db, metadata, security), + new QualifyLeadRequestHandler(this, db, metadata, security), new CloseIncidentRequestHandler(this, db, metadata, security), new AddMembersTeamRequestHandler(this, db, metadata, security), new RemoveMembersTeamRequestHandler(this, db, metadata, security), diff --git a/src/XrmMockupShared/Requests/QualifyLeadRequestHandler.cs b/src/XrmMockupShared/Requests/QualifyLeadRequestHandler.cs new file mode 100644 index 00000000..324e0891 --- /dev/null +++ b/src/XrmMockupShared/Requests/QualifyLeadRequestHandler.cs @@ -0,0 +1,238 @@ +using DG.Tools.XrmMockup; +using DG.Tools.XrmMockup.Database; +using Microsoft.Crm.Sdk.Messages; +using Microsoft.Xrm.Sdk; +using Microsoft.Xrm.Sdk.Messages; +using Microsoft.Xrm.Sdk.Metadata; +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel; + +namespace DG.Tools.XrmMockup +{ + internal class QualifyLeadRequestHandler : RequestHandler + { + private readonly Dictionary leadToAccountAttributesMap = new Dictionary + { + { "sic", "sic" }, + { "emailaddress1", "emailaddress1" }, + { "companyname", "name" }, + { "fax", "fax" }, + { "websiteurl", "websiteurl" }, + { "address1_country", "address1_country" }, + { "address1_city", "address1_city" }, + { "address1_line1", "address1_line1" }, + { "address1_line2", "address1_line2" }, + { "address1_line3", "address1_line3" }, + { "address1_postalcode", "address1_postalcode" }, + { "address1_stateorprovince", "address1_stateorprovince" }, + { "telephone2", "telephone2" }, + { "donotpostalmail", "donotpostalmail" }, + { "donotphone", "donotphone" }, + { "donotfax", "donotfax" }, + { "donotsendmm", "donotsendmm" }, + { "description", "description" }, + { "donotemail", "donotemail" }, + { "yomicompanyname", "yominame" }, + { "donotbulkemail", "donotbulkemail" } + }; + + private readonly Dictionary leadToContactAttributesMap = new Dictionary + { + { "mobilephone", "mobilephone" }, + { "emailaddress1", "emailaddress1" }, + { "emailaddress3", "emailaddress3" }, + { "websiteurl", "websiteurl" }, + { "yomilastname", "yomilastname" }, + { "lastname", "lastname" }, + { "donotpostalmail", "donotpostalmail" }, + { "donotphone", "donotphone" }, + { "yomimiddlename", "yomimiddlename" }, + { "description", "description" }, + { "firstname", "firstname" }, + { "donotemail", "donotemail" }, + { "address1_stateorprovince", "address1_stateorprovince" }, + { "address2_county", "address2_county" }, + { "donotfax", "donotfax" }, + { "donotsendmm", "donotsendmm" }, + { "jobtitle", "jobtitle" }, + { "pager", "pager" }, + { "address1_country", "address1_country" }, + { "address1_line1", "address1_line1" }, + { "address1_line2", "address1_line2" }, + { "address1_line3", "address1_line3" }, + { "telephone2", "telephone2" }, + { "telephone3", "telephone3" }, + { "address2_fax", "address2_fax" }, + { "donotbulkemail", "donotbulkemail" }, + { "emailaddress2", "emailaddress2" }, + { "fax", "fax" }, + { "yomifirstname", "yomifirstname" }, + { "address1_postalcode", "address1_postalcode" }, + { "address1_city", "address1_city" }, + { "address2_country", "address2_country" } + }; + + private readonly Dictionary leadToOpportunityAttributesMap = new Dictionary + { + { "subject", "name" }, + { "qualificationcomments", "qualificationcomments" }, + { "description", "description" } + }; + + internal QualifyLeadRequestHandler(Core core, XrmDb db, MetadataSkeleton metadata, Security security) : base(core, db, metadata, security, "QualifyLead") + { + } + + internal override OrganizationResponse Execute(OrganizationRequest orgRequest, EntityReference userRef) + { + var request = MakeRequest(orgRequest); + + if (request.LeadId == null) + { + throw new FaultException("Required field 'LeadId' is missing"); + } + + var leadMetadata = metadata.EntityMetadata.GetMetadata(request.LeadId.LogicalName); + + if (leadMetadata == null) + { + throw new FaultException($"The entity with a name = '{request.LeadId.LogicalName}' was not found in the MetadataCache."); + } + + if (request.OpportunityCurrencyId != null) + { + var currencyMetadata = metadata.EntityMetadata.GetMetadata(request.OpportunityCurrencyId.LogicalName); + if (currencyMetadata == null) + { + throw new FaultException($"The entity with a name = '{request.OpportunityCurrencyId.LogicalName}' was not found in the MetadataCache."); + } + } + + EntityMetadata customerMetadata = null; + if (request.OpportunityCustomerId != null) + { + customerMetadata = metadata.EntityMetadata.GetMetadata(request.OpportunityCustomerId.LogicalName); + if (customerMetadata == null) + { + throw new FaultException($"The entity with a name = '{request.OpportunityCustomerId.LogicalName}' was not found in the MetadataCache."); + } + } + + var leadRow = db.GetDbRow(request.LeadId); + + if (leadRow == null || request.LeadId.LogicalName != LogicalNames.Lead) + { + throw new FaultException($"{LogicalNames.Lead} With Id = {request.LeadId.Id} Does Not Exist"); + } + + var currentState = leadRow.GetColumn("statecode"); + + if (currentState == 1) + { + throw new FaultException($"The {LogicalNames.Lead} is already closed."); + } + + var status = request.Status != null ? request.Status.Value : 0; + var statusOptionMetadata = Utility.GetStatusOptionMetadata(leadMetadata) + .FirstOrDefault(s => s.Value == status) as StatusOptionMetadata; + + if (statusOptionMetadata == null) + { + throw new FaultException($"{status} is not a valid status code on lead with Id {request.LeadId.Id}"); + } + + if (statusOptionMetadata.State != 1) + { + throw new FaultException($"{request.Status.Value} is not a valid status code for state code LeadState.Qualified lead with Id {request.LeadId.Id}"); + } + + var createdEntities = new EntityReferenceCollection(); + + var lead = leadRow.ToEntity(); + + if (request.CreateAccount) + { + createdEntities.Add(CreateEntityFromLead(lead, LogicalNames.Account, leadToAccountAttributesMap, userRef).ToEntityReference()); + } + + if (request.CreateContact) + { + createdEntities.Add(CreateEntityFromLead(lead, LogicalNames.Contact, leadToContactAttributesMap, userRef).ToEntityReference()); + } + + if (request.CreateOpportunity) + { + createdEntities.Add(CreateOpportunityFromLead(lead, request.OpportunityCustomerId, request.OpportunityCurrencyId, userRef).ToEntityReference()); + } + + lead["statuscode"] = status; + db.Update(lead); + + var resp = new QualifyLeadResponse(); + resp.Results["CreatedEntities"] = createdEntities; + return resp; + } + + private Entity CreateOpportunityFromLead(Entity lead, EntityReference customer, EntityReference currency, EntityReference userRef) + { + if (customer != null) + { + if (customer.LogicalName != LogicalNames.Account && + customer.LogicalName != LogicalNames.Contact) + { + throw new FaultException($"CustomerIdType for {LogicalNames.Opportunity} can either be an {LogicalNames.Account} or {LogicalNames.Contact}"); + } + } + var opportunity = new Entity(LogicalNames.Opportunity); + MapAttributesFromLead(lead, leadToOpportunityAttributesMap, ref opportunity); + opportunity["originatingleadid"] = lead.ToEntityReference(); + + if (customer != null) + { + opportunity["customerid"] = customer; + } + + if(currency != null) + { + opportunity["transactioncurrencyid"] = currency; + } + + opportunity.Id = CreateEntity(opportunity, userRef); + + return opportunity; + } + + private Entity CreateEntityFromLead(Entity lead, string newEntityLogicalName, IDictionary attributesMap, EntityReference userRef) + { + var newEntity = new Entity(newEntityLogicalName); + + MapAttributesFromLead(lead, attributesMap, ref newEntity); + + newEntity["originatingleadid"] = lead.ToEntityReference(); + + newEntity.Id = CreateEntity(newEntity, userRef); + return newEntity; + } + + private void MapAttributesFromLead(Entity lead, IDictionary attributesMap, ref Entity toEntity) + { + foreach(var attr in attributesMap) + { + if(lead.Attributes.Contains(attr.Key)) + toEntity[attr.Value] = lead[attr.Key]; + } + } + + private Guid CreateEntity(Entity entity, EntityReference userRef) + { + var req = new CreateRequest + { + Target = entity + }; + var response = core.Execute(req, userRef) as CreateResponse; + return response.id; + } + } +} \ No newline at end of file diff --git a/src/XrmMockupShared/Utility.cs b/src/XrmMockupShared/Utility.cs index d1a80035..179f414c 100644 --- a/src/XrmMockupShared/Utility.cs +++ b/src/XrmMockupShared/Utility.cs @@ -304,16 +304,6 @@ internal static void CheckStatusTransitions(EntityMetadata metadata, Entity newE throw new FaultException($"Trying to switch {newEntity.LogicalName} from status {prevValue.Value} to {newValue.Value}"); } - internal static OptionMetadata GetStateOptionMetadataFromInvariantName(string stateInvariantName, EntityMetadata entityMetadata) - { - var stateOptionMeta = (entityMetadata.Attributes - .FirstOrDefault(a => a is StateAttributeMetadata) as StateAttributeMetadata) - .OptionSet - .Options; - - return stateOptionMeta.FirstOrDefault(o => (o as StateOptionMetadata).InvariantName == stateInvariantName); - } - internal static bool IsValidStatusTransition(string transitionData, int newStatusCode) { var ns = XNamespace.Get("http://schemas.microsoft.com/crm/2009/WebServices"); @@ -333,6 +323,16 @@ internal static OptionMetadataCollection GetStatusOptionMetadata(EntityMetadata .FirstOrDefault(a => a is StatusAttributeMetadata) as StatusAttributeMetadata) .OptionSet.Options; } + + internal static OptionMetadata GetStateOptionMetadataFromInvariantName(string stateInvariantName, EntityMetadata entityMetadata) + { + var stateOptionMeta = (entityMetadata.Attributes + .FirstOrDefault(a => a is StateAttributeMetadata) as StateAttributeMetadata) + .OptionSet + .Options; + + return stateOptionMeta.FirstOrDefault(o => (o as StateOptionMetadata).InvariantName == stateInvariantName); + } internal static EntityReference GetBaseCurrency(MetadataSkeleton metadata) { @@ -921,6 +921,7 @@ internal static Entity ToActivityPointer(this Entity entity) internal class LogicalNames { + public const string Account = "account"; public const string TransactionCurrency = "transactioncurrency"; public const string BusinessUnit = "businessunit"; public const string SystemUser = "systemuser"; diff --git a/src/XrmMockupShared/XrmMockupShared.projitems b/src/XrmMockupShared/XrmMockupShared.projitems index 4149f5ea..3219465f 100644 --- a/src/XrmMockupShared/XrmMockupShared.projitems +++ b/src/XrmMockupShared/XrmMockupShared.projitems @@ -20,6 +20,7 @@ + diff --git a/tests/SharedTests/SharedTests.projitems b/tests/SharedTests/SharedTests.projitems index 4ba123c7..0be87e3b 100644 --- a/tests/SharedTests/SharedTests.projitems +++ b/tests/SharedTests/SharedTests.projitems @@ -12,6 +12,7 @@ + diff --git a/tests/SharedTests/TestLeads.cs b/tests/SharedTests/TestLeads.cs new file mode 100644 index 00000000..4668b914 --- /dev/null +++ b/tests/SharedTests/TestLeads.cs @@ -0,0 +1,809 @@ +using System; +using System.Text; +using System.Collections.Generic; +using DG.Some.Namespace; +using System.Linq; +using DG.XrmMockupTest; +using Microsoft.Xrm.Sdk; +using System.Diagnostics; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.Xrm.Sdk.Query; +using System.ServiceModel; +using Microsoft.Xrm.Sdk.Messages; +using DG.XrmFramework.BusinessDomain.ServiceContext; +using Microsoft.Crm.Sdk.Messages; + +namespace DG.XrmMockupTest +{ + [TestClass] + public class TestLeads : UnitTestBase + { + [TestMethod] + public void TestQualifyLeadRequestLeadIdMissingFails() + { + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified) + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestLeadIdNotExistingFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead", + Id = Guid.NewGuid() + }; + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestOpportunityCurrencyIdWrongLogicalNameFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead" + }; + + lead.Id = orgAdminUIService.Create(lead); + + var currency = new Entity + { + LogicalName = "Wrong Logical Name", + Id = Guid.NewGuid() + }; + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + OpportunityCurrencyId = currency.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestOpportunityCustomerIdNotExistingFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead" + }; + + lead.Id = orgAdminUIService.Create(lead); + + var customer = new Account() + { + Id = Guid.NewGuid() + }; + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + CreateOpportunity = true, + OpportunityCustomerId = customer.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestLeadNotExistingFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead", + Id = Guid.NewGuid() + }; + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestLeadWrongLogicalNameFails() + { + var account = new Account(); + + account.Id = orgAdminUIService.Create(account); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = account.ToEntityReference(), + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestLeadAlreadyClosedFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead" + }; + + lead.Id = orgAdminUIService.Create(lead); + +#if (XRM_MOCKUP_TEST_2011 || XRM_MOCKUP_TEST_2013) + lead.SetState(orgAdminUIService, LeadState.Qualified, Lead_StatusCode.Qualified); +#else + lead.StateCode = LeadState.Qualified; + lead.StatusCode = Lead_StatusCode.Qualified; + orgAdminUIService.Update(lead); +#endif + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestInvalidStatusCodeFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead" + }; + + lead.Id = orgAdminUIService.Create(lead); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue(9999), + LeadId = lead.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestStateNotQualifiedFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead" + }; + + lead.Id = orgAdminUIService.Create(lead); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Canceled), + LeadId = lead.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestCreateOpportunityOpportunityCustomerIdWrongLogicalNameFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead" + }; + + lead.Id = orgAdminUIService.Create(lead); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + CreateOpportunity = true, + OpportunityCustomerId = lead.ToEntityReference(), + LeadId = lead.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestCreateOpportunityOpportunityCustomerIdDoesNotExistFails() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead" + }; + + lead.Id = orgAdminUIService.Create(lead); + + var contact = new Contact + { + FirstName = "Test", + LastName = "Lead", + Id = Guid.NewGuid() + }; + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + CreateOpportunity = true, + OpportunityCustomerId = contact.ToEntityReference(), + LeadId = lead.ToEntityReference() + }; + try + { + orgAdminUIService.Execute(request); + Assert.Fail(); + } + catch (Exception e) + { + Assert.IsInstanceOfType(e, typeof(FaultException)); + } + } + + [TestMethod] + public void TestQualifyLeadRequestSuccess() + { + var lead = new Lead + { + FirstName = "Test", + LastName = "Lead" + }; + + lead.Id = orgAdminUIService.Create(lead); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference() + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 0); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + } + + [TestMethod] + public void TestQualifyLeadRequestOpportunityCurrencyIdSuccess() + { + var lead = GetLeadWithAttributes(); + var currency = new TransactionCurrency() + { + ExchangeRate = 0.5m, + CurrencyPrecision = 2 + }; + + lead.Id = orgAdminUIService.Create(lead); + currency.Id = orgAdminUIService.Create(currency); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + OpportunityCurrencyId = currency.ToEntityReference() + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 0); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + } + + [TestMethod] + public void TestQualifyLeadRequestOpportunityCustomerIdSuccess() + { + var lead = GetLeadWithAttributes(); + + var account = new Account(); + lead.Id = orgAdminUIService.Create(lead); + account.Id = orgAdminUIService.Create(account); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + OpportunityCustomerId = account.ToEntityReference() + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 0); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + } + + [TestMethod] + public void TestQualifyLeadRequestCreateAccountSuccess() + { + var lead = GetLeadWithAttributes(); + lead.Id = orgAdminUIService.Create(lead); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + CreateAccount = true + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 1); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + + var accountId = createdEntities.First(e => e.LogicalName == Account.EntityLogicalName).Id; + var account = orgAdminUIService.Retrieve(Account.EntityLogicalName, accountId, new ColumnSet(true)) as Account; + + Assert.IsNotNull(account); + AssertAccountMatchesLead(account, lead); + } + + [TestMethod] + public void TestQualifyLeadRequestCreateContactSuccess() + { + var lead = GetLeadWithAttributes(); + lead.Id = orgAdminUIService.Create(lead); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + CreateContact = true + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 1); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + + var contactId = createdEntities.First(e => e.LogicalName == Contact.EntityLogicalName).Id; + var contact = orgAdminUIService.Retrieve(Contact.EntityLogicalName, contactId, new ColumnSet(true)) as Contact; + + Assert.IsNotNull(contact); + AssertContactMatchesLead(contact, lead); + } + + [TestMethod] + public void TestQualifyLeadRequestCreateOpportunitySuccess() + { + var lead = GetLeadWithAttributes(); + lead.Id = orgAdminUIService.Create(lead); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + CreateOpportunity = true + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 1); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + + var opportunityId = createdEntities.First(e => e.LogicalName == Opportunity.EntityLogicalName).Id; + var opportunity = orgAdminUIService.Retrieve(Opportunity.EntityLogicalName, opportunityId, new ColumnSet(true)) as Opportunity; + + Assert.IsNotNull(opportunity); + AssertOpportunityMatchesLead(opportunity, lead); + } + + [TestMethod] + public void TestQualifyLeadRequestCreateOpportunityCurrencySuccess() + { + var lead = GetLeadWithAttributes(); + lead.Id = orgAdminUIService.Create(lead); + + var currency = new TransactionCurrency() + { + ExchangeRate = 0.5m, + CurrencyPrecision = 2 + }; + + currency.Id = orgAdminUIService.Create(currency); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + CreateOpportunity = true, + OpportunityCurrencyId = currency.ToEntityReference() + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 1); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + + var opportunityId = createdEntities.First(e => e.LogicalName == Opportunity.EntityLogicalName).Id; + var opportunity = orgAdminUIService.Retrieve(Opportunity.EntityLogicalName, opportunityId, new ColumnSet(true)) as Opportunity; + + Assert.IsNotNull(opportunity); + AssertOpportunityMatchesLead(opportunity, lead); + } + + [TestMethod] + public void TestQualifyLeadRequestCreateOpportunityCustomerAccountSuccess() + { + var lead = GetLeadWithAttributes(); + lead.Id = orgAdminUIService.Create(lead); + + var account = new Account(); + account.Id = orgAdminUIService.Create(account); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + CreateOpportunity = true, + OpportunityCustomerId = account.ToEntityReference(), + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 1); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + + var opportunityId = createdEntities.First(e => e.LogicalName == Opportunity.EntityLogicalName).Id; + var opportunity = orgAdminUIService.Retrieve(Opportunity.EntityLogicalName, opportunityId, new ColumnSet(true)) as Opportunity; + + Assert.IsNotNull(opportunity); + AssertOpportunityMatchesLead(opportunity, lead, account); + } + + [TestMethod] + public void TestQualifyLeadRequestCreateOpportunityCustomerContactSuccess() + { + var lead = GetLeadWithAttributes(); + lead.Id = orgAdminUIService.Create(lead); + + var contact = new Contact(); + contact.Id = orgAdminUIService.Create(contact); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + CreateOpportunity = true, + OpportunityCustomerId = contact.ToEntityReference() + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 1); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + + var opportunityId = createdEntities.First(e => e.LogicalName == Opportunity.EntityLogicalName).Id; + var opportunity = orgAdminUIService.Retrieve(Opportunity.EntityLogicalName, opportunityId, new ColumnSet(true)) as Opportunity; + + Assert.IsNotNull(opportunity); + AssertOpportunityMatchesLead(opportunity, lead, contact); + } + + [TestMethod] + public void TestQualifyLeadRequestCreateAllSuccess() + { + var lead = GetLeadWithAttributes(); + lead.Id = orgAdminUIService.Create(lead); + + var customer = new Contact(); + customer.Id = orgAdminUIService.Create(customer); + + var currency = new TransactionCurrency() + { + ExchangeRate = 0.5m, + CurrencyPrecision = 2 + }; + + currency.Id = orgAdminUIService.Create(currency); + + var request = new QualifyLeadRequest + { + Status = new OptionSetValue((int)Lead_StatusCode.Qualified), + LeadId = lead.ToEntityReference(), + CreateOpportunity = true, + CreateAccount = true, + CreateContact = true, + OpportunityCustomerId = customer.ToEntityReference(), + OpportunityCurrencyId = currency.ToEntityReference() + }; + + var response = orgAdminUIService.Execute(request) as QualifyLeadResponse; + Assert.IsNotNull(response); + var createdEntities = response.CreatedEntities; + Assert.IsNotNull(createdEntities); + Assert.IsTrue(createdEntities.Count == 3); + + var qualifiedLead = orgAdminUIService.Retrieve(Lead.EntityLogicalName, lead.Id, new ColumnSet(true)) as Lead; + + Assert.IsNotNull(qualifiedLead); + Assert.AreEqual(Lead_StatusCode.Qualified, qualifiedLead.StatusCode); + + var opportunityId = createdEntities.First(e => e.LogicalName == Opportunity.EntityLogicalName).Id; + var opportunity = orgAdminUIService.Retrieve(Opportunity.EntityLogicalName, opportunityId, new ColumnSet(true)) as Opportunity; + Assert.IsNotNull(opportunity); + AssertOpportunityMatchesLead(opportunity, lead, customer, currency); + + var contactId = createdEntities.First(e => e.LogicalName == Contact.EntityLogicalName).Id; + var contact = orgAdminUIService.Retrieve(Contact.EntityLogicalName, contactId, new ColumnSet(true)) as Contact; + AssertContactMatchesLead(contact, lead); + + var accountId = createdEntities.First(e => e.LogicalName == Account.EntityLogicalName).Id; + var account = orgAdminUIService.Retrieve(Account.EntityLogicalName, accountId, new ColumnSet(true)) as Account; + AssertAccountMatchesLead(account, lead); + } + + private Lead GetLeadWithAttributes() + { + return new Lead + { + FirstName = "Test", + LastName = "Lead", + Subject = "Subject", + SIC = "SIC", + EMailAddress1 = "EMailAddress1", + CompanyName = "CompanyName", + Fax = "Fax", + WebSiteUrl = "WebSiteUrl", + Address1_Country = "Address1_Country", + Address1_City = "Address1_City", + Address1_Line1 = "Address1_Line1", + Address1_Line2 = "Address1_Line2", + Address1_Line3 = "Address1_Line3", + Address1_PostalCode = "Address1_PostalCode", + Address1_StateOrProvince = "Address1_StateOrProvince", + Telephone2 = "Telephone2", + DoNotPostalMail = true, + DoNotPhone = true, + DoNotFax = true, + DoNotSendMM = true, + Description = "Description", + DoNotEMail = true, + YomiCompanyName = "YomiCompanyName", + DoNotBulkEMail = true, + MobilePhone = "MobilePhone", + EMailAddress3 = "EMailAddress3", + YomiLastName = "YomiLastName", + YomiMiddleName = "YomiMiddleName", + Address2_Country = "Address2_Country", + JobTitle = "JobTitle", + Pager = "Pager", + Telephone3 = "Telephone3", + Address2_Fax = "Address2_Fax", + EMailAddress2 = "EMailAddress2", + YomiFirstName = "YomiFirstName", + QualificationComments = "QualificationComments" + }; + } + + private void AssertOpportunityMatchesLead(Opportunity opportunity, Lead lead, Entity customer = null, TransactionCurrency currency = null) + { + Assert.AreEqual(lead.Subject, opportunity.Name); + Assert.AreEqual(lead.QualificationComments, opportunity.QualificationComments); + Assert.AreEqual(lead.Description, opportunity.Description); + Assert.IsNotNull(opportunity.OriginatingLeadId); + Assert.AreEqual(lead.LeadId, opportunity.OriginatingLeadId.Id); + + if(customer != null) + { + Assert.IsNotNull(opportunity.CustomerId); + Assert.AreEqual(customer.Id, opportunity.CustomerId.Id); + } + + if(currency != null) + { + Assert.IsNotNull(opportunity.TransactionCurrencyId); + Assert.AreEqual(currency.Id, opportunity.TransactionCurrencyId.Id); + } + } + + private void AssertContactMatchesLead(Contact contact, Lead lead) + { + Assert.AreEqual(lead.MobilePhone, contact.MobilePhone); + Assert.AreEqual(lead.EMailAddress1, contact.EMailAddress1); + Assert.AreEqual(lead.EMailAddress3, contact.EMailAddress3); + Assert.AreEqual(lead.WebSiteUrl, contact.WebSiteUrl); + Assert.AreEqual(lead.YomiLastName, contact.YomiLastName); + Assert.AreEqual(lead.LastName, contact.LastName); + Assert.AreEqual(lead.DoNotPostalMail, contact.DoNotPostalMail); + Assert.AreEqual(lead.DoNotPhone, contact.DoNotPhone); + Assert.AreEqual(lead.YomiMiddleName, contact.YomiMiddleName); + Assert.AreEqual(lead.Description, contact.Description); + Assert.AreEqual(lead.FirstName, contact.FirstName); + Assert.AreEqual(lead.DoNotEMail, contact.DoNotEMail); + Assert.AreEqual(lead.Address1_StateOrProvince, contact.Address1_StateOrProvince); + Assert.AreEqual(lead.Address2_Country, contact.Address2_Country); + Assert.AreEqual(lead.DoNotFax, contact.DoNotFax); + Assert.AreEqual(lead.DoNotSendMM, contact.DoNotSendMM); + Assert.AreEqual(lead.JobTitle, contact.JobTitle); + Assert.AreEqual(lead.Pager, contact.Pager); + Assert.AreEqual(lead.Address1_Country, contact.Address1_Country); + Assert.AreEqual(lead.Address1_Line1, contact.Address1_Line1); + Assert.AreEqual(lead.Address1_Line2, contact.Address1_Line2); + Assert.AreEqual(lead.Address1_Line3, contact.Address1_Line3); + Assert.AreEqual(lead.Telephone2, contact.Telephone2); + Assert.AreEqual(lead.Telephone3, contact.Telephone3); + Assert.AreEqual(lead.Address2_Fax, contact.Address2_Fax); + Assert.AreEqual(lead.DoNotBulkEMail, contact.DoNotBulkEMail); + Assert.AreEqual(lead.EMailAddress2, contact.EMailAddress2); + Assert.AreEqual(lead.Fax, contact.Fax); + Assert.AreEqual(lead.YomiFirstName, contact.YomiFirstName); + Assert.AreEqual(lead.Address1_PostalCode, contact.Address1_PostalCode); + Assert.AreEqual(lead.Address1_City, contact.Address1_City); + Assert.AreEqual(lead.Address2_Country, contact.Address2_Country); + Assert.IsNotNull(contact.OriginatingLeadId); + Assert.AreEqual(lead.Id, contact.OriginatingLeadId.Id); + } + + private void AssertAccountMatchesLead(Account account, Lead lead) + { + Assert.AreEqual(lead.SIC, account.SIC); + Assert.AreEqual(lead.EMailAddress1, account.EMailAddress1); + Assert.AreEqual(lead.CompanyName, account.Name); + Assert.AreEqual(lead.Fax, account.Fax); + Assert.AreEqual(lead.WebSiteUrl, account.WebSiteURL); + Assert.AreEqual(lead.Address1_City, account.Address1_City); + Assert.AreEqual(lead.Address1_Country, account.Address1_Country); + Assert.AreEqual(lead.Address1_Line1, account.Address1_Line1); + Assert.AreEqual(lead.Address1_Line2, account.Address1_Line2); + Assert.AreEqual(lead.Address1_Line3, account.Address1_Line3); + Assert.AreEqual(lead.Address1_PostalCode, account.Address1_PostalCode); + Assert.AreEqual(lead.Address1_StateOrProvince, account.Address1_StateOrProvince); + Assert.AreEqual(lead.Telephone2, account.Telephone2); + Assert.AreEqual(lead.DoNotPostalMail, account.DoNotPostalMail); + Assert.AreEqual(lead.DoNotPhone, account.DoNotPhone); + Assert.AreEqual(lead.DoNotFax, account.DoNotFax); + Assert.AreEqual(lead.DoNotSendMM, account.DoNotSendMM); + Assert.AreEqual(lead.Description, account.Description); + Assert.AreEqual(lead.DoNotEMail, account.DoNotEMail); + Assert.AreEqual(lead.YomiCompanyName, account.YomiName); + Assert.AreEqual(lead.DoNotBulkEMail, account.DoNotBulkEMail); + Assert.IsNotNull(account.OriginatingLeadId); + Assert.AreEqual(lead.Id, account.OriginatingLeadId.Id); + } + } +}