public IActionResult GetAccount(string id)
        {
            _logger.LogInformation(LoggingEvents.HttpGet, "Begin method " + this.GetType().Name + "." + MethodBase.GetCurrentMethod().ReflectedType.Name);
            _logger.LogDebug(LoggingEvents.HttpGet, "id: " + id);

            Boolean userAccessToAccount = false;

            ViewModels.Account result = null;

            // query the Dynamics system to get the account record.
            if (!string.IsNullOrEmpty(id) && Guid.TryParse(id, out Guid accountId))
            {
                // verify the currently logged in user has access to this account
                try
                {
                    userAccessToAccount = UserDynamicsExtensions.CurrentUserHasAccessToAccount(accountId, _httpContextAccessor, _dynamicsClient);
                }
                catch (OdataerrorException odee)
                {
                    _logger.LogError(LoggingEvents.Error, "Error while checking if current user has access to account.");
                    _logger.LogError("Request:");
                    _logger.LogError(odee.Request.Content);
                    _logger.LogError("Response:");
                    _logger.LogError(odee.Response.Content);
                }

                if (!userAccessToAccount)
                {
                    _logger.LogWarning(LoggingEvents.NotFound, "Current user has NO access to account.");
                    return(new NotFoundResult());
                }
                List <string> expand = new List <string> {
                    "bcgov_CurrentBusinessPhysicalAddress",
                    "bcgov_CurrentBusinessMailingAddress", "bcgov_AdditionalContact", "primarycontactid"
                };
                try
                {
                    MicrosoftDynamicsCRMaccount account = _dynamicsClient.Accounts.GetByKey(accountId.ToString(), expand: expand);
                    result = account.ToViewModel();
                }
                catch (OdataerrorException)
                {
                    return(new NotFoundResult());
                }
            }
            else
            {
                _logger.LogWarning(LoggingEvents.BadRequest, "Bad Request.");
                return(BadRequest());
            }

            _logger.LogDebug(LoggingEvents.HttpGet, "Account result: " +
                             JsonConvert.SerializeObject(result, Formatting.Indented, new JsonSerializerSettings {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            }));
            return(Json(result));
        }
        public async Task <IActionResult> DeleteDynamicsAccount(string id)
        {
            _logger.LogInformation(LoggingEvents.HttpPost, "Begin method " + this.GetType().Name + "." + MethodBase.GetCurrentMethod().ReflectedType.Name);

            // verify the currently logged in user has access to this account
            Guid accountId = new Guid(id);

            if (!UserDynamicsExtensions.CurrentUserHasAccessToAccount(accountId, _httpContextAccessor, _dynamicsClient))
            {
                _logger.LogWarning(LoggingEvents.NotFound, "Current user has NO access to the account.");
                return(new NotFoundResult());
            }

            // get the account
            MicrosoftDynamicsCRMaccount account = _dynamicsClient.GetAccountByIdWithChildren(accountId);

            if (account == null)
            {
                _logger.LogWarning(LoggingEvents.NotFound, "Account NOT found.");
                return(new NotFoundResult());
            }

            try
            {
                await _dynamicsClient.Accounts.DeleteAsync(accountId.ToString());

                _logger.LogDebug(LoggingEvents.HttpDelete, "Account deleted: " + accountId.ToString());
            }
            catch (OdataerrorException odee)
            {
                _logger.LogError(LoggingEvents.Error, "Error deleting the account: " + accountId.ToString());
                _logger.LogError("Request:");
                _logger.LogError(odee.Request.Content);
                _logger.LogError("Response:");
                _logger.LogError(odee.Response.Content);
                throw new OdataerrorException("Error deleting the account: " + accountId.ToString());
            }

            _logger.LogDebug(LoggingEvents.HttpDelete, "No content returned.");
            return(NoContent()); // 204
        }
        public async Task <IActionResult> UpdateAccount([FromBody] ViewModels.Account item, string id)
        {
            if (!string.IsNullOrEmpty(id) && Guid.TryParse(id, out Guid accountId))
            {
                _logger.LogInformation(LoggingEvents.HttpPut, "Begin method " + this.GetType().Name + "." + MethodBase.GetCurrentMethod().ReflectedType.Name);
                _logger.LogDebug(LoggingEvents.HttpPut, "Account parameter: " + JsonConvert.SerializeObject(item));
                _logger.LogDebug(LoggingEvents.HttpPut, "id parameter: " + id);


                if (!UserDynamicsExtensions.CurrentUserHasAccessToAccount(accountId, _httpContextAccessor, _dynamicsClient))
                {
                    _logger.LogWarning(LoggingEvents.NotFound, "Current user has NO access to the account.");
                    return(NotFound());
                }

                MicrosoftDynamicsCRMaccount account = _dynamicsClient.GetAccountByIdWithChildren(accountId);
                if (account == null)
                {
                    _logger.LogWarning(LoggingEvents.NotFound, "Account NOT found.");
                    return(new NotFoundResult());
                }

                // handle the contacts.

                UpdateContacts(item);

                // we are doing a patch, so wipe out the record.
                MicrosoftDynamicsCRMaccount patchAccount = new MicrosoftDynamicsCRMaccount();

                // copy values over from the data provided
                patchAccount.CopyValues(item);
                if (item.primaryContact != null && item.primaryContact.id != null &&
                    (account._primarycontactidValue == null || account._primarycontactidValue != item.primaryContact.id))
                {
                    patchAccount.PrimaryContactidODataBind = _dynamicsClient.GetEntityURI("contacts", item.primaryContact.id);
                }
                else
                {
                    if (account._primarycontactidValue != null && !item.primaryContact.HasValue())
                    {
                        // remove the reference.
                        try
                        {
                            // pass null as recordId to remove the single value navigation property
                            _dynamicsClient.Accounts.RemoveReference(accountId.ToString(), "primarycontactid", null);
                        }
                        catch (OdataerrorException odee)
                        {
                            _logger.LogError(LoggingEvents.Error, "Error updating the account.");
                            _logger.LogError("Request:");
                            _logger.LogError(odee.Request.Content);
                            _logger.LogError("Response:");
                            _logger.LogError(odee.Response.Content);
                            throw new OdataerrorException("Error updating the account.");
                        }

                        // delete the contact.
                        try
                        {
                            _dynamicsClient.Contacts.Delete(account._primarycontactidValue);
                        }
                        catch (OdataerrorException odee)
                        {
                            _logger.LogError(LoggingEvents.Error, "Error removing primary contact");
                            _logger.LogError("Request:");
                            _logger.LogError(odee.Request.Content);
                            _logger.LogError("Response:");
                            _logger.LogError(odee.Response.Content);
                            throw new OdataerrorException("Error updating the account.");
                        }
                    }
                }


                if (item.additionalContact != null && item.additionalContact.id != null &&
                    (account._bcgovAdditionalcontactValue == null || account._bcgovAdditionalcontactValue != item.additionalContact.id))
                {
                    patchAccount.AdditionalContactODataBind = _dynamicsClient.GetEntityURI("contacts", item.additionalContact.id);
                }
                else
                {
                    if (account._bcgovAdditionalcontactValue != null && !item.additionalContact.HasValue())
                    {
                        // remove the reference.
                        try
                        {
                            // pass null as recordId to remove the single value navigation property
                            _dynamicsClient.Accounts.RemoveReference(accountId.ToString(), "bcgov_AdditionalContact", null);
                        }
                        catch (OdataerrorException odee)
                        {
                            _logger.LogError(LoggingEvents.Error, "Error updating the account.");
                            _logger.LogError("Request:");
                            _logger.LogError(odee.Request.Content);
                            _logger.LogError("Response:");
                            _logger.LogError(odee.Response.Content);
                            throw new OdataerrorException("Error updating the account.");
                        }

                        // delete the contact.
                        try
                        {
                            _dynamicsClient.Contacts.Delete(account._bcgovAdditionalcontactValue);
                        }
                        catch (OdataerrorException odee)
                        {
                            _logger.LogError(LoggingEvents.Error, "Error removing additional contact");
                            _logger.LogError("Request:");
                            _logger.LogError(odee.Request.Content);
                            _logger.LogError("Response:");
                            _logger.LogError(odee.Response.Content);
                            throw new OdataerrorException("Error updating the account.");
                        }
                    }
                }


                try
                {
                    await _dynamicsClient.Accounts.UpdateAsync(accountId.ToString(), patchAccount);
                }
                catch (OdataerrorException odee)
                {
                    _logger.LogError(LoggingEvents.Error, "Error updating the account.");
                    _logger.LogError("Request:");
                    _logger.LogError(odee.Request.Content);
                    _logger.LogError("Response:");
                    _logger.LogError(odee.Response.Content);
                    throw new OdataerrorException("Error updating the account.");
                }

                // purge any existing non bceid accounts.
                _dynamicsClient.DeleteNonBceidBusinessContactLinkForAccount(_logger, accountId.ToString());

                // create the business contact links.
                if (item.primaryContact != null)
                {
                    _dynamicsClient.CreateBusinessContactLink(_logger, item.primaryContact.id, accountId.ToString(), null, (int?)ContactTypeCodes.Primary, item.primaryContact.title);
                }
                if (item.additionalContact != null)
                {
                    _dynamicsClient.CreateBusinessContactLink(_logger, item.additionalContact.id, accountId.ToString(), null, (int?)ContactTypeCodes.Additional, item.additionalContact.title);
                }


                // populate child items in the account.
                patchAccount = _dynamicsClient.GetAccountByIdWithChildren(accountId);

                var updatedAccount = patchAccount.ToViewModel();
                _logger.LogDebug(LoggingEvents.HttpPut, "updatedAccount: " +
                                 JsonConvert.SerializeObject(updatedAccount, Formatting.Indented, new JsonSerializerSettings {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                }));

                return(Json(updatedAccount));
            }
            else
            {
                return(new BadRequestResult());
            }
        }
        public IActionResult GetAccountLocations(string id)
        {
            _logger.LogInformation(LoggingEvents.HttpGet, "Begin method " + this.GetType().Name + "." + MethodBase.GetCurrentMethod().ReflectedType.Name);
            _logger.LogDebug(LoggingEvents.HttpGet, "id: " + id);

            Boolean userAccessToAccount       = false;
            List <ViewModels.Location> result = new List <Location>();

            // query the Dynamics system to get the account record.
            if (!string.IsNullOrEmpty(id) && Guid.TryParse(id, out Guid accountId))
            {
                // verify the currently logged in user has access to this account
                try
                {
                    userAccessToAccount = UserDynamicsExtensions.CurrentUserHasAccessToAccount(accountId, _httpContextAccessor, _dynamicsClient);
                }
                catch (OdataerrorException odee)
                {
                    _logger.LogError(LoggingEvents.Error, "Error while checking if current user has access to account.");
                    _logger.LogError("Request:");
                    _logger.LogError(odee.Request.Content);
                    _logger.LogError("Response:");
                    _logger.LogError(odee.Response.Content);
                }

                if (!userAccessToAccount)
                {
                    _logger.LogWarning(LoggingEvents.NotFound, "Current user has NO access to account.");
                    return(new NotFoundResult());
                }
                List <string> expand = new List <string> {
                    "bcgov_LocationAddress"
                };
                try
                {
                    string filter = $"_bcgov_businessprofile_value eq {id}";
                    var    query  = _dynamicsClient.Locations.Get(filter: filter, expand: expand);

                    foreach (var item in query.Value)
                    {
                        result.Add(item.ToViewModel());
                    }
                }
                catch (OdataerrorException)
                {
                    _logger.LogDebug("Error occured obtaining incident locations.");
                    return(new NotFoundResult());
                }
            }
            else
            {
                _logger.LogWarning(LoggingEvents.BadRequest, "Bad Request.");
                return(BadRequest());
            }

            _logger.LogDebug(LoggingEvents.HttpGet, "Account result: " +
                             JsonConvert.SerializeObject(result, Formatting.Indented, new JsonSerializerSettings {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            }));
            return(Json(result));
        }
        public IActionResult CreateWorkerContact([FromBody] ViewModels.Contact item)
        {
            // get UserSettings from the session
            string       temp         = _httpContextAccessor.HttpContext.Session.GetString("UserSettings");
            UserSettings userSettings = JsonConvert.DeserializeObject <UserSettings>(temp);

            // first check to see that a contact exists.
            string contactSiteminderGuid = userSettings.SiteMinderGuid;

            if (contactSiteminderGuid == null || contactSiteminderGuid.Length == 0)
            {
                _logger.LogError(LoggingEvents.Error, "No Contact Siteminder Guid exernal id");
                throw new Exception("Error. No ContactSiteminderGuid exernal id");
            }

            // get the contact record.
            MicrosoftDynamicsCRMcontact userContact = null;

            // see if the contact exists.
            try
            {
                userContact = _dynamicsClient.GetContactByExternalId(contactSiteminderGuid);
                if (userContact != null)
                {
                    throw new Exception("Contact already Exists");
                }
            }
            catch (OdataerrorException odee)
            {
                _logger.LogError(LoggingEvents.Error, "Error getting contact by Siteminder Guid.");
                _logger.LogError("Request:");
                _logger.LogError(odee.Request.Content);
                _logger.LogError("Response:");
                _logger.LogError(odee.Response.Content);
                throw new OdataerrorException("Error getting contact by Siteminder Guid");
            }

            // create a new contact.
            MicrosoftDynamicsCRMcontact contact = new MicrosoftDynamicsCRMcontact();

            contact.CopyValues(item);


            contact.Externaluseridentifier = UserDynamicsExtensions.GetServiceCardID(contactSiteminderGuid);

            // if we have not yet authenticated, then this is the new record for the user.
            if (userSettings.IsNewUserRegistration)
            {
                userSettings.ContactId = contact.Contactid.ToString();

                // we can now authenticate.
                if (userSettings.AuthenticatedUser == null)
                {
                    Models.User user = new Models.User();
                    user.Active    = true;
                    user.ContactId = Guid.Parse(userSettings.ContactId);
                    user.UserType  = userSettings.UserType;
                    user.SmUserId  = userSettings.UserId;
                    userSettings.AuthenticatedUser = user;
                }

                userSettings.IsNewUserRegistration = false;

                string userSettingsString = JsonConvert.SerializeObject(userSettings);
                _logger.LogDebug("userSettingsString --> " + userSettingsString);

                // add the user to the session.
                _httpContextAccessor.HttpContext.Session.SetString("UserSettings", userSettingsString);
                _logger.LogDebug("user added to session. ");
            }
            else
            {
                _logger.LogError(LoggingEvents.Error, "Invalid user registration.");
                throw new Exception("Invalid user registration.");
            }

            return(Json(contact.ToViewModel()));
        }