< Summary

Information
Class: OzonOrdersWeb.Areas.Studio2.Controllers.OzonSplitController
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/Controllers/OzonSplitController.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 122
Coverable lines: 122
Total lines: 262
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 40
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
GetOzonSplitData()0%2040%
SplitOzonOrder()0%1056320%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/Controllers/OzonSplitController.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Authorization;
 2using Microsoft.AspNetCore.Mvc;
 3using Microsoft.EntityFrameworkCore;
 4using OzonRepositories.Context;
 5using OzonRepositories.Data;
 6using Services.ApiServices.OzonApi;
 7using Services.ApiServices.OzonApi.Filters;
 8using Services.DataServices;
 9
 10namespace OzonOrdersWeb.Areas.Studio2.Controllers
 11{
 12    [Authorize(Roles = "User,Admin")]
 13    [Area("Studio2")]
 14    [Route("Studio2/Orders")]
 15    public class OzonSplitController : Controller
 16    {
 17        private readonly ApplicationDbContext _context;
 18        private readonly OzonApiDataManager _ozonApiDataManager;
 19        private readonly OzonClientServices _ozonClientServices;
 20        private readonly ShipmentRepository _shipmentRepository;
 21
 022        public OzonSplitController(
 023            ApplicationDbContext context,
 024            OzonApiDataManager ozonApiDataManager,
 025            OzonClientServices ozonClientServices,
 026            ShipmentRepository shipmentRepository)
 27        {
 028            _context = context;
 029            _ozonApiDataManager = ozonApiDataManager;
 030            _ozonClientServices = ozonClientServices;
 031            _shipmentRepository = shipmentRepository;
 032        }
 33
 34        /// <summary>
 35        /// Получает данные для разделения заказа на Ozon
 36        /// </summary>
 37        [HttpGet]
 38        [Route("GetOzonSplitData")]
 39        public async Task<IActionResult> GetOzonSplitData(int orderId, int shipmentId)
 40        {
 41            try
 42            {
 43                // Получаем все заказы в этом отправлении
 044                var ordersInShipment = await _context.Orders
 045                    .Include(o => o.ProductInfo)
 046                    .Where(o => o.ShipmentId == shipmentId)
 047                    .AsNoTracking()
 048                    .ToListAsync();
 49
 050                if (!ordersInShipment.Any())
 51                {
 052                    return Json(new { success = false, message = "Заказы в отправлении не найдены" });
 53                }
 54
 55                // Получаем номер отправления из первого заказа
 056                var postingNumber = await _context.Shipments
 057                    .Where(s => s.Id == shipmentId)
 058                    .Select(s => s.ShipmentNumber)
 059                    .FirstOrDefaultAsync();
 60
 061                if (string.IsNullOrEmpty(postingNumber))
 62                {
 063                    return Json(new { success = false, message = "Номер отправления не найден" });
 64                }
 65
 66                // Формируем данные для отображения
 067                var ordersData = ordersInShipment.Select(o => new
 068                {
 069                    id = o.Id,
 070                    article = o.Article,
 071                    productName = o.ProductName,
 072                    fbsOzonSkuId = o.ProductInfo?.FbsOzonSkuId,
 073                    quantity = o.Quantity ?? 0
 074                }).ToList();
 75
 076                return Json(new
 077                {
 078                    success = true,
 079                    data = new
 080                    {
 081                        postingNumber = postingNumber,
 082                        orders = ordersData
 083                    }
 084                });
 85            }
 086            catch (Exception ex)
 87            {
 088                return Json(new { success = false, message = $"Ошибка при получении данных: {ex.Message}" });
 89            }
 090        }
 91
 92        /// <summary>
 93        /// Разделяет заказ на Ozon через API
 94        /// </summary>
 95        [HttpPost]
 96        [Route("SplitOzonOrder")]
 97        public async Task<IActionResult> SplitOzonOrder([FromBody] OzonSplitRequest request)
 98        {
 99            try
 100            {
 0101                if (string.IsNullOrEmpty(request.PostingNumber))
 102                {
 0103                    return Json(new { success = false, message = "Номер отправления не указан" });
 104                }
 105
 0106                if (request.SelectedOrders == null || !request.SelectedOrders.Any())
 107                {
 0108                    return Json(new { success = false, message = "Не выбраны заказы для разделения" });
 109                }
 110
 111                // Получаем один из заказов для определения Ozon клиента
 0112                var firstOrderId = request.SelectedOrders.First().OrderId;
 0113                var order = await _context.Orders
 0114                    .Include(o => o.OzonClient)
 0115                    .FirstOrDefaultAsync(o => o.Id.ToString() == firstOrderId);
 116
 0117                if (order?.OzonClient == null)
 118                {
 0119                    return Json(new { success = false, message = "Не найден Ozon клиент для заказа" });
 120                }
 121
 0122                var ozonClient = await _ozonClientServices.GetOzonClientAsync(order.OzonClient.Id);
 0123                if (ozonClient == null)
 124                {
 0125                    return Json(new { success = false, message = "Ozon клиент не найден" });
 126                }
 127
 128                // Проверяем наличие учетных данных
 0129                var clientId = ozonClient.DecryptClientId;
 0130                var apiKey = ozonClient.DecryptApiKey;
 131
 0132                if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(apiKey))
 133                {
 0134                    return Json(new
 0135                        { success = false, message = "Отсутствуют учетные данные Ozon API (Client-Id или Api-Key)" });
 136                }
 137
 138                // Устанавливаем клиента для API запросов
 0139                _ozonApiDataManager.SetClient(clientId, apiKey);
 140
 141                // Получаем все заказы в отправлении для определения оставшихся товаров
 0142                var allOrdersInShipment = await _context.Orders
 0143                    .Include(o => o.ProductInfo)
 0144                    .Where(o => o.ShipmentId == request.ShipmentId)
 0145                    .ToListAsync();
 146
 0147                var selectedOrderIds = request.SelectedOrders.Select(o => o.OrderId).ToHashSet();
 148
 149                // Создаем список отправлений для API Ozon
 0150                var postings = new List<FbsSplitPosting>();
 151
 152                // 1. Новое отправление с выбранными заказами
 0153                var newPosting = new FbsSplitPosting
 0154                {
 0155                    Products = request.SelectedOrders.Select(o => new FbsSplitProduct
 0156                    {
 0157                        ProductId = o.FbsOzonSkuId,
 0158                        Quantity = o.Quantity
 0159                    }).ToList()
 0160                };
 0161                postings.Add(newPosting);
 162
 163                // 2. Оставшееся отправление с невыбранными заказами
 0164                var remainingOrders = allOrdersInShipment
 0165                    .Where(o => !selectedOrderIds.Contains(o.Id.ToString()))
 0166                    .ToList();
 167
 0168                if (remainingOrders.Any())
 169                {
 0170                    var remainingPosting = new FbsSplitPosting
 0171                    {
 0172                        Products = remainingOrders
 0173                            .Where(o => o.ProductInfo?.FbsOzonSkuId != null)
 0174                            .Select(o => new FbsSplitProduct
 0175                            {
 0176                                ProductId = long.Parse(o.ProductInfo!.FbsOzonSkuId!),
 0177                                Quantity = o.Quantity ?? 1
 0178                            }).ToList()
 0179                    };
 180
 0181                    if (remainingPosting.Products.Any())
 182                    {
 0183                        postings.Add(remainingPosting);
 184                    }
 185                }
 186
 187                // Проверяем, что есть минимум 2 отправления
 0188                if (postings.Count < 2)
 189                {
 0190                    return Json(new
 0191                    {
 0192                        success = false,
 0193                        message =
 0194                            "Для разделения необходимо минимум 2 отправления. Выберите часть товаров, оставив остальные 
 0195                    });
 196                }
 197
 198                // Вызываем метод разделения через OzonApiDataManager
 0199                var result = await _ozonApiDataManager.SplitFbsPosting(request.PostingNumber, postings);
 200
 0201                if (result != null && result.Postings != null && result.Postings.Any())
 202                {
 203                    // Обновляем номера отправлений для выбранных заказов
 0204                    var selectedOrders = allOrdersInShipment
 0205                        .Where(o => selectedOrderIds.Contains(o.Id.ToString()))
 0206                        .ToList();
 207
 208                    // Получаем номер нового отправления из результата API
 0209                    var newPostingNumber = result.Postings.First().PostingNumber;
 210
 0211                    if (!string.IsNullOrEmpty(newPostingNumber))
 212                    {
 0213                        var newShipmentId = await _shipmentRepository.GetOrCreateAsync(newPostingNumber);
 214
 0215                        foreach (var selectedOrder in selectedOrders)
 216                        {
 0217                            selectedOrder.ShipmentNumber = newPostingNumber;
 0218                            selectedOrder.ShipmentId = newShipmentId;
 219                        }
 220
 0221                        await _context.SaveChangesAsync();
 222                    }
 223
 0224                    return Json(new
 0225                    {
 0226                        success = true,
 0227                        message = "Заказ успешно разделен на Ozon",
 0228                        data = result
 0229                    });
 230                }
 231                else
 232                {
 0233                    return Json(new { success = false, message = "Не удалось разделить заказ. Ответ от API пустой." });
 234                }
 235            }
 0236            catch (Exception ex)
 237            {
 0238                return Json(new { success = false, message = $"Ошибка при разделении заказа: {ex.Message}" });
 239            }
 0240        }
 241    }
 242
 243    /// <summary>
 244    /// Модель запроса для разделения заказа на Ozon
 245    /// </summary>
 246    public class OzonSplitRequest
 247    {
 248        public string PostingNumber { get; set; } = string.Empty;
 249        public int ShipmentId { get; set; }
 250        public List<OzonSplitOrderItem> SelectedOrders { get; set; } = new();
 251    }
 252
 253    /// <summary>
 254    /// Элемент заказа для разделения
 255    /// </summary>
 256    public class OzonSplitOrderItem
 257    {
 258        public string OrderId { get; set; } = string.Empty;
 259        public long FbsOzonSkuId { get; set; }
 260        public int Quantity { get; set; }
 261    }
 262}