nozzlegear / ShopifySharp

ShopifySharp is a .NET library that helps developers easily authenticate with and manage Shopify stores.
https://nozzlegear.com/shopify-development-handbook
MIT License
733 stars 303 forks source link

How to list order by product ? #1045

Closed Loocist23 closed 3 months ago

Loocist23 commented 3 months ago

Ok so i'm trying to create a multi vendor dashboard and for this i want to get all the orders that are related to a products that my vendor sell

I don't know if i'm clear but if you can help me please

and sorry my first langage isn't english

concua1111 commented 3 months ago

hey guy! so hard and not good for performance, you should try to get all the orders and get all the products. then you can create a function to map this information to make the report.

Loocist23 commented 3 months ago

yes so actualy this is what i do

public async Task OnGetAsync()
{
    TotalSalesVolume = 0;
    var uniqueOrderIdsForVendor = new HashSet<long>();
    var today = DateTime.Today;
    var threeMonthsAgo = new DateTime(today.Year, today.Month, 1).AddMonths(-2);
    MonthlySalesStats = Enumerable.Range(0, 3).Select(i => today.AddMonths(-i)).ToDictionary(d => d.ToString("yyyy-MM"), d => 0m);
    HttpContext.Session.SetString("VendorName", "VendorName"); // its just a test it will go in the login logic
    var vendorName = HttpContext.Session.GetString("VendorName");
    var productIds = await GetProductIdsByVendorAsync(vendorName);

    var orders = await orderService.ListAsync(new OrderListFilter { CreatedAtMin = threeMonthsAgo, Status = "any" });

    foreach (var order in orders.Items)
    {
        var orderDate = DateTime.Parse(order.CreatedAt.ToString());
        var orderMonth = orderDate.ToString("yyyy-MM");

        if (MonthlySalesStats.ContainsKey(orderMonth))
        {
            foreach (var lineItem in order.LineItems)
            {
                if (!lineItem.ProductId.HasValue || !productIds.Contains(lineItem.ProductId.Value)) continue;
                uniqueOrderIdsForVendor.Add(order.Id.Value);

                var lineItemTotal = (decimal)(lineItem.Price * lineItem.Quantity);
                TotalSalesVolume += lineItemTotal;
                MonthlySalesStats[orderMonth] += lineItemTotal;

                var productSaleInfo = TopSellingProducts.FirstOrDefault(x => x.ProductId == lineItem.ProductId.Value);
                if (productSaleInfo == null)
                {
                    productSaleInfo = new ProductSaleInfo
                    {
                        ProductId = lineItem.ProductId.Value,
                        ProductTitle = lineItem.Title,
                        QuantitySold = (int)lineItem.Quantity,
                        TotalSales = lineItemTotal
                    };
                    TopSellingProducts.Add(productSaleInfo);
                }
                else
                {
                    productSaleInfo.QuantitySold += (int)lineItem.Quantity;
                    productSaleInfo.TotalSales += lineItemTotal;
                }
            }
        }
    }

    TotalOrders = uniqueOrderIdsForVendor.Count;
    TopSellingProducts = TopSellingProducts.OrderByDescending(p => p.TotalSales).Take(10).ToList();
}

and it works i just thinks that if you have a millions order it will be really hard on the server to map everythings

but thanks i wil close this cause it works now and i'm gonna

nozzlegear commented 3 months ago

Hey! I agree it's not great for performance, especially if you have a shop with millions of orders.

I think what I would do is put this into a background service first, so that you're not blocking any sort of UI or frontend javascript while you query this data. In Asp.Net 5+, you can use the IHostedService interface to create a service that runs in the background on startup.

For the actual querying though, I can't find any better method than what's been suggested already. Shopify doesn't seem to support anything to look up orders by the product that was purchased as far as I'm aware. I'll think on this and do some experiments! I'm interested in figuring this out.