public ActionResult GetOrdersOfUser(string username)
 {
     try
     {
         var orders = GH.GetOrders(username, order_db);
         if (orders != null)
         {
             return(Ok(new ResponseData
             {
                 Code = "200",
                 Message = "Success",
                 Data = orders
             }));
         }
         else
         {
             return(BadRequest(new ResponseData
             {
                 Code = "404",
                 Message = "No orders found",
                 Data = null
             }));
         }
     }
     catch (Exception ex)
     {
         LoggerDataAccess.CreateLog("OrderController", "GetOrdersOfUser", "GetOrdersOfUser", ex.Message);
         return(BadRequest(new ResponseData
         {
             Code = "400",
             Message = "Failed",
             Data = ex.Message
         }));
     }
 }
        public async Task <ActionResult> ReturnProduct([FromBody] OrderInfo data, string request, string username, string productSKU)
        {
            try
            {
                if (request == "refund" || request == "replace")
                {
                    var orders = GH.GetOrders(username, order_db).Result;
                    if (orders == null)
                    {
                        return(BadRequest(new ResponseData
                        {
                            Code = "404",
                            Message = "No orders found",
                            Data = null
                        }));
                    }
                    else
                    {
                        IAsyncCursor <OrderInfo> orderCursor = await order_db.GetCollection <OrderInfo>("OrderInfo").FindAsync(Builders <OrderInfo> .Filter.Eq("UserName", username) & Builders <OrderInfo> .Filter.Eq("OrderId", data.OrderId));

                        var order = orderCursor.FirstOrDefaultAsync().Result;
                        if (order == null)
                        {
                            return(BadRequest(new ResponseData
                            {
                                Code = "404",
                                Message = "Order Not Found",
                                Data = null
                            }));
                        }
                        foreach (var productDetails in order.ProductDetails)
                        {
                            if (productDetails.ProductSKU == productSKU)
                            {
                                var productData = BsonSerializer.Deserialize <Product>(MH.GetSingleObject(Builders <BsonDocument> .Filter.Eq("ProductSKU", productSKU), "ProductDB", "Product").Result);
                                if (productDetails.Status != "Delivered")
                                {
                                    return(BadRequest(new ResponseData
                                    {
                                        Code = "401",
                                        Message = "Order Return Request Failed",
                                        Data = null
                                    }));
                                }
                                else
                                {
                                    if (request == "refund")
                                    {
                                        if (productData.RefundApplicable == false)
                                        {
                                            return(BadRequest(new ResponseData
                                            {
                                                Code = "402",
                                                Message = "Refund not applicable for this product",
                                                Data = null
                                            }));
                                        }
                                    }
                                    if (request == "replace")
                                    {
                                        if (productData.ReplacementApplicable == false)
                                        {
                                            return(BadRequest(new ResponseData
                                            {
                                                Code = "403",
                                                Message = "Replacement not applicable for this product",
                                                Data = null
                                            }));
                                        }
                                    }
                                    PaymentMethod paymentMethod = new PaymentMethod();
                                    paymentMethod.Method = order.PaymentMethod;
                                    List <StatusCode> paymentList = new List <StatusCode>();
                                    int i = 1;
                                    foreach (var status in order.PaymentDetails.Status)
                                    {
                                        paymentList.Add(status);
                                        i++;
                                    }
                                    StatusCode paymentStatus = new StatusCode();
                                    paymentStatus.StatusId = i;
                                    paymentStatus.Date     = DateTime.UtcNow;
                                    if (request == "refund")
                                    {
                                        paymentStatus.Description = "Refund Initiated";
                                    }
                                    if (request == "replace")
                                    {
                                        paymentStatus.Description = "Replacement Initiated";
                                    }
                                    paymentList.Add(paymentStatus);
                                    paymentMethod.Status = paymentList;
                                    var paymentUpdate = Builders <BsonDocument> .Update.Set("PaymentDetails", paymentMethod);

                                    var result = MH.UpdateSingleObject(Builders <BsonDocument> .Filter.Eq("UserName", username) & Builders <BsonDocument> .Filter.Eq("OrderId", data.OrderId), "OrderDB", "OrderInfo", paymentUpdate).Result;
                                    List <ProductDetails> productDetailsList = new List <ProductDetails>();
                                    foreach (var product in order.ProductDetails)
                                    {
                                        if (product.ProductSKU == productSKU)
                                        {
                                            ProductDetails details = new ProductDetails();
                                            details.ProductSKU = productSKU;
                                            details.Status     = "Refund Initiated";
                                            List <StatusCode> productStatusList = new List <StatusCode>();
                                            int j = 1;
                                            foreach (var status in product.StatusCode)
                                            {
                                                productStatusList.Add(status);
                                                j++;
                                            }
                                            StatusCode productStatus = new StatusCode();
                                            productStatus.StatusId = j;
                                            productStatus.Date     = DateTime.UtcNow;
                                            if (request == "refund")
                                            {
                                                productStatus.Description = "Refund Initiated";
                                            }
                                            if (request == "replace")
                                            {
                                                productStatus.Description = "Replacement Initiated";
                                            }
                                            productStatusList.Add(productStatus);
                                            details.StatusCode    = productStatusList;
                                            details.ProductInCart = product.ProductInCart;
                                            productDetailsList.Add(details);
                                        }
                                        else
                                        {
                                            productDetailsList.Add(product);
                                        }
                                    }
                                    var productUpdate = Builders <BsonDocument> .Update.Set("ProductDetails", productDetailsList);

                                    var responce = MH.UpdateSingleObject(Builders <BsonDocument> .Filter.Eq("UserName", username) & Builders <BsonDocument> .Filter.Eq("OrderId", data.OrderId), "OrderDB", "OrderInfo", productUpdate).Result;
                                }
                            }
                        }
                        return(Ok(new ResponseData
                        {
                            Code = "200",
                            Message = "Success",
                            Data = null
                        }));
                    }
                }
                else
                {
                    return(BadRequest(new ResponseData
                    {
                        Code = "405",
                        Message = "Invalid Request",
                        Data = null
                    }));
                }
            }
            catch (Exception ex)
            {
                LoggerDataAccess.CreateLog("OrderController", "ReturnProduct", "ReturnProduct", ex.Message);
                return(BadRequest(new ResponseData
                {
                    Code = "400",
                    Message = "Failed",
                    Data = ex.Message
                }));
            }
        }
        public async Task <ActionResult> PlaceOrder([FromBody] OrderInfo data, string username)
        {
            try
            {
                if (data.PaymentMethod != null)
                {
                    IAsyncCursor <Address> userCursor = await _db.GetCollection <Address>("UserInfo").FindAsync(Builders <Address> .Filter.Eq("UserName", username));

                    var users = userCursor.ToList();
                    if (users.Count > 0)
                    {
                        IAsyncCursor <Cart> cartCursor = await _db.GetCollection <Cart>("Cart").FindAsync(Builders <Cart> .Filter.Eq("UserName", username));

                        var cartDatas = cartCursor.ToList();
                        if (cartDatas.Count > 0)
                        {
                            var orders = await GH.GetOrders(username, order_db);

                            if (orders == null)
                            {
                                data.OrderId = 1;
                            }
                            else
                            {
                                data.OrderId = orders.Count + 1;
                            }
                            data.UserName = username;
                            double totalPrice = 0;
                            foreach (var product in cartDatas)
                            {
                                totalPrice = totalPrice + product.ProductPrice;
                            }
                            data.TotalAmount = totalPrice;
                            PaymentMethod paymentMethod = new PaymentMethod();
                            paymentMethod.Method = data.PaymentMethod;
                            List <StatusCode> paymentStatus = new List <StatusCode>();
                            if (data.PaymentMethod == "Cash On Delivery")
                            {
                                paymentStatus.Add(new StatusCode {
                                    StatusId = 1, Date = DateTime.UtcNow, Description = "Payment Pending"
                                });
                            }
                            else
                            {
                                paymentStatus.Add(new StatusCode {
                                    StatusId = 1, Date = DateTime.UtcNow, Description = "Payment Service Initiated"
                                });
                            }
                            paymentMethod.Status = paymentStatus;
                            data.PaymentDetails  = paymentMethod;
                            List <Address> addressList = new List <Address>();
                            foreach (var address in users)
                            {
                                if (address.DefaultAddress == true)
                                {
                                    addressList.Add(address);
                                }
                            }
                            data.Address = addressList;
                            if (data.Address.Count == 0)
                            {
                                return(BadRequest(new ResponseData
                                {
                                    Code = "405",
                                    Message = "No default address found",
                                    Data = null
                                }));
                            }
                            List <ProductDetails> productList = new List <ProductDetails>();
                            foreach (var cart in cartDatas)
                            {
                                foreach (var product in GH.GetProducts(cart.ProductSKU, product_db).Result)
                                {
                                    if (product.ProductStock < cart.ProductQuantity)
                                    {
                                        return(BadRequest(new ResponseData
                                        {
                                            Code = "403",
                                            Message = "Order quantity is higher than the product stock.",
                                            Data = null
                                        }));
                                    }
                                    ProductDetails productDetails = new ProductDetails();
                                    productDetails.ProductSKU = cart.ProductSKU;
                                    productDetails.Status     = "Order Placed";
                                    List <StatusCode> productStatus = new List <StatusCode>();
                                    productStatus.Add(new StatusCode {
                                        StatusId = 1, Date = DateTime.UtcNow, Description = "OrderPlaced"
                                    });
                                    productDetails.StatusCode    = productStatus;
                                    productDetails.ProductInCart = cart;
                                    productList.Add(productDetails);
                                }
                            }
                            data.ProductDetails = productList;
                            await order_db.GetCollection <OrderInfo>("OrderInfo").InsertOneAsync(data);

                            foreach (var cart in cartDatas)
                            {
                                foreach (var product in GH.GetProducts(cart.ProductSKU, product_db).Result)
                                {
                                    var update = Builders <BsonDocument> .Update.Set("ProductStock", product.ProductStock - cart.ProductQuantity);

                                    var result = MH.UpdateSingleObject(Builders <BsonDocument> .Filter.Eq("ProductSKU", cart.ProductSKU), "ProductDB", "Product", update).Result;
                                }
                                var response = MH.DeleteSingleObject(Builders <BsonDocument> .Filter.Eq("ProductSKU", cart.ProductSKU), "UserInfo", "Cart");
                            }
                            return(Ok(new ResponseData
                            {
                                Code = "200",
                                Message = "Order Placed",
                                Data = null
                            }));
                        }
                        else
                        {
                            return(BadRequest(new ResponseData
                            {
                                Code = "402",
                                Message = "Cart not found",
                                Data = null
                            }));
                        }
                    }
                    else
                    {
                        return(BadRequest(new ResponseData
                        {
                            Code = "401",
                            Message = "UserInfo not found",
                            Data = null
                        }));
                    }
                }
                else
                {
                    return(BadRequest(new ResponseData
                    {
                        Code = "404",
                        Message = "Provide a payment method",
                        Data = null
                    }));
                }
            }
            catch (Exception ex)
            {
                LoggerDataAccess.CreateLog("OrderController", "PlaceOrder", "PlaceOrder", ex.Message);
                return(BadRequest(new ResponseData
                {
                    Code = "400",
                    Message = "Failed",
                    Data = ex.Message
                }));
            }
        }
        public async Task <ActionResult> CancelOrder([FromBody] OrderInfo data, string username, string productSKU)
        {
            try
            {
                var orders = GH.GetOrders(username, order_db).Result;
                if (orders == null)
                {
                    return(BadRequest(new ResponseData
                    {
                        Code = "404",
                        Message = "No orders found",
                        Data = null
                    }));
                }
                else
                {
                    IAsyncCursor <OrderInfo> orderCursor = await order_db.GetCollection <OrderInfo>("OrderInfo").FindAsync(Builders <OrderInfo> .Filter.Eq("UserName", username) & Builders <OrderInfo> .Filter.Eq("OrderId", data.OrderId));

                    var order = orderCursor.FirstOrDefaultAsync().Result;
                    if (order == null)
                    {
                        return(BadRequest(new ResponseData
                        {
                            Code = "404",
                            Message = "Order Not Found",
                            Data = null
                        }));
                    }
                    foreach (var productDetails in order.ProductDetails)
                    {
                        if (productDetails.Status == "Cancled" || productDetails.Status == "Refunded" || productDetails.Status == "Replaced" || productDetails.Status == "Delivered")
                        {
                            return(BadRequest(new ResponseData
                            {
                                Code = "401",
                                Message = "Order Cancle Request Failed",
                                Data = null
                            }));
                        }
                        else
                        {
                            PaymentMethod paymentMethod = new PaymentMethod();
                            paymentMethod.Method = order.PaymentMethod;
                            List <StatusCode> paymentList = new List <StatusCode>();
                            int i = 1;
                            foreach (var status in order.PaymentDetails.Status)
                            {
                                paymentList.Add(status);
                                i++;
                            }
                            StatusCode paymentStatus = new StatusCode();
                            paymentStatus.StatusId = i;
                            paymentStatus.Date     = DateTime.UtcNow;
                            if (data.PaymentMethod == "Cash On Delivery")
                            {
                                paymentStatus.Description = "Payment Cancled";
                            }
                            else
                            {
                                paymentStatus.Description = "Refund Initiated";
                            }
                            paymentList.Add(paymentStatus);
                            paymentMethod.Status = paymentList;
                            var paymentUpdate = Builders <BsonDocument> .Update.Set("PaymentDetails", paymentMethod);

                            var result = MH.UpdateSingleObject(Builders <BsonDocument> .Filter.Eq("UserName", username) & Builders <BsonDocument> .Filter.Eq("OrderId", data.OrderId), "OrderDB", "OrderInfo", paymentUpdate).Result;
                            List <ProductDetails> productDetailsList = new List <ProductDetails>();
                            foreach (var product in order.ProductDetails)
                            {
                                if (product.ProductSKU == productSKU)
                                {
                                    ProductDetails details = new ProductDetails();
                                    details.ProductSKU = productSKU;
                                    details.Status     = "Cancled";
                                    List <StatusCode> productStatusList = new List <StatusCode>();
                                    int j = 1;
                                    foreach (var status in product.StatusCode)
                                    {
                                        productStatusList.Add(status);
                                        j++;
                                    }
                                    StatusCode productStatus = new StatusCode {
                                        StatusId = j, Date = DateTime.UtcNow, Description = "Cancled"
                                    };
                                    productStatusList.Add(productStatus);
                                    details.StatusCode    = productStatusList;
                                    details.ProductInCart = product.ProductInCart;
                                    productDetailsList.Add(details);
                                }
                                else
                                {
                                    productDetailsList.Add(product);
                                }
                            }
                            var productUpdate = Builders <BsonDocument> .Update.Set("ProductDetails", productDetailsList);

                            var responce = MH.UpdateSingleObject(Builders <BsonDocument> .Filter.Eq("UserName", username) & Builders <BsonDocument> .Filter.Eq("OrderId", data.OrderId), "OrderDB", "OrderInfo", productUpdate).Result;
                        }
                    }
                    IAsyncCursor <OrderInfo> orderCursorAfterUpdate = await order_db.GetCollection <OrderInfo>("OrderInfo").FindAsync(Builders <OrderInfo> .Filter.Eq("UserName", username) & Builders <OrderInfo> .Filter.Eq("OrderId", data.OrderId));

                    var orderAfterUpdate = orderCursorAfterUpdate.FirstOrDefaultAsync().Result;
                    foreach (var product in orderAfterUpdate.ProductDetails)
                    {
                        if (product.ProductSKU == productSKU)
                        {
                            IAsyncCursor <Product> productCursor = await product_db.GetCollection <Product>("Product").FindAsync(Builders <Product> .Filter.Eq("ProductSKU", productSKU));

                            var productData   = productCursor.FirstOrDefaultAsync().Result;
                            var productUpdate = Builders <BsonDocument> .Update.Set("ProductStock", productData.ProductStock + product.ProductInCart.ProductQuantity);

                            var responce = MH.UpdateSingleObject(Builders <BsonDocument> .Filter.Eq("ProductSKU", productSKU), "ProductDB", "Product", productUpdate).Result;
                        }
                    }
                    return(Ok(new ResponseData
                    {
                        Code = "200",
                        Message = "Success",
                        Data = null
                    }));
                }
            }
            catch (Exception ex)
            {
                LoggerDataAccess.CreateLog("OrderController", "CancleOrder", "CancleOrder", ex.Message);
                return(BadRequest(new ResponseData
                {
                    Code = "400",
                    Message = "Failed",
                    Data = ex.Message
                }));
            }
        }