| | | 1 | | using System.Globalization; |
| | | 2 | | using System.Xml.Linq; |
| | | 3 | | |
| | | 4 | | namespace Services.ApiServices.AvdApi; |
| | | 5 | | |
| | | 6 | | public sealed class AvdDataManager |
| | | 7 | | { |
| | | 8 | | private readonly AvdSoapClient _client; |
| | 88 | 9 | | public AvdDataManager(AvdSoapClient client) => _client = client; |
| | | 10 | | |
| | 0 | 11 | | public Task<XElement> GetUserStatusAsync(CancellationToken ct = default) => _client.SendAsync("GetUserStatus", null, |
| | 9 | 12 | | public Task<XElement> GetBasketItemAsync(CancellationToken ct = default) => _client.SendAsync("GetBasketItem", null, |
| | 0 | 13 | | public Task<XElement> GetBalanceAsync(CancellationToken ct = default) => _client.SendAsync("GetBalance", null, ct); |
| | 16 | 14 | | public Task<XElement> GetOrdersAsync(string? dateBegin, string? dateEnd, int status, string? number, CancellationTok |
| | 0 | 15 | | public Task<XElement> GetCrossesPriceAsync(string number, string? catalog, string? supplier, CancellationToken ct = |
| | | 16 | | |
| | | 17 | | public Task<XElement> InsertToBasketAsync(string hash, decimal quantity, string? comment, bool onlyThis, Cancellatio |
| | 8 | 18 | | _client.SendAsync("InsertToBasket", new Dictionary<string, string?> { ["hash"] = hash, ["quantity"] = quantity.T |
| | | 19 | | |
| | | 20 | | /// <summary>Оформляет все строки текущей корзины АВД и возвращает внешний ID заказа.</summary> |
| | | 21 | | public async Task<long> CreateOrderAsync(string? comment, CancellationToken ct = default) |
| | | 22 | | { |
| | 2 | 23 | | var response = await _client.SendAsync("CreateOrder", new Dictionary<string, string?> { ["comment"] = comment ?? |
| | 2 | 24 | | return GetCreatedOrderId(response, "CreateOrderResult"); |
| | 1 | 25 | | } |
| | | 26 | | |
| | | 27 | | /// <summary>Оформляет только выбранные строки текущей корзины АВД и возвращает внешний ID заказа.</summary> |
| | | 28 | | public async Task<long> CreateOrderByBasketIdsAsync(IReadOnlyCollection<long> basketIds, string? comment, Cancellati |
| | | 29 | | { |
| | | 30 | | var ids = basketIds.Where(id => id > 0).Distinct().ToArray(); |
| | 2 | 31 | | if (ids.Length == 0) |
| | 0 | 32 | | throw new ArgumentException("Не выбраны позиции корзины АВД.", nameof(basketIds)); |
| | | 33 | | |
| | 2 | 34 | | var response = await _client.SendAsync( |
| | 2 | 35 | | "CreateOrderSByIdBasket", |
| | 2 | 36 | | new Dictionary<string, string?> { ["comment"] = comment ?? string.Empty }, |
| | 2 | 37 | | ct, |
| | 2 | 38 | | new Dictionary<string, IReadOnlyCollection<long>> { ["basketIds"] = ids }); |
| | 2 | 39 | | return GetCreatedOrderId(response, "CreateOrderSByIdBasketResult"); |
| | 2 | 40 | | } |
| | | 41 | | |
| | | 42 | | public Task<XElement> EditItemInBasketAsync(string idBasketItem, decimal quantity, string? comment, bool onlyThis, C |
| | 1 | 43 | | _client.SendAsync("EditItemInBasket", new Dictionary<string, string?> { ["idBasketItem"] = idBasketItem, ["quant |
| | | 44 | | |
| | | 45 | | public Task<XElement> DeleteItemInBasketAsync(string idBasketItem, CancellationToken ct = default) => |
| | 1 | 46 | | _client.SendAsync("DeleteItemInBasket", new Dictionary<string, string?> { ["idBasketItem"] = idBasketItem }, ct) |
| | | 47 | | |
| | | 48 | | public async Task<IReadOnlyList<AvdBasketItem>> GetBasketItemsAsync(CancellationToken ct = default) |
| | | 49 | | { |
| | 9 | 50 | | var xml = await GetBasketItemAsync(ct); |
| | 5 | 51 | | return xml.Descendants() |
| | | 52 | | .Where(x => AvdSoapClient.Value(x, "Id") != null && AvdSoapClient.Value(x, "ItemNumber") != null) |
| | | 53 | | .Select(x => new AvdBasketItem |
| | | 54 | | { |
| | | 55 | | Id = AvdSoapClient.Value(x, "Id") ?? string.Empty, |
| | | 56 | | CatalogName = AvdSoapClient.Value(x, "CatalogName") ?? string.Empty, |
| | | 57 | | ItemName = AvdSoapClient.Value(x, "ItemName") ?? string.Empty, |
| | | 58 | | ItemNumber = AvdSoapClient.Value(x, "ItemNumber") ?? string.Empty, |
| | | 59 | | Comment = AvdSoapClient.Value(x, "Comment") ?? string.Empty, |
| | | 60 | | Price = AvdSoapClient.DecimalValue(x, "Price"), |
| | | 61 | | Quantity = AvdSoapClient.DecimalValue(x, "Quantity"), |
| | | 62 | | Period = AvdSoapClient.IntValue(x, "Period"), |
| | | 63 | | Region = AvdSoapClient.Value(x, "Region") ?? string.Empty, |
| | | 64 | | SupplierName = AvdSoapClient.Value(x, "SupplierName") ?? string.Empty, |
| | | 65 | | OnlyThis = AvdSoapClient.Value(x, "OnlyThis") == "1" |
| | | 66 | | }).ToList(); |
| | 5 | 67 | | } |
| | | 68 | | |
| | | 69 | | public async Task<IReadOnlyList<AvdOrder>> GetOrdersParsedAsync(string? dateBegin, string? dateEnd, int status, stri |
| | | 70 | | { |
| | 16 | 71 | | var xml = await GetOrdersAsync(dateBegin, dateEnd, status, number, ct); |
| | 13 | 72 | | var items = xml.Descendants() |
| | | 73 | | .Where(x => AvdSoapClient.Value(x, "OrderId") != null && AvdSoapClient.Value(x, "ItemNumber") != null) |
| | | 74 | | .Select(x => new AvdOrderItem |
| | | 75 | | { |
| | | 76 | | Id = AvdSoapClient.Value(x, "Id") ?? string.Empty, |
| | | 77 | | OrderId = AvdSoapClient.Value(x, "OrderId") ?? string.Empty, |
| | | 78 | | OrderNumber = AvdSoapClient.Value(x, "OrderNumber") ?? string.Empty, |
| | | 79 | | OrderDate = AvdSoapClient.Value(x, "OrderDate") ?? string.Empty, |
| | | 80 | | OrderInfo = AvdSoapClient.Value(x, "OrderInfo") ?? string.Empty, |
| | | 81 | | SchetNumber = AvdSoapClient.Value(x, "SchetNumber"), |
| | | 82 | | CatalogName = AvdSoapClient.Value(x, "CatalogName") ?? string.Empty, |
| | | 83 | | ItemName = AvdSoapClient.Value(x, "ItemName") ?? string.Empty, |
| | | 84 | | ItemNumber = AvdSoapClient.Value(x, "ItemNumber") ?? string.Empty, |
| | | 85 | | Comment = AvdSoapClient.Value(x, "Comment") ?? string.Empty, |
| | | 86 | | Price = AvdSoapClient.DecimalValue(x, "Price"), |
| | | 87 | | DealerPrice = AvdSoapClient.DecimalValue(x, "DealerPrice"), |
| | | 88 | | Quantity = AvdSoapClient.DecimalValue(x, "Quantity"), |
| | | 89 | | QuantityBuyin = AvdSoapClient.DecimalValue(x, "QuantityBuyin"), |
| | | 90 | | QuantityCome = AvdSoapClient.DecimalValue(x, "QuantityCome"), |
| | | 91 | | QuantityDeny = AvdSoapClient.DecimalValue(x, "QuantityDeny"), |
| | | 92 | | QuantityDone = AvdSoapClient.DecimalValue(x, "QuantityDone"), |
| | | 93 | | Period = AvdSoapClient.IntValue(x, "Period"), |
| | | 94 | | Status = AvdSoapClient.Value(x, "Status") ?? string.Empty, |
| | | 95 | | StatusId = AvdSoapClient.IntValue(x, "Status_id"), |
| | | 96 | | StatusDate = AvdSoapClient.Value(x, "StatusDate") ?? string.Empty, |
| | | 97 | | Send = AvdSoapClient.Value(x, "Send") == "1", |
| | | 98 | | Archive = AvdSoapClient.Value(x, "Archive") == "1", |
| | | 99 | | SupplierName = AvdSoapClient.Value(x, "SupplierName") ?? string.Empty, |
| | | 100 | | User = AvdSoapClient.Value(x, "User") ?? string.Empty |
| | | 101 | | }).ToList(); |
| | | 102 | | return items.GroupBy(x => x.OrderId, StringComparer.Ordinal) |
| | | 103 | | .Select(g => new AvdOrder |
| | | 104 | | { |
| | | 105 | | OrderId = g.Key, |
| | | 106 | | OrderNumber = g.First().OrderNumber, |
| | | 107 | | OrderDate = g.First().OrderDate, |
| | | 108 | | OrderInfo = g.First().OrderInfo, |
| | | 109 | | SchetNumber = g.First().SchetNumber, |
| | | 110 | | Items = g.ToList() |
| | | 111 | | }) |
| | | 112 | | .OrderByDescending(x => x.OrderId, StringComparer.Ordinal) |
| | 13 | 113 | | .ToList(); |
| | 13 | 114 | | } |
| | | 115 | | public async Task<IReadOnlyList<string>> GetCatalogsListAsync(string number, CancellationToken ct = default) |
| | | 116 | | { |
| | 0 | 117 | | var xml = await _client.SendAsync("GetCatalogsList", new Dictionary<string, string?> { ["number"] = number }, ct |
| | | 118 | | return xml.Descendants().Where(x => x.Name.LocalName == "CatalogName").Select(x => x.Value.Trim()).Where(x => x. |
| | 0 | 119 | | } |
| | 2 | 120 | | public async Task<IReadOnlyList<AvdPriceOffer>> GetOriginalPriceAsync(string number, string? catalog, string? suppli |
| | 0 | 121 | | public async Task<IReadOnlyList<AvdPriceOffer>> GetFastCrossesPriceAsync(string number, string catalog, string? supp |
| | | 122 | | |
| | 2 | 123 | | private static Dictionary<string, string?> PriceParameters(string number, string? catalog, string? supplier) => new( |
| | | 124 | | |
| | | 125 | | private static long GetCreatedOrderId(XElement response, string resultElementName) |
| | | 126 | | { |
| | 16 | 127 | | var result = response.Descendants().FirstOrDefault(element => element.Name.LocalName == resultElementName)?.Valu |
| | 4 | 128 | | if (!long.TryParse(result, NumberStyles.Integer, CultureInfo.InvariantCulture, out var orderId) || orderId <= 0) |
| | 1 | 129 | | throw new AvdApiException("АВД не создал заказ: API вернул пустой или нулевой идентификатор."); |
| | 3 | 130 | | return orderId; |
| | | 131 | | } |
| | 2 | 132 | | private static IReadOnlyList<AvdPriceOffer> ParseOffers(XElement xml) => xml.Descendants() |
| | 18 | 133 | | .Where(x => AvdSoapClient.Value(x, "ItemNumber") != null && AvdSoapClient.Value(x, "Price") != null) |
| | 2 | 134 | | .Select(x => new AvdPriceOffer { CatalogName = AvdSoapClient.Value(x, "CatalogName") ?? string.Empty, ItemName = |
| | 4 | 135 | | .Where(x => x.Price.HasValue).ToList(); |
| | | 136 | | } |