public async Task SaveAsync()
        {
            QuoteCacheRegion.ExpireQuote(_quoteRequest);

            var quoteDto = _quoteRequest.ToQuoteRequestDto();

            if (_quoteRequest.IsTransient())
            {
                await _quoteApi.CreateAsync(quoteDto);
            }
            else
            {
                await _quoteApi.UpdateAsync(quoteDto);
            }

            await _publisher.Publish(new QuoteRequestUpdatedEvent(_quoteRequest));
        }
        public async Task <IQuoteRequestBuilder> GetOrCreateNewTransientQuoteRequestAsync(Store store, User user, Language language, Currency currency)
        {
            var cacheKey = CacheKey.With(GetType(), store.Id, user.Id);

            _quoteRequest = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                var activeQuoteSearchCriteria = new quoteModel.QuoteRequestSearchCriteria
                {
                    Tag        = "actual",
                    CustomerId = user.Id,
                    StoreId    = store.Id
                };

                var searchResult = await _quoteApi.SearchAsync(activeQuoteSearchCriteria);

                var quoteRequest = searchResult.QuoteRequests.Select(x => x.ToQuoteRequest(currency, language)).FirstOrDefault();
                if (quoteRequest == null)
                {
                    quoteRequest = new QuoteRequest(currency, language)
                    {
                        Currency   = currency,
                        CustomerId = user.Id,
                        Language   = language,
                        Status     = "New",
                        StoreId    = store.Id,
                        Tag        = "actual"
                    };

                    quoteRequest.CustomerName = user.UserName;
                }
                else
                {
                    quoteRequest = (await _quoteApi.GetByIdAsync(quoteRequest.Id)).ToQuoteRequest(currency, language);
                }
                //Add expiration token for concrete quote instance
                cacheEntry.AddExpirationToken(QuoteCacheRegion.CreateChangeToken(quoteRequest));
                quoteRequest.Customer = user;

                return(quoteRequest);
            });

            return(this);
        }
        public async Task <IQuoteRequestBuilder> MergeFromOtherAsync(QuoteRequest quoteRequest)
        {
            _quoteRequest.Comment = quoteRequest.Comment;

            foreach (var quoteItem in quoteRequest.Items)
            {
                _quoteRequest.Items.Add(quoteItem);
            }

            if (quoteRequest.Addresses != null && quoteRequest.Addresses.Any())
            {
                _quoteRequest.Addresses = quoteRequest.Addresses;
            }

            await _quoteApi.DeleteAsync(new[] { quoteRequest.Id }.ToList());

            QuoteCacheRegion.ExpireQuote(_quoteRequest);

            return(this);
        }
        public IQuoteRequestBuilder Update(QuoteRequestFormModel quoteRequest)
        {
            QuoteCacheRegion.ExpireQuote(_quoteRequest);

            _quoteRequest.Comment = quoteRequest.Comment;
            _quoteRequest.Status  = quoteRequest.Status;
            _quoteRequest.Tag     = quoteRequest.Tag;

            _quoteRequest.Addresses.Clear();
            if (quoteRequest.BillingAddress != null)
            {
                _quoteRequest.Addresses.Add(quoteRequest.BillingAddress);
            }
            if (quoteRequest.ShippingAddress != null)
            {
                _quoteRequest.Addresses.Add(quoteRequest.ShippingAddress);
            }

            if (quoteRequest.Items != null)
            {
                foreach (var item in quoteRequest.Items)
                {
                    var existingItem = _quoteRequest.Items.FirstOrDefault(i => i.Id == item.Id);
                    if (existingItem != null)
                    {
                        existingItem.Comment           = item.Comment;
                        existingItem.SelectedTierPrice = new TierPrice(new Money(item.SelectedTierPrice.Price, _quoteRequest.Currency), item.SelectedTierPrice.Quantity);
                        existingItem.ProposalPrices.Clear();
                        foreach (var proposalPrice in item.ProposalPrices)
                        {
                            existingItem.ProposalPrices.Add(new TierPrice(new Money(proposalPrice.Price, _quoteRequest.Currency), proposalPrice.Quantity));
                        }
                    }
                }
            }

            return(this);
        }