public async Task <Guid> InsertAsync(MessagesPostRequest contract)
        {
            using (var context = _msSqlContextFactory.CreateDataContext())
            {
                var entity = _mapper.Map <MessageEntity>(contract);

                entity.CreationTimestamp = DateTime.UtcNow;

                context.Add(entity);

                await context.SaveChangesAsync();

                return(entity.Id);
            }
        }
        public async Task <MessagesPostResponse> SendMessageAsync(MessagesPostRequest contract)
        {
            _log.Info("Send Message Async started",
                      new
            {
                contract.CustomerId,
                LocationId = contract.ExternalLocationId,
                contract.PartnerId,
                contract.SendPushNotification,
                contract.PosId,
                contract.Subject
            });

            //Check customer id
            var customerBlockState =
                await _customerManagementServiceClient.CustomersApi.GetCustomerBlockStateAsync(contract.CustomerId);

            if (customerBlockState.Error == CustomerBlockStatusError.CustomerNotFound)
            {
                _log.Warning("Customer Not Found", null,
                             new { contract.CustomerId, contract.PartnerId, contract.ExternalLocationId });

                return(new MessagesPostResponse
                {
                    PartnerMessageId = null, ErrorCode = MessagesErrorCode.CustomerNotFound
                });
            }
            else if (customerBlockState.Status == CustomerActivityStatus.Blocked)
            {
                _log.Warning("Customer Is Blocked", null,
                             new { contract.CustomerId, contract.PartnerId, contract.ExternalLocationId });

                return(new MessagesPostResponse
                {
                    PartnerMessageId = null, ErrorCode = MessagesErrorCode.CustomerIsBlocked
                });
            }

            //Check location
            LocationInfoResponse locationInfoResponse = null;

            if (!string.IsNullOrWhiteSpace(contract.ExternalLocationId))
            {
                locationInfoResponse =
                    await _partnerManagementClient.Locations.GetByExternalId2Async(contract.ExternalLocationId);

                if (locationInfoResponse == null)
                {
                    _log.Warning("Location Not Found", null,
                                 new { contract.CustomerId, contract.PartnerId, contract.ExternalLocationId });

                    return(new MessagesPostResponse
                    {
                        PartnerMessageId = null, ErrorCode = MessagesErrorCode.LocationNotFound
                    });
                }
            }

            //Check partner and location id
            var partnerAndLocationStatus =
                await _partnerAndLocationHelper.ValidatePartnerInfo(contract.PartnerId, locationInfoResponse);

            if (partnerAndLocationStatus != PartnerAndLocationStatus.OK)
            {
                var(message, errorCode) = partnerAndLocationStatus == PartnerAndLocationStatus.LocationNotFound
                    ? ("Location Not Found", MessagesErrorCode.LocationNotFound)
                    : ("Partner Not Found", MessagesErrorCode.PartnerNotFound);

                _log.Warning(message, null, new { contract.CustomerId, contract.PartnerId, contract.ExternalLocationId });

                return(new MessagesPostResponse {
                    PartnerMessageId = null, ErrorCode = errorCode
                });
            }

            var messageId = await _messagesRepository.InsertAsync(contract);

            _log.Info("Message saved", messageId);

            try
            {
                await _messageContentRepository.SaveContentAsync(messageId.ToString(), contract.Message);
            }
            catch (Exception ex)
            {
                _log.Error(ex, "Failed to save message content", new { messageId, contract.Message });

                await _messagesRepository.DeleteMessageAsync(messageId.ToString());

                throw;
            }

            _log.Info("Message content saved", messageId);

            //Send push notification via Rabbit
            if (contract.SendPushNotification.HasValue && contract.SendPushNotification.Value)
            {
                var evt = new PushNotificationEvent
                {
                    CustomerId         = contract.CustomerId,
                    MessageTemplateId  = _partnerMessageTemplateId,
                    Source             = _componentSourceName,
                    TemplateParameters =
                        new Dictionary <string, string>
                    {
                        { "Subject", contract.Subject },
                        { "PartnerMessageId", messageId.ToString() }
                    }
                };

                await _partnerMessagesPublisher.PublishAsync(evt);

                _log.Info("Partner message published", new { messageId, contract.CustomerId, contract.Subject });
            }

            return(new MessagesPostResponse
            {
                ErrorCode = MessagesErrorCode.OK, PartnerMessageId = messageId.ToString()
            });
        }