| | | 1 | | using Microsoft.AspNetCore.Authorization; |
| | | 2 | | using Microsoft.AspNetCore.Mvc; |
| | | 3 | | using Newtonsoft.Json.Linq; |
| | | 4 | | using Newtonsoft.Json; |
| | | 5 | | using Services.ApiServices.ShateMApi; |
| | | 6 | | using Services.ApiServices.ApiSupplierRequestLog; |
| | | 7 | | using OzonOrdersWeb.TransactionServices; |
| | | 8 | | |
| | | 9 | | namespace OzonOrdersWeb.Areas.Studio2.Controllers.Directories; |
| | | 10 | | |
| | | 11 | | [Authorize(Roles = "User,Admin")] |
| | | 12 | | [Area("Studio2")] |
| | | 13 | | [Route("ShateM/[action]")] |
| | | 14 | | public sealed class ShateMController : Controller |
| | | 15 | | { |
| | 0 | 16 | | private static readonly IReadOnlyDictionary<string, string> ReadOperations = new Dictionary<string, string>(StringCo |
| | 0 | 17 | | { |
| | 0 | 18 | | ["articles-search"] = "/api/v1/articles/search", |
| | 0 | 19 | | ["articles-search-path"] = "/api/v1/articles/search/{id}", |
| | 0 | 20 | | ["article"] = "/api/v1/articles/{id}", |
| | 0 | 21 | | ["analogs"] = "/api/v1/articles/{id}/analogs", |
| | 0 | 22 | | ["cart-items"] = "/api/v1/cartitems", |
| | 0 | 23 | | ["cart-item"] = "/api/v1/cartitems/{id}", |
| | 0 | 24 | | ["agreements"] = "/api/v1/customer/agreements", |
| | 0 | 25 | | ["customer"] = "/api/v1/customer/info", |
| | 0 | 26 | | ["addresses"] = "/api/v1/delivery/addresses", |
| | 0 | 27 | | ["available-datetimes"] = "/api/v1/delivery/availabledatetimes", |
| | 0 | 28 | | ["locations"] = "/api/v1/locations", |
| | 0 | 29 | | ["order-item-history"] = "/api/v1/orderitems/{id}/statuseshistory", |
| | 0 | 30 | | ["order-statuses"] = "/api/v1/orderitemstatuscodes", |
| | 0 | 31 | | ["orders"] = "/api/v1/orders", |
| | 0 | 32 | | ["returns"] = "/api/v1/returns", |
| | 0 | 33 | | ["return-reasons"] = "/api/v1/returns/returnitemreasons", |
| | 0 | 34 | | ["return-statuses"] = "/api/v1/returns/returnitemstatuscodes", |
| | 0 | 35 | | ["return-history"] = "/api/v1/returns/{id}/statuseshistory", |
| | 0 | 36 | | ["trademarks"] = "/api/v1/trademarks", |
| | 0 | 37 | | ["trademark"] = "/api/v1/trademarks/{id}" |
| | 0 | 38 | | }; |
| | 0 | 39 | | private static readonly IReadOnlyDictionary<string, string> SearchOperations = new Dictionary<string, string>(String |
| | 0 | 40 | | { |
| | 0 | 41 | | ["articles-filter"] = "/api/v1/articles/search", |
| | 0 | 42 | | ["contents"] = "/api/v1/contents/search", |
| | 0 | 43 | | ["prices"] = "/api/v1/prices/search", |
| | 0 | 44 | | ["prices-with-article-info"] = "/api/v1/prices/search/with_article_info" |
| | 0 | 45 | | }; |
| | | 46 | | private readonly ShateMDataManager _shateM; |
| | | 47 | | private readonly ApiSupplierRequestLogStore _logs; |
| | | 48 | | private readonly ShateMCartService _cart; |
| | | 49 | | |
| | 0 | 50 | | public ShateMController(ShateMDataManager shateM, ApiSupplierRequestLogStore logs, ShateMCartService cart) |
| | | 51 | | { |
| | 0 | 52 | | _shateM = shateM; |
| | 0 | 53 | | _logs = logs; |
| | 0 | 54 | | _cart = cart; |
| | 0 | 55 | | } |
| | | 56 | | |
| | | 57 | | [HttpGet, Route("~/ShateM")] |
| | 0 | 58 | | public IActionResult Index() => View(); |
| | | 59 | | |
| | | 60 | | [HttpGet] |
| | 0 | 61 | | public IActionResult Logs() => Json(_logs.Get("ShateM")); |
| | | 62 | | |
| | | 63 | | [HttpGet] |
| | | 64 | | public async Task<IActionResult> Ping(CancellationToken cancellationToken) |
| | | 65 | | { |
| | 0 | 66 | | try { return JsonToken(await _shateM.PingAsync(cancellationToken)); } |
| | 0 | 67 | | catch (Exception ex) { return Error(ex); } |
| | 0 | 68 | | } |
| | | 69 | | |
| | | 70 | | [HttpGet] |
| | | 71 | | public async Task<IActionResult> Read(string operation, string? id, CancellationToken cancellationToken) |
| | | 72 | | { |
| | 0 | 73 | | if (!ReadOperations.TryGetValue(operation, out var template)) return BadRequest(new { error = true, message = "Н |
| | 0 | 74 | | if ((template.Contains("{id}", StringComparison.Ordinal) || operation.Equals("articles-search", StringComparison |
| | 0 | 75 | | var path = template.Replace("{id}", Uri.EscapeDataString(id ?? string.Empty), StringComparison.Ordinal); |
| | 0 | 76 | | var query = Request.Query.Where(x => x.Key is not "operation" and not "id").ToDictionary(x => x.Key, x => (strin |
| | 0 | 77 | | if (operation.Equals("articles-search", StringComparison.OrdinalIgnoreCase)) query["searchString"] = id; |
| | 0 | 78 | | try { return JsonToken(await _shateM.GetAsync(path, query, cancellationToken)); } |
| | 0 | 79 | | catch (Exception ex) { return Error(ex); } |
| | 0 | 80 | | } |
| | | 81 | | |
| | | 82 | | [HttpGet] |
| | | 83 | | public async Task<IActionResult> Search(string operation, string payload, CancellationToken cancellationToken) |
| | | 84 | | { |
| | 0 | 85 | | if (!SearchOperations.TryGetValue(operation, out var path)) return BadRequest(new { error = true, message = "Нед |
| | 0 | 86 | | try { return JsonToken(await _shateM.SearchAsync(path, JToken.Parse(payload), cancellationToken)); } |
| | 0 | 87 | | catch (Newtonsoft.Json.JsonReaderException) { return BadRequest(new { error = true, message = "Фильтр должен быт |
| | 0 | 88 | | catch (Exception ex) { return Error(ex); } |
| | 0 | 89 | | } |
| | | 90 | | |
| | | 91 | | [HttpGet] |
| | | 92 | | public async Task<IActionResult> CheckoutData(CancellationToken cancellationToken) |
| | | 93 | | { |
| | 0 | 94 | | try { return JsonToken(await _cart.GetCheckoutDataAsync(cancellationToken)); } |
| | 0 | 95 | | catch (Exception ex) { return Error(ex); } |
| | 0 | 96 | | } |
| | | 97 | | |
| | | 98 | | [HttpGet] |
| | | 99 | | public async Task<IActionResult> AvailableDates(string locationCode, string deliveryAddressCode, CancellationToken c |
| | | 100 | | { |
| | 0 | 101 | | if (string.IsNullOrWhiteSpace(locationCode) || string.IsNullOrWhiteSpace(deliveryAddressCode)) |
| | 0 | 102 | | return BadRequest(new { error = true, message = "Укажите склад и адрес доставки Шате‑М." }); |
| | 0 | 103 | | try { return JsonToken(await _cart.GetAvailableDatesAsync(locationCode, deliveryAddressCode, cancellationToken)) |
| | 0 | 104 | | catch (Exception ex) { return Error(ex); } |
| | 0 | 105 | | } |
| | | 106 | | |
| | 0 | 107 | | private IActionResult Error(Exception ex) => ex switch |
| | 0 | 108 | | { |
| | 0 | 109 | | ShateMApiException api => StatusCode(api.StatusCode is >= 400 and < 600 ? api.StatusCode.Value : 502, new { erro |
| | 0 | 110 | | _ => StatusCode(500, new { error = true, message = "Не удалось выполнить запрос к Шате-М." }) |
| | 0 | 111 | | }; |
| | | 112 | | |
| | 0 | 113 | | private ContentResult JsonToken(JToken token) => Content(token.ToString(Formatting.None), "application/json"); |
| | | 114 | | } |