< Summary

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

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_OrderId()100%210%
get_FbsOzonSkuId()100%210%
get_Quantity()100%210%

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
 22        public OzonSplitController(
 23            ApplicationDbContext context,
 24            OzonApiDataManager ozonApiDataManager,
 25            OzonClientServices ozonClientServices,
 26            ShipmentRepository shipmentRepository)
 27        {
 28            _context = context;
 29            _ozonApiDataManager = ozonApiDataManager;
 30            _ozonClientServices = ozonClientServices;
 31            _shipmentRepository = shipmentRepository;
 32        }
 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                // Получаем все заказы в этом отправлении
 44                var ordersInShipment = await _context.Orders
 45                    .Include(o => o.ProductInfo)
 46                    .Where(o => o.ShipmentId == shipmentId)
 47                    .AsNoTracking()
 48                    .ToListAsync();
 49
 50                if (!ordersInShipment.Any())
 51                {
 52                    return Json(new { success = false, message = "Заказы в отправлении не найдены" });
 53                }
 54
 55                // Получаем номер отправления из первого заказа
 56                var postingNumber = await _context.Shipments
 57                    .Where(s => s.Id == shipmentId)
 58                    .Select(s => s.ShipmentNumber)
 59                    .FirstOrDefaultAsync();
 60
 61                if (string.IsNullOrEmpty(postingNumber))
 62                {
 63                    return Json(new { success = false, message = "Номер отправления не найден" });
 64                }
 65
 66                // Формируем данные для отображения
 67                var ordersData = ordersInShipment.Select(o => new
 68                {
 69                    id = o.Id,
 70                    article = o.Article,
 71                    productName = o.ProductName,
 72                    fbsOzonSkuId = o.ProductInfo?.FbsOzonSkuId,
 73                    quantity = o.Quantity ?? 0
 74                }).ToList();
 75
 76                return Json(new
 77                {
 78                    success = true,
 79                    data = new
 80                    {
 81                        postingNumber = postingNumber,
 82                        orders = ordersData
 83                    }
 84                });
 85            }
 86            catch (Exception ex)
 87            {
 88                return Json(new { success = false, message = $"Ошибка при получении данных: {ex.Message}" });
 89            }
 90        }
 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            {
 101                if (string.IsNullOrEmpty(request.PostingNumber))
 102                {
 103                    return Json(new { success = false, message = "Номер отправления не указан" });
 104                }
 105
 106                if (request.SelectedOrders == null || !request.SelectedOrders.Any())
 107                {
 108                    return Json(new { success = false, message = "Не выбраны заказы для разделения" });
 109                }
 110
 111                // Получаем один из заказов для определения Ozon клиента
 112                var firstOrderId = request.SelectedOrders.First().OrderId;
 113                var order = await _context.Orders
 114                    .Include(o => o.OzonClient)
 115                    .FirstOrDefaultAsync(o => o.Id.ToString() == firstOrderId);
 116
 117                if (order?.OzonClient == null)
 118                {
 119                    return Json(new { success = false, message = "Не найден Ozon клиент для заказа" });
 120                }
 121
 122                var ozonClient = await _ozonClientServices.GetOzonClientAsync(order.OzonClient.Id);
 123                if (ozonClient == null)
 124                {
 125                    return Json(new { success = false, message = "Ozon клиент не найден" });
 126                }
 127
 128                // Проверяем наличие учетных данных
 129                var clientId = ozonClient.DecryptClientId;
 130                var apiKey = ozonClient.DecryptApiKey;
 131
 132                if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(apiKey))
 133                {
 134                    return Json(new
 135                        { success = false, message = "Отсутствуют учетные данные Ozon API (Client-Id или Api-Key)" });
 136                }
 137
 138                // Устанавливаем клиента для API запросов
 139                _ozonApiDataManager.SetClient(clientId, apiKey);
 140
 141                // Получаем все заказы в отправлении для определения оставшихся товаров
 142                var allOrdersInShipment = await _context.Orders
 143                    .Include(o => o.ProductInfo)
 144                    .Where(o => o.ShipmentId == request.ShipmentId)
 145                    .ToListAsync();
 146
 147                var selectedOrderIds = request.SelectedOrders.Select(o => o.OrderId).ToHashSet();
 148
 149                // Создаем список отправлений для API Ozon
 150                var postings = new List<FbsSplitPosting>();
 151
 152                // 1. Новое отправление с выбранными заказами
 153                var newPosting = new FbsSplitPosting
 154                {
 155                    Products = request.SelectedOrders.Select(o => new FbsSplitProduct
 156                    {
 157                        ProductId = o.FbsOzonSkuId,
 158                        Quantity = o.Quantity
 159                    }).ToList()
 160                };
 161                postings.Add(newPosting);
 162
 163                // 2. Оставшееся отправление с невыбранными заказами
 164                var remainingOrders = allOrdersInShipment
 165                    .Where(o => !selectedOrderIds.Contains(o.Id.ToString()))
 166                    .ToList();
 167
 168                if (remainingOrders.Any())
 169                {
 170                    var remainingPosting = new FbsSplitPosting
 171                    {
 172                        Products = remainingOrders
 173                            .Where(o => o.ProductInfo?.FbsOzonSkuId != null)
 174                            .Select(o => new FbsSplitProduct
 175                            {
 176                                ProductId = long.Parse(o.ProductInfo!.FbsOzonSkuId!),
 177                                Quantity = o.Quantity ?? 1
 178                            }).ToList()
 179                    };
 180
 181                    if (remainingPosting.Products.Any())
 182                    {
 183                        postings.Add(remainingPosting);
 184                    }
 185                }
 186
 187                // Проверяем, что есть минимум 2 отправления
 188                if (postings.Count < 2)
 189                {
 190                    return Json(new
 191                    {
 192                        success = false,
 193                        message =
 194                            "Для разделения необходимо минимум 2 отправления. Выберите часть товаров, оставив остальные 
 195                    });
 196                }
 197
 198                // Вызываем метод разделения через OzonApiDataManager
 199                var result = await _ozonApiDataManager.SplitFbsPosting(request.PostingNumber, postings);
 200
 201                if (result != null && result.Postings != null && result.Postings.Any())
 202                {
 203                    // Обновляем номера отправлений для выбранных заказов
 204                    var selectedOrders = allOrdersInShipment
 205                        .Where(o => selectedOrderIds.Contains(o.Id.ToString()))
 206                        .ToList();
 207
 208                    // Получаем номер нового отправления из результата API
 209                    var newPostingNumber = result.Postings.First().PostingNumber;
 210
 211                    if (!string.IsNullOrEmpty(newPostingNumber))
 212                    {
 213                        var newShipmentId = await _shipmentRepository.GetOrCreateAsync(newPostingNumber);
 214
 215                        foreach (var selectedOrder in selectedOrders)
 216                        {
 217                            selectedOrder.ShipmentNumber = newPostingNumber;
 218                            selectedOrder.ShipmentId = newShipmentId;
 219                        }
 220
 221                        await _context.SaveChangesAsync();
 222                    }
 223
 224                    return Json(new
 225                    {
 226                        success = true,
 227                        message = "Заказ успешно разделен на Ozon",
 228                        data = result
 229                    });
 230                }
 231                else
 232                {
 233                    return Json(new { success = false, message = "Не удалось разделить заказ. Ответ от API пустой." });
 234                }
 235            }
 236            catch (Exception ex)
 237            {
 238                return Json(new { success = false, message = $"Ошибка при разделении заказа: {ex.Message}" });
 239            }
 240        }
 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    {
 0258        public string OrderId { get; set; } = string.Empty;
 0259        public long FbsOzonSkuId { get; set; }
 0260        public int Quantity { get; set; }
 261    }
 262}