コード例 #1
0
        public async Task <StatusCodes> CallAddInWebhookAsync(Opportunity opportunity, string requestId = "")
        {
            var client = await proposalManagerClientFactory.GetProposalManagerClientAsync();

            var result = await client.PostAsync("/api/dynamics/LinkSharePointLocations", new StringContent(JsonConvert.SerializeObject(await opportunityHelpers.OpportunityToViewModelAsync(opportunity, requestId)), Encoding.UTF8, "application/json"));

            return(result.IsSuccessStatusCode ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest);
        }
コード例 #2
0
        public async Task <IActionResult> CreateOpportunityAsync(string @event, [FromBody] JObject data)
        {
            if (string.IsNullOrWhiteSpace(@event))
            {
                return(BadRequest($"{nameof(@event)} is required"));
            }
            else if ([email protected]("create", StringComparison.InvariantCultureIgnoreCase))
            {
                return(BadRequest($"{@event} is not supported"));
            }
            else if (data["InputParameters"] == null)
            {
                return(BadRequest($"Payload is malformed"));
            }

            var opportunityMapping = dynamicsConfiguration.OpportunityMapping;

            try
            {
                var jopp = data["InputParameters"].First()["value"];

                if (!jopp["LogicalName"].ToString().Equals(opportunityMapping.EntityName, StringComparison.OrdinalIgnoreCase))
                {
                    _logger.LogError($"DYNAMICS INTEGRATION ENGINE: Incorrect entity type recieved from opportunity creation. Expected ${opportunityMapping.EntityName}, got {jopp["LogicalName"].ToString()}.");
                    return(BadRequest());
                }

                var opportunityId = jopp["Id"].ToString();

                jopp = jopp["Attributes"];
                var attributes = jopp.ToDictionary(p => p["key"], v => v["value"]);

                var opportunityName = GetAttribute(attributes, opportunityMapping.NameProperty)?.ToString();
                var creator         = dynamicsLinkService.GetUserData(data["InitiatingUserId"].ToString());
                var creatorRole     = proposalManagerConfiguration.CreatorRole;

                //Determine customer name
                string customerDisplayName = string.Empty;
                var    customer            = GetAttribute(attributes, "customerid");

                if (customer != null)
                {
                    if (customer["LogicalName"].ToString() == "account")
                    {
                        customerDisplayName = dynamicsLinkService.GetAccountName(customer["Id"].ToString());
                    }
                    else if (customer["LogicalName"].ToString() == "contact")
                    {
                        customerDisplayName = dynamicsLinkService.GetContactName(customer["Id"].ToString());
                    }
                }

                var opp = new OpportunityViewModel
                {
                    Reference        = opportunityId,
                    DisplayName      = opportunityName,
                    OpportunityState = OpportunityStateModel.FromValue(opportunityMapping.MapStatusCode((int)GetAttribute(attributes, "statuscode"))),
                    Customer         = new CustomerModel
                    {
                        DisplayName = customerDisplayName
                    },

                    TeamMembers = new TeamMemberModel[]
                    {
                        new TeamMemberModel
                        {
                            DisplayName       = creator.DisplayName,
                            Id                = creator.Id,
                            Mail              = creator.Email,
                            UserPrincipalName = creator.Email,
                            RoleName          = creatorRole.DisplayName,
                            RoleId            = creatorRole.Id,
                            TeamsMembership   = new TeamsMembershipModel()
                            {
                                Name  = "Member",
                                Value = 1
                            }
                        }
                    },
                    Checklists = Array.Empty <ChecklistModel>()
                };

                var proposalManagerClient = await proposalManagerClientFactory.GetProposalManagerClientAsync();

                var metaDataResult = await proposalManagerClient.GetAsync("/api/MetaData");

                if (!metaDataResult.IsSuccessStatusCode)
                {
                    _logger.LogError("DYNAMICS INTEGRATION ENGINE: Proposal Manager did not return a success status code on metadata request.");
                    return(BadRequest());
                }
                var metadataList = await metaDataResult.Content.ReadAsAsync <List <MetaDataModel> >();

                opp.MetaDataFields = new List <OpportunityMetaDataFields>();

                foreach (var metadata in metadataList)
                {
                    var mappingName = opportunityMapping.MetadataFields.FirstOrDefault(x => x.To == metadata.DisplayName);

                    if (mappingName != null)
                    {
                        opp.MetaDataFields.Add(new OpportunityMetaDataFields
                        {
                            DisplayName = metadata.DisplayName,
                            Values      = GetAttribute(attributes, mappingName.From, metadata.FieldType),
                            FieldType   = metadata.FieldType,
                            Screen      = metadata.Screen
                        });
                    }
                }

                var userProfileResult = await proposalManagerClient.GetAsync($"/api/UserProfile?upn={creator.Email}");

                if (!userProfileResult.IsSuccessStatusCode)
                {
                    _logger.LogError("DYNAMICS INTEGRATION ENGINE: Proposal Manager did not return a success status code on user query request.");
                    return(BadRequest());
                }

                var userProfile = JsonConvert.DeserializeObject <UserProfileViewModel>(await userProfileResult.Content.ReadAsStringAsync());
                if (!userProfile.UserRoles.Any(ur => ur.AdGroupName == creatorRole.AdGroupName))
                {
                    return(BadRequest($"{creator.Email} is not a member of role {creatorRole.AdGroupName}."));
                }

                var remoteEndpoint = $"/api/Opportunity";
                var result         = await proposalManagerClient.PostAsync(remoteEndpoint, new StringContent(JsonConvert.SerializeObject(opp), Encoding.UTF8, "application/json"));

                if (result.IsSuccessStatusCode)
                {
                    await dynamicsLinkService.CreateTemporaryLocationForOpportunityAsync(opportunityId, opportunityName);

                    return(Ok());
                }
                else
                {
                    _logger.LogError("DYNAMICS INTEGRATION ENGINE: Proposal Manager did not return a success status code.");
                    return(BadRequest());
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message);
                _logger.LogError(ex.StackTrace);
                return(BadRequest());
            }
        }
