1using System.Collections.Concurrent;
2
3public record Product(string Name, decimal Price, string Category);
4
5public record OrderLine(Product Product, int Quantity)
6{
7 public decimal Total => Product.Price * Quantity;
8}
9
10public record Order(
11 Guid Id,
12 DateTime CreatedAt,
13 List<OrderLine> Lines
14)
15{
16 public decimal GrandTotal => Lines.Sum(l => l.Total);
17}
18
19public class OrderService
20{
21 private readonly ConcurrentDictionary<Guid, Order> _orders = new();
22
23 public async Task<Order> CreateOrderAsync(
24 List<OrderLine> lines)
25 {
26 await Task.Delay(10);
27 var order = new Order(
28 Guid.NewGuid(),
29 DateTime.UtcNow,
30 lines
31 );
32 _orders.TryAdd(order.Id, order);
33 return order;
34 }
35
36 public IEnumerable<Order> GetByCategory(string category)
37 {
38 return _orders.Values
39 .Where(o => o.Lines.Any(
40 l => l.Product.Category == category))
41 .OrderByDescending(o => o.GrandTotal);
42 }
43
44 public Dictionary<string, decimal> RevenueByCategory()
45 {
46 return _orders.Values
47 .SelectMany(o => o.Lines)
48 .GroupBy(l => l.Product.Category)
49 .ToDictionary(
50 g => g.Key,
51 g => g.Sum(l => l.Total)
52 );
53 }
54
55 public decimal AverageOrderValue()
56 {
57 if (_orders.IsEmpty) return 0m;
58 return _orders.Values.Average(o => o.GrandTotal);
59 }
60}