public TopupTransactionEN SendTopup(PersonEN pPerson, string pOperatorName, decimal pAmount, string pPhone, int pPackCode)
        {
            TopupTransactionEN topupResult = new TopupTransactionEN();
            TopupEN            topup       = new TopupEN();

            ProductEN product = new ProductEN();

            topup.Operator    = pOperatorName;
            topup.Amount      = pAmount;
            topup.Phone       = pPhone;
            topup.PackageCode = pPackCode;

            try
            {
                var topupData = ValidateTopupData(pPerson, topup, ref product);

                if (topupData.IsValid)
                {
                    List <PersonBagOperatorEN> operatorUserBags = topupDAL.GetUserOperatorBags(pPerson.PersonID);

                    //Register initial bags state
                    // var states = RegisterInitialUserBagState(operatorUserBags, product.ProductID);

                    try
                    {
                        //Discounts product amount from user's bag
                        if (UpdateUserBags(product, operatorUserBags, pPerson.PersonID))
                        {
                            #region AzureSearch
                            //if (!azureSearch.CheckExistingEntry(topupData.Phone))
                            //    azureSearch.InsertEntry(pPerson.PersonID, pOperatorName, pPhone, pPerson.CountryID);
                            //else
                            //    azureSearch.ComparePhoneNumber(pPhone, pOperatorName, pPerson.PersonID, pPerson.CountryID);
                            #endregion

                            //Gets response from Topup Service
                            topupResult = topupClient.AttemptSendTopup(pPhone, pAmount, pPackCode, topupData.OperatorID, topupData.CategoryID);

                            GatsTransactionEN transaction = new GatsTransactionEN();
                            transaction.Request               = topupResult.RequestURL;
                            transaction.Response              = topupResult.Response;
                            transaction.TransactionID         = topupResult.ServiceTransactionID;
                            transaction.ProviderTransactionID = topupResult.ServiceTransactionID;
                            transaction.Amount       = pAmount;
                            transaction.CountryID    = pPerson.CountryID;
                            transaction.PhoneNumber  = long.Parse(pPhone.ToString());
                            transaction.RegDate      = DateTime.Now;
                            transaction.ResponseCode = topupResult.Code;
                            transaction.Paid         = true;

                            if (!String.Equals(topupResult.Code, "Success") && !String.Equals(topupResult.Code, "02"))
                            {
                                if (product.PersonDiscount > 0)
                                {
                                    //Refunds user balance from updated values
                                    var updatedBags = topupDAL.GetUserOperatorBags(pPerson.PersonID);
                                    UpdateUserBagsRefund(product, updatedBags, pPerson.PersonID);
                                }
                            }
                            else
                            {
                                topupResult.Message = topupData.Result;
                            }

                            //Updates users bags history
                            //RegisterFinalUserBagState(states, pPerson.PersonID);

                            topupDAL.LogTopupTransaction(transaction, pPerson.PersonID, pPerson.CountryID, topupData.Operator, product.InventoryDiscount, product.PersonDiscount);
                            EventViewerLogger.LogInformation("SendTopup: " + transaction.Response);
                        }
                    }
                    catch (Exception ex)
                    {
                        topupResult.Message = ex.Message;
                        topupResult.Code    = "Error";

                        if (product.PersonDiscount > 0)
                        {
                            //Gets user bags with updated values
                            operatorUserBags = topupDAL.GetUserOperatorBags(pPerson.PersonID);

                            //Refunds user bag if any exception ocurred
                            UpdateUserBagsRefund(product, operatorUserBags, pPerson.PersonID);
                            EventViewerLogger.LogError(String.Format("SendTopup - Inner exception: Refund user bags. PersonID {0}. Amount {1}. Message: {2}",
                                                                     Convert.ToString(pPerson.PersonID), product.PersonDiscount, ex.Message));

                            //Updates users bags history
                            //RegisterFinalUserBagState(states, pPerson.PersonID);
                        }
                    }
                }
                else
                {
                    //Sets the results according to topup data validation
                    topupResult.Message = topupData.Result;
                    topupResult.Code    = topupData.Result;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException);
                EventViewerLogger.LogError("SendTopup: " + ex.Message);
            }

            return(topupResult);
        }
        /// <summary>
        /// Validates topup requested data is correct. Checks the product selected is available for the mobile operator.
        /// Validates amount requested over user's bags
        /// </summary>
        /// <param name="pPerson">Vendor</param>
        /// <param name="pTopupData">Topup info (phone, amount, operator, etc)</param>
        /// <returns>Topup data result</returns>
        private TopupEN ValidateTopupData(PersonEN pPerson, TopupEN pTopupData, ref ProductEN oProduct)
        {
            ProductEN productAvailable = new ProductEN();
            TopupEN   validTopup       = new TopupEN();

            validTopup.IsValid  = false;
            validTopup.PersonID = pPerson.PersonID;

            try
            {
                //Checks available topup product
                productAvailable = topupDAL.GetAvailableTopupProduct(pTopupData.Operator, pPerson.CountryID, pTopupData.Amount, pTopupData.PackageCode);

                if (productAvailable != null)
                {
                    //Product selected for transaction
                    oProduct = productAvailable;

                    //Validates if user balance is required for transaction
                    if (productAvailable.PersonDiscount > 0)
                    {
                        //Checks user's bags balance
                        Decimal balance = topupDAL.GetPersonAvailableAmount(pPerson.PersonID, pPerson.CountryID, pTopupData.Operator);
                        if (balance > 0)
                        {
                            if (balance >= productAvailable.PersonDiscount)
                            {
                                validTopup.Operator   = productAvailable.OperatorName;
                                validTopup.Product    = productAvailable;
                                validTopup.IsValid    = true;
                                validTopup.Result     = Values.Ok;
                                validTopup.ResultCode = Values.OkCode;
                                validTopup.OperatorID = productAvailable.OperatorID;
                                validTopup.CategoryID = productAvailable.CategoryID;
                            }
                            else
                            {
                                validTopup.Operator   = productAvailable.OperatorName;
                                validTopup.IsValid    = false;
                                validTopup.Result     = Values.NoCreditLeft;
                                validTopup.ResultCode = Values.NoCreditLeftCode;
                            }
                        }
                        else
                        {
                            validTopup.Operator   = productAvailable.OperatorName;
                            validTopup.IsValid    = false;
                            validTopup.Result     = Values.NoCreditLeft;
                            validTopup.ResultCode = Values.NoCreditLeftCode;
                        }
                    }
                    else
                    {
                        //Balance on user bag is not required
                        validTopup.Operator   = productAvailable.OperatorName;
                        validTopup.IsValid    = true;
                        validTopup.Result     = Values.Ok;
                        validTopup.ResultCode = Values.PackageTopupCode;
                    }
                }
                else
                {
                    validTopup.Operator   = pTopupData.Operator;
                    validTopup.IsValid    = false;
                    validTopup.Result     = Values.InvalidProduct;
                    validTopup.ResultCode = Values.InvalidProductCode;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException);
                EventViewerLogger.LogError("ValidateTopupData: " + ex.Message);
            }

            return(validTopup);
        }