コード例 #3
0
        public async Task <IActionResult> CreateOpportunityAsync(string @event, [FromBody] JObject data)
        {
            if (!string.IsNullOrWhiteSpace(@event) && @event.Equals("create", StringComparison.InvariantCultureIgnoreCase))
            {
                try
                {
                    var jopp = data["InputParameters"].First()["value"]["Attributes"];

                    var attributes = jopp.ToDictionary(p => p["key"], v => v["value"]);

                    var opportunityMapping = dynamicsConfiguration.OpportunityMapping;
                    var opportunityName    = GetAttribute(attributes, opportunityMapping.DisplayName)?.ToString();
                    var opportunityId      = GetAttribute(attributes, "opportunityid").ToString();
                    var creator            = dynamicsLinkService.GetUserData(data["InitiatingUserId"].ToString());
                    var creatorRole        = proposalManagerConfiguration.CreatorRole;
                    var opp = new OpportunityViewModel
                    {
                        Reference        = opportunityId,
                        DisplayName      = opportunityName,
                        OpportunityState = OpportunityStateModel.FromValue(opportunityMapping.MapStatusCode((int)GetAttribute(attributes, "statuscode")["Value"])),
                        Customer         = new CustomerModel
                        {
                            DisplayName = dynamicsLinkService.GetAccountName(GetAttribute(attributes, "customerid")?["Id"].ToString())
                        },
                        DealSize             = (double?)GetAttribute(attributes, opportunityMapping.DealSize) ?? 0,
                        AnnualRevenue        = (double?)GetAttribute(attributes, opportunityMapping.AnnualRevenue) ?? 0,
                        OpenedDate           = DateTimeOffset.TryParse(GetAttribute(attributes, opportunityMapping.OpenedDate)?.ToString(), out var dto) ? dto : DateTimeOffset.Now,
                        Margin               = (double?)GetAttribute(attributes, opportunityMapping.Margin) ?? 0,
                        Rate                 = (double?)GetAttribute(attributes, opportunityMapping.Rate) ?? 0,
                        DebtRatio            = (double?)GetAttribute(attributes, opportunityMapping.DebtRatio) ?? 0,
                        Purpose              = GetAttribute(attributes, opportunityMapping.Purpose)?.ToString(),
                        DisbursementSchedule = GetAttribute(attributes, opportunityMapping.DisbursementSchedule)?.ToString(),
                        CollateralAmount     = (double?)GetAttribute(attributes, opportunityMapping.CollateralAmount) ?? 0,
                        Guarantees           = GetAttribute(attributes, opportunityMapping.Guarantees)?.ToString(),
                        RiskRating           = (int?)GetAttribute(attributes, opportunityMapping.RiskRating) ?? 0,
                        TeamMembers          = new TeamMemberModel[]
                        {
                            new TeamMemberModel
                            {
                                DisplayName       = creator.DisplayName,
                                Id                = creator.Id,
                                Mail              = creator.Email,
                                UserPrincipalName = creator.Email,
                                AssignedRole      = new RoleModel
                                {
                                    AdGroupName = creatorRole.AdGroupName,
                                    DisplayName = creatorRole.DisplayName,
                                    Id          = creatorRole.Id
                                }
                            }
                        },
                        Checklists = new ChecklistModel[] { }
                    };

                    var proposalManagerClient = await proposalManagerClientFactory.GetProposalManagerClientAsync();

                    var userProfileResult = await proposalManagerClient.GetAsync($"/api/UserProfile?upn={creator.Email}");

                    var userProfile = JsonConvert.DeserializeObject <UserProfileViewModel>(await userProfileResult.Content.ReadAsStringAsync());
                    if (!userProfile.UserRoles.Any(ur => ur.AdGroupName == creatorRole.AdGroupName))
                    {
                        return(BadRequest($"{creator.Email} is not a member of role {creatorRole.AdGroupName}."));
                    }

                    var remoteEndpoint = $"/api/Opportunity";
                    var result         = await proposalManagerClient.PostAsync(remoteEndpoint, new StringContent(JsonConvert.SerializeObject(opp), Encoding.UTF8, "application/json"));

                    if (result.IsSuccessStatusCode)
                    {
                        await dynamicsLinkService.CreateTemporaryLocationForOpportunityAsync(opportunityId, opportunityName);

                        return(Ok());
                    }
                    else
                    {
                        _logger.LogError("DYNAMICS INTEGRATION ENGINE: Proposal Manager did not return a success status code.");
                        return(BadRequest());
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.Message);
                    _logger.LogError(ex.StackTrace);
                    return(BadRequest());
                }
            }

            return(BadRequest($"{nameof(@event)} is required"));
        }
コード例 #4
0
        public async Task ProcessFormalProposalChangesAsync(string opportunityName, string resource)
        {
            var resetLink = $"https://graph.microsoft.com/v1.0{resource}/delta";
            var deltaLink = deltaLinksStorage.OpportunityDeltaLinks.ContainsKey(opportunityName) ? deltaLinksStorage.OpportunityDeltaLinks[opportunityName] : resetLink;
            var result    = ProcessDriveChangesAsync(
                ref deltaLink,
                di =>
                (
                    di.ParentReference?.Path == "/drive/root:/Formal Proposal" &&
                    di.Name.EndsWith(".docx") &&
                    true                     // change by CreatedBy check
                ),
                async batch =>
            {
                var preResult   = new List <Task>();
                var actions     = batch.Select(d => new { FileName = d.Name, OpportunityName = d.ParentReference.Path.Split('/').Last() });
                var graphClient = graphClientContext.GraphClient;
                var item        = batch.Last();

                var fileUri = $"https://graph.microsoft.com/v1.0{resource}:/Formal Proposal/{item.Name}[email protected]";

                var parts       = new Uri(fileUri).Segments;
                var partsLength = parts.Length;
                var docName     = parts[partsLength - 1];
                var oppName     = parts[partsLength - 2].Replace("/", "");
                try
                {
                    var hrm      = new HttpRequestMessage(HttpMethod.Get, fileUri);
                    var response = new HttpResponseMessage();

                    // Authenticate (add access token) to the HttpRequestMessage
                    await graphClient.AuthenticationProvider.AuthenticateRequestAsync(hrm);

                    // Send the request and get the response
                    var jsonResponse = await graphClient.HttpProvider.SendAsync(hrm);

                    var dataJson = JsonConvert.DeserializeObject <GraphMetadata>(jsonResponse.Content.ReadAsStringAsync().Result);

                    var hrmContent = new HttpRequestMessage(HttpMethod.Get, dataJson.DownloadUrl);

                    await graphClient.AuthenticationProvider.AuthenticateRequestAsync(hrmContent);

                    var responseContent = await graphClient.HttpProvider.SendAsync(hrmContent);

                    var arr = await responseContent.Content.ReadAsByteArrayAsync();

                    var fileContent = new ByteArrayContent(arr);

                    var multiContent = new MultipartFormDataContent()
                    {
                        { fileContent, "file", docName },
                        { new StringContent(opportunityName), "opportunityName" },
                        { new StringContent("ProposalTemplate"), "docType" }
                    };

                    var client = await proposalManagerClientFactory.GetProposalManagerClientAsync();

                    var pmResult = await client.PutAsync($"/api/Document/UploadFile/{opportunityName}/ProposalTemplate", multiContent);

                    if (!pmResult.IsSuccessStatusCode)
                    {
                        throw new Exception($@"DYNAMICS INTEGRATION ENGINE: Something went wrong when expecting Proposal Manager to parse the document. Relevant context is as follows:
    Opportunity: {opportunityName}
    Resource: {resource}
    Proposal Manager result: {await pmResult.Content.ReadAsStringAsync()}");
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception($@"DYNAMICS INTEGRATION ENGINE: Something went wrong when processing file changes for the opportunity specified. Relevant context is as follows:
    Opportunity: {opportunityName}
    Resource: {resource}
    [INNER EXCEPTION]:
        Message: {ex.Message}
        Stacktrace: {ex.StackTrace}", ex);
                }
            }, resetLink);

            /* This causes the next immediate request to be bypassed, given that it will correspond to the
             * file overwriting that Proposal Manager performs after analyzing the document. */
            deltaLinksStorage.OpportunityDeltaLinks.Remove(opportunityName);
            await result;
        }