< Summary

Class:SVETA.Api.Controllers.GoodsController
Assembly:SVETA.Api
File(s):/opt/dev/sveta_api_build/SVETA.Api/Controllers/GoodsController.cs
/opt/dev/sveta_api_build/SVETA.Api/Controllers/GoodsController.Obsolete.cs
/opt/dev/sveta_api_build/SVETA.Api/Data/DTO/FileInputModelDTO.cs
Covered lines:0
Uncovered lines:593
Coverable lines:593
Total lines:1196
Line coverage:0% (0 of 593)
Covered branches:0
Total branches:268
Branch coverage:0% (0 of 268)

Metrics

MethodLine coverage Branch coverage
.ctor(...)0%100%
GetActiveGoodsFromCategory()0%0%
GetActiveGoodsFromCategoryCount()0%0%
GetAllGoodsFromCategory()0%0%
GetAllGoodsFromCategoryCount()0%0%
GetCategoriesParent()0%0%
GetGood()0%0%
UploadGoodImage()0%0%
UpdateGood()0%0%
CreateGood()0%0%
DeleteGood()0%100%
DeleteImages()0%0%
StartDownloadingGoodsImages()0%100%
GetDownloadingGoodsImagesStatus()0%100%
DownloadGoods()0%100%
.cctor()0%100%
ToCatalogGoodDtoMapper()0%0%
ToGoodDtoMapper()0%0%
GetGoods()0%0%
GetActiveGoods()0%0%
GetGoodsByCategory()0%0%
SearchGoods()0%0%
CreateGood()0%0%
PostGood()0%0%
ApprooveGoodForCatalog()0%0%
SwitchOffGood()0%0%
UploadGoodFromFile()0%0%
PrepareGood()0%0%
ToShortGoodDtoMapper()0%0%
FromDtoMapper()0%0%
get_Good()0%100%
get_File()0%100%

File(s)

/opt/dev/sveta_api_build/SVETA.Api/Controllers/GoodsController.cs

#LineLine coverage
 1using AutoMapper;
 2using SkiaSharp;
 3using Microsoft.AspNetCore.Http;
 4using Microsoft.AspNetCore.Mvc;
 5using Microsoft.EntityFrameworkCore;
 6using Microsoft.Extensions.Logging;
 7using Microsoft.Extensions.Options;
 8using SVETA.Api.Data.Domain;
 9using SVETA.Api.Data.DTO;
 10using SVETA.Api.Data.DTO.Goods;
 11using SVETA.Api.Helpers;
 12using Swashbuckle.AspNetCore.Annotations;
 13using System;
 14using System.Collections.Generic;
 15using System.IO;
 16using System.Linq;
 17using System.Text;
 18using System.Threading.Tasks;
 19using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 20using WinSolutions.Sveta.Server.Data.DataModel.Kinds;
 21using WinSolutions.Sveta.Server.Services.Interfaces;
 22using Microsoft.AspNetCore.Authorization;
 23using Microsoft.EntityFrameworkCore.Internal;
 24using WinSolutions.Sveta.Common.Extensions;
 25using WinSolutions.Sveta.Common;
 26using SVETA.Api.Services.Interfaces;
 27using WinSolutions.Sveta.Server.Data.DataModel.Extensions;
 28using Department = DocumentFormat.OpenXml.Bibliography.Department;
 29
 30namespace SVETA.Api.Controllers
 31{
 32    /// <summary>
 33    /// Controller goods
 34    /// </summary>
 35    /// [SwaggerOperation(Tags = new[] { "Management Reports" })]
 36    [Route("api/v1/Goods")]
 37    [ApiController]
 38    [Authorize]
 39    public partial class GoodsController : SvetaController
 40    {
 41        const string _routeUrl = "api/v1/Goods";
 42        readonly IGoodService _service;
 43        readonly IContragentService _contragentService;
 44        readonly ICategoryService _categoryService;
 45        readonly IBrandService _brandService;
 46        readonly IDirectoriesService _dirService;
 47        readonly ICountryService _countryService;
 48        readonly ILogger<GoodsController> _logger;
 49        readonly ImagesSettings _imagesSettings;
 50        readonly ConfigurationsSettings _confSettings;
 51        readonly IBarcodeService _barcodeService;
 52        readonly IDownloadGoodsImagesWorker _downloadGoodsImagesWorker;
 53        IDiskStorageService _diskStorage;
 54        const int searchLimit = 12;
 55
 56        public GoodsController(IGoodService service,
 57            IContragentService contragentService,
 58            ICategoryService categoryService,
 59            IBrandService brandService,
 60            IDirectoriesService dirService,
 61            ICountryService countryService,
 62            IBarcodeService barcodeService,
 63            IDiskStorageService diskStorage,
 64            IOptions<ImagesSettings> imagesSettings,
 65            IOptions<ConfigurationsSettings> confSettings,
 66            IDownloadGoodsImagesWorker downloadGoodsImagesWorker,
 067            ILogger<GoodsController> logger) : base(logger)
 068        {
 069            _service = service;
 070            _logger = logger;
 071            _dirService = dirService;
 072            _confSettings = confSettings.Value;
 073            _contragentService = contragentService;
 074            _categoryService = categoryService;
 075            _brandService = brandService;
 076            _countryService = countryService;
 077            _barcodeService = barcodeService;
 078            _imagesSettings = imagesSettings.Value;
 079            _diskStorage = diskStorage;
 080            _downloadGoodsImagesWorker = downloadGoodsImagesWorker;
 081        }
 82
 83
 84        /// <summary>
 85        /// Возвращает только активные товары из категории
 86        /// </summary>
 87        /// <param name="id">код категории, 0 если возвращать товары из всех категорий</param>
 88        /// <param name="page">Любое значение ниже нуля изменится на 1, пейджинг: номер страницы</param>
 89        /// <param name="limit">Любое значение ниже нуля изменится на 10, пейджинг: размер страницы</param>
 90        /// <param name="filter">фильтр по значимым полям (Name, Barcode)</param>
 91        /// <param name="sort">сортировка по полям name,name|desc, brandName,brandName|desc, По умолчанию по id</param>
 92        /// <remarks>author: oboligatov\aabelentsov</remarks>
 93        [HttpGet("Active/FromCategory/{id}")]
 94        [SwaggerResponse(200, "Успешно", typeof(BaseResponseDTO<GoodCatalogDTO>))]
 95        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 96        [Authorize(Roles = Role.SystemAdmin+"," + Role.SystemOperator)]
 97        public async Task<IActionResult> GetActiveGoodsFromCategory(long id, int page = 1, int limit = 10, string filter
 098        {
 099            filter = filter.NormalizeName();
 0100            page = page < 1 ? 1 : page;
 0101            limit = limit < 1 ? 10 : limit;
 0102            var goods = await _service.GetGoods(page - 1, limit, filter, sort, id != 0 ? id : (long?)null, true);
 0103            goods.ForEach(g => g.Photos.SetPhotoUrl(_imagesSettings));
 104
 105
 0106            var totalCount = await _service.GetGoodsCount(null, (long?)null, true);
 0107            var totalFiltredCount = await _service.GetGoodsCount(filter, id != 0 ? id : (long?)null, true);
 108
 0109            var response = new BaseResponseDTO<GoodCatalogDTO>(_routeUrl, page, limit, totalFiltredCount, totalCount, so
 0110            {
 0111                Data = ToCatalogGoodDtoMapper().Map<List<GoodCatalogDTO>>(goods)
 0112            };
 0113            return Ok(response);
 0114        }
 115
 116        /// <summary>
 117        /// Возвращает количество только активных товаров из категории
 118        /// </summary>
 119        /// <param name="id">код категории, 0 если возвращать товары из всех категорий</param>
 120        /// <param name="filter">фильтр по значимым полям (Name, Barcode)</param>
 121        /// <remarks>author: oboligatov</remarks>
 122        [HttpGet("Active/FromCategory/{id}/Count")]
 123        [SwaggerResponse(200, "Успешно", typeof(CountDTO))]
 124        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 125        [Authorize(Roles = Role.SystemAdmin+"," + Role.SystemOperator)]
 126        public async Task<IActionResult> GetActiveGoodsFromCategoryCount(long id, string filter = null)
 0127        {
 0128            filter = filter.NormalizeName();
 0129            return Ok(new CountDTO(await _service.GetGoodsCount(filter, id != 0 ? id : (long?)null, true)));
 0130        }
 131
 132        /// <summary>
 133        /// Возвращает все (активные + неактивные) товары из категории
 134        /// </summary>
 135        /// <param name="id">код категории, 0 если возвращать товары из всех категорий</param>
 136        /// <param name="page">Любое значение ниже нуля изменится на 1, пейджинг: номер страницы</param>
 137        /// <param name="limit">Любое значение ниже нуля изменится на 10, пейджинг: размер страницы</param>
 138        /// <param name="filter">фильтр по значимым полям (Name, Barcode)</param>
 139        /// <param name="sort">сортировка по полям name,name|desc, brandName,brandName|desc, По умолчанию по id</param>
 140        /// <remarks>author: oboligatov</remarks>
 141        [HttpGet("FromCategory/{id}")]
 142        [SwaggerResponse(200, "Успешно", typeof(BaseResponseDTO<GoodCatalogDTO>))]
 143        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 144        [Authorize(Roles = Role.SystemAdmin+"," + Role.SystemOperator)]
 145        public async Task<IActionResult> GetAllGoodsFromCategory(long id, int page = 1, int limit = 10, string filter = 
 0146        {
 0147            filter = filter.NormalizeName();
 0148            page = page < 1 ? 1 : page;
 0149            limit = limit < 1 ? 10 : limit;
 0150            var goods = await _service.GetGoods(page - 1, limit, filter, sort, id != 0 ? id : (long?)null, false);
 0151            goods.ForEach(g => g.Photos.SetPhotoUrl(_imagesSettings));
 152
 0153            var totalCount = await _service.GetGoodsCount(null, null, false);
 0154            var totalFiltredCount = await _service.GetGoodsCount(filter, id != 0 ? id : (long?)null, false);
 155
 0156            var response = new BaseResponseDTO<GoodCatalogDTO>(_routeUrl, page, limit, totalFiltredCount, totalCount, so
 0157            {
 0158                Data = ToCatalogGoodDtoMapper().Map<List<GoodCatalogDTO>>(goods)
 0159            };
 0160            return Ok(response);
 0161        }
 162
 163        /// <summary>
 164        /// Возвращает количество всех (активные + неактивные) товаров из категории
 165        /// </summary>
 166        /// <param name="id">код категории, 0 если возвращать товары из всех категорий</param>
 167        /// <param name="filter">фильтр по значимым полям (Name, Barcode)</param>
 168        /// <remarks>author: oboligatov</remarks>
 169        [HttpGet("FromCategory/{id}/Count")]
 170        [SwaggerResponse(200, "Успешно", typeof(CountDTO))]
 171        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 172        [Authorize(Roles = Role.SystemAdmin+"," + Role.SystemOperator)]
 173        public async Task<IActionResult> GetAllGoodsFromCategoryCount(long id, string filter = null)
 0174        {
 0175            filter = filter.NormalizeName();
 0176            return Ok(new CountDTO(await _service.GetGoodsCount(filter, id != 0 ? id : (long?)null, false)));
 0177        }
 178
 179        /// <summary>
 180        /// Возвращает группы, расположенные над товаром
 181        /// </summary>
 182        /// <remarks>author: oboligatov</remarks>
 183        /// <param name="id">Id товара</param>
 184        [HttpGet("{id}/ParentCategories")]
 185        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<CategoryResponseDTO>))]
 186        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 187        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 188        [Authorize(Roles = Role.SystemAdmin+"," + Role.SystemOperator)]
 189        public async Task<IActionResult> GetCategoriesParent(long id)
 0190        {
 0191            var good = await _service.GetGood(id);
 0192            if (good == null)
 0193            {
 0194                return NotFoundResult();
 195            }
 196
 0197            List<CategoryResponseDTO> categories = new List<CategoryResponseDTO>();
 0198            var category = await _categoryService.GetNoTrackCategory(good.Category.Id);
 199
 0200            var config = new MapperConfiguration(cfg =>
 201            {
 202                cfg.CreateMap<Category, CategoryResponseDTO>()
 203                    .ForMember(d => d.ParentId, e => e.MapFrom(s => s.Parent != null ? s.Parent.Id : 0));
 204            });
 0205            IMapper mapper = config.CreateMapper();
 206
 0207            while (category != null)
 0208            {
 0209                CategoryResponseDTO categoryDto = mapper.Map<Category, CategoryResponseDTO>(category);
 0210                categories.Add(categoryDto);
 0211                category = category.Parent != null ? await _categoryService.GetCategory(category.Parent.Id) : null;
 0212            }
 213
 0214            return Ok(categories);
 0215        }
 216
 217        /// <summary>
 218        /// Возвращает товар
 219        /// </summary>
 220        /// <remarks>author: oboligatov</remarks>
 221        /// <param name="id">код товара</param>
 222        [HttpGet("{id}")]
 223        [SwaggerResponse(200, "Успешно", typeof(GoodDTO))]
 224        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 225        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 226        [Authorize(Roles = Role.SystemAdmin +"," + Role.SystemOperator)]
 227        public async Task<IActionResult> GetGood(long id)
 0228        {
 0229            var good = await _service.GetGood(id);
 0230            if (good == null)
 0231            {
 0232                return NotFoundResult();
 233            }
 234
 0235            good.Photos.SetPhotoUrl(_imagesSettings);
 236
 0237            return Ok(ToGoodDtoMapper().Map<Good, GoodDTO>(good));
 0238        }
 239
 240        /// <summary>
 241        /// Загружает картинку для товара
 242        /// </summary>
 243        /// <remarks>author: oboligatov</remarks>
 244        /// <param name="id">Id товара</param>
 245        /// <param name="file">картинка</param>
 246        /// <returns></returns>
 247        [HttpPost("{id}/Image")]
 248        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 249        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 250        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 251        [Authorize(Roles = Role.SystemAdmin)]
 252        public async Task<IActionResult> UploadGoodImage(long id, IFormFile file)
 0253        {
 0254            int prevWidth = _imagesSettings.ImagePreveiwWidth, prevHeight = _imagesSettings.ImagePreveiwHeight;
 255            int fullWidth, fullHeight, newPrevWidth, newPrevHeight;
 0256            Good good = await _service.GetGood(id);
 257
 0258            if (good == null)
 0259                throw new ArgumentException($"Товар #{id} не найден");
 260
 0261            if (file == null || file?.Length == 0)
 0262                throw new ArgumentException("Изображение не выбрано");
 263
 0264            string[] extensions = _confSettings.GetConfValue("ImageSettings", "AllowedExtensions").Split(",");
 0265            string fileExtension = Path.GetExtension(file.FileName.ToLower());
 0266            if (!extensions.Contains(fileExtension))
 0267                throw new ArgumentException($"Расширение файла {fileExtension} не поддерживается");
 268
 0269            string fileNameFull = Transliteration.Translit(good.Name.ToLowerInvariant()) + "_" + DateTime.Now.Ticks.ToSt
 0270            string fileNamePrev = Transliteration.Translit(good.Name.ToLowerInvariant()) + "_" + DateTime.Now.Ticks.ToSt
 0271            string filePathFull = Path.Combine(_imagesSettings.ImageSavePath, fileNameFull);
 0272            string filePathPrev = Path.Combine(_imagesSettings.ImageSavePath, fileNamePrev);
 0273            System.Drawing.Image fullImage = System.Drawing.Image.FromStream(file.OpenReadStream());
 0274            fullWidth = fullImage.Width;
 0275            fullHeight = fullImage.Height;
 0276            using (var stream = new FileStream(filePathFull, FileMode.Create))
 0277            {
 0278                await file.CopyToAsync(stream);
 0279            }
 0280            if (fullWidth > fullHeight)  //сохраняем пропорции
 0281            {
 0282                newPrevWidth = prevWidth;
 0283                newPrevHeight = fullHeight * prevWidth / fullWidth;
 0284            }
 285            else
 0286            {
 0287                newPrevWidth = fullWidth * prevHeight / fullHeight;
 0288                newPrevHeight = prevHeight;
 0289            }
 0290            using (var stream = System.IO.File.OpenRead(filePathFull))
 0291            using (var inputStream = new SKManagedStream(stream))
 0292            using (var original = SKBitmap.Decode(inputStream))
 0293            {
 0294                using (var resized = original.Resize(new SKImageInfo(newPrevWidth, newPrevHeight), SKFilterQuality.Mediu
 0295                using (var image = SKImage.FromBitmap(resized))
 0296                using (var output = System.IO.File.OpenWrite(filePathPrev))
 0297                    image.Encode(SKEncodedImageFormat.Jpeg, 75).SaveTo(output);
 0298            }
 0299            var photo = new Photo
 0300            {
 0301                FullSizeUrl = fileNameFull,
 0302                PreviewUrl = fileNamePrev,
 0303                PreviewHeight = newPrevHeight,
 0304                PreviewWidth = newPrevWidth,
 0305                FullSizeHeight = fullHeight,
 0306                FullSizeWidth = fullWidth
 0307            };
 0308            if (good.Photos.Count == 0)
 0309                good.Photos.Add(photo);
 310            else
 0311                good.Photos[0] = photo;
 0312            await _service.SetPhoto(good, good.Photos);
 313
 0314            return Ok();
 0315        }
 316
 317        /// <summary>
 318        /// Обновляет поля товара
 319        /// </summary>
 320        /// <remarks>author: oboligatov</remarks>
 321        /// <param name="id">Id товара</param>
 322        /// <param name="goodDto"></param>
 323        [HttpPut("{id}")]
 324        [SwaggerResponse(200, "Успешно", typeof(GoodDTO))]
 325        [SwaggerResponse(400, "Неверные входные параметры", typeof(ErrorDTO))]
 326        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 327        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 328        [Authorize(Roles = Role.SystemAdmin)]
 329        public async Task<IActionResult> UpdateGood(long id, [FromBody] [SwaggerParameter(Required = true)] GoodInputDTO
 0330        {
 0331            var good = await _service.GetGood(id);
 0332            if (good == null)
 0333            {
 0334                return NotFoundResult($"Good #{id} not found");
 335            }
 336
 0337            await PrepareGood(goodDto, good);
 0338            await _service.UpdateGood(good);
 339
 0340            return Ok(ToGoodDtoMapper().Map<GoodDTO>(good));
 0341        }
 342
 343        /// <summary>
 344        /// Создает товар
 345        /// </summary>
 346        /// <remarks>author: oboligatov</remarks>
 347        [HttpPost()]
 348        [SwaggerResponse(200, "Успешно", typeof(GoodDTO))]
 349        [SwaggerResponse(400, "Неверные входные параметры", typeof(ErrorDTO))]
 350        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 351        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 352        [Authorize(Roles = Role.SystemAdmin)]
 353        public async Task<IActionResult> CreateGood([FromBody] [SwaggerParameter(Required = true)] GoodInputDTO goodDto)
 0354        {
 0355            var good = new Good();
 0356            await PrepareGood(goodDto, good);
 0357            await _service.CreateGood(good);
 358
 0359            return Ok(ToGoodDtoMapper().Map<GoodDTO>(good));
 0360        }
 361
 362        /// <summary>
 363        /// Удалить товар
 364        /// </summary>
 365        /// <remarks>author: oboligatov</remarks>
 366        /// <param name="id">Id товара</param>
 367        [HttpDelete("{id}")]
 368        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 369        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 370        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 371        [Authorize(Roles = Role.SystemAdmin)]
 372        public async Task<IActionResult> DeleteGood(long id)
 0373        {
 0374            await _service.DeleteGood(id);
 0375            return Ok();
 0376        }
 377
 378        /// <summary>
 379        /// Удалить все фотографии у товара
 380        /// </summary>
 381        /// <param name="goodId">идентификатор товара</param>
 382        /// <returns></returns>
 383        [HttpPost("{goodId}/DeleteImages")]
 384        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 385        [SwaggerResponse(400, "Ошибка входных данных", typeof(ErrorDTO))]
 386        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 387        [Authorize(Roles = Role.SystemAdmin)]
 388        public async Task<IActionResult> DeleteImages(long goodId)
 0389        {
 0390            var good = await _service.GetGood(goodId) ??
 0391                       throw new ArgumentException($"Товар #{goodId} не найден");
 0392            good.Photos.RemoveRange(0, good.Photos.Count);
 0393            await _service.UpdateGood(good);
 0394            return Ok();
 0395        }
 396
 397        /// <summary>
 398        /// Создает задачу на выгрузку картинок для товаров
 399        /// </summary>
 400        /// <param name="activeOnly">возвращать картинки только для активных товаров</param>
 401        /// <remarks> значения возвращаемого статуса: 0 - Нет активных скачиваний, 1 - В очереди, 2 - Выгружается, 3 - З
 402        [HttpPost("DownloadGoodsImages")]
 403        [SwaggerResponse(200, "Успешно", typeof(DownloadGoodsImagesStatusDTO))]
 404        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 405        public async Task<IActionResult> StartDownloadingGoodsImages(bool activeOnly = true)
 0406        {
 0407            return Ok(await _downloadGoodsImagesWorker.StartDownload(activeOnly));
 0408        }
 409
 410        /// <summary>
 411        /// Возвращает статус активного скачивания
 412        /// </summary>
 413        /// <remarks> значения возвращаемого статуса: 0 - Нет активных скачиваний, 1 - В очереди, 2 - Выгружается, 3 - З
 414        [HttpGet("DownloadGoodsImages/Status")]
 415        [SwaggerResponse(200, "Успешно", typeof(DownloadGoodsImagesStatusDTO))]
 416        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 417        public async Task<IActionResult> GetDownloadingGoodsImagesStatus()
 0418        {
 0419            return Ok(await _downloadGoodsImagesWorker.GetDownloadStatus());
 0420        }
 421
 422        /// <summary>
 423        /// Выгрузка номенклатуры в excel
 424        /// </summary>
 425        /// <param name="activeOnly">выгружать только активные товары (иначе все)</param>
 426        /// <returns></returns>
 427        [HttpGet("DownloadGoods")]
 428        [SwaggerResponse(200, "Успешно", typeof(File))]
 429        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 430        [Authorize(Roles = Role.SystemAdmin + "," + Role.SystemOperator)]
 431        public async Task<IActionResult> DownloadGoods(bool activeOnly = true)
 0432        {
 0433            var goods = await _service.GetGoods(0, int.MaxValue, null, null, (long?)null, activeOnly);
 434
 0435            var rows = new List<string[]>();
 0436            rows.Add(new string[]
 0437            {
 0438                "BarCode", "Name", "ManufacturerName", "ExpirationDays", "Weight",
 0439                "Width", "Height", "Thickness", "ParentCategoryName", "CategoryCode", "CategoryName",
 0440                "VatName", "CustomDeclarationNumber", "UnitName", "CountryName", "ConformityCertNumber",
 0441                "GroupPackNesting", "GroupPackWidth", "GroupPackHeight", "GroupPackThickness", "PalletNesting",
 0442                "BrandName", "SubbrandName", "LargeImageFileName", "SmallImageFileName", "LargeImageFileExists", "SmallI
 0443                "UniqueCode", "IsActive"
 0444            });
 445
 0446            goods.ForEach(x =>
 0447            {
 0448                rows.Add(new string[]
 0449                {
 450                    x.GoodBarcodes.FirstOrDefault(d => d.IsPrimary) != null
 451                        ? x.GoodBarcodes.FirstOrDefault(d => d.IsPrimary).BarCode.Code
 0452                        : x.DefaultBarCode?.Code,
 0453                    x.Name,
 0454                    "Производитель не указан",
 0455                    x.ExpirationDays.ToString(),
 0456                    x.Weight.ToString(),
 0457                    x.Width.ToString(),
 0458                    x.Height.ToString(),
 0459                    x.Thickness.ToString(),
 0460                    x.Category.Parent?.Name,
 0461                    x.Category.Code,
 0462                    x.Category.Name,
 0463                    x.VatsKind.Code,
 0464                    x.CustomDeclarationNumber,
 0465                    x.UnitsKind.Name,
 0466                    x.Country.Name,
 0467                    x.ConformityCertNumber,
 0468                    x.GroupPackNesting.ToString(),
 0469                    x.GroupPackWidth.ToString(),
 0470                    x.GroupPackHeight.ToString(),
 0471                    x.GroupPackThickness.ToString(),
 0472                    x.PalletNesting.ToString(),
 0473                    x.Brand.Name,
 0474                    x.SubBrand?.Name,
 0475                    x.Photos.FirstOrDefault()?.FullSizeUrl,
 0476                    x.Photos.FirstOrDefault()?.PreviewUrl,
 0477                    _diskStorage.PictureExists(x.Photos.FirstOrDefault()?.FullSizeUrl) ? "1" : "0",
 0478                    _diskStorage.PictureExists(x.Photos.FirstOrDefault()?.PreviewUrl) ? "1" : "0",
 0479                    x.UniqueCode,
 0480                    (x.RecState.Id == (long)RecordState.Active) ? "1" : "0"
 0481                });
 0482            });
 483
 0484            var stream = CsvUtil.ToExcelStream(rows);
 0485            _diskStorage.SaveDownload("goods.xlsx", stream, out string fileName);
 0486            return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", Path.GetFileName(fi
 0487        }
 488
 0489        static char[] trimChars = new char[] { '/', '\\' };
 490
 0491        private static IMapper ToCatalogGoodDtoMapper() => new MapperConfiguration(cfg =>
 0492        {
 0493            cfg.CreateMap<Good, GoodCatalogDTO>()
 0494                .ForMember(d => d.Barcode,
 0495                    e => e.MapFrom(
 0496                        s => s.GoodBarcodes.FirstOrDefault(barcode => barcode.IsPrimary) != null ?
 0497                            s.GoodBarcodes.FirstOrDefault(barcode => barcode.IsPrimary).BarCode.Code
 0498                            : s.DefaultBarCode.Code))
 0499                .ForMember(d => d.BrandId, e => e.MapFrom(s => s.Brand.Id));
 0500            cfg.CreateMap<Photo, PhotoDTO>();
 0501            cfg.CreateMap<Brand, IdNameDTO>();
 0502        }).CreateMapper();
 503
 504        private static IMapper ToGoodDtoMapper()
 0505        {
 0506            var config = new MapperConfiguration(cfg =>
 0507            {
 0508                cfg.CreateMap<Good, GoodDTO>()
 0509                    .ForMember(d => d.CategoryId, e => e.MapFrom(s => s.Category.Id))
 0510                    .ForMember(d => d.BrandId, e => e.MapFrom(s => s.Brand.Id))
 0511                    .ForMember(d => d.SubBrandId, e => e.MapFrom(s => s.SubBrand.Id))
 0512                    .ForMember(d => d.UnitKindId, e => e.MapFrom(s => int.Parse(s.UnitsKind.Code)))
 0513                    .ForMember(d => d.VatId, e => e.MapFrom(s => int.Parse(s.VatsKind.Code)))
 0514                    .ForMember(d => d.VatKind, e => e.MapFrom(s => new EnumDB_DTO { Id = s.VatsKind.Id, Code = s.VatsKin
 0515                    .ForMember(d => d.UnitKind, e => e.MapFrom(s => new EnumDB_DTO { Id = s.UnitsKind.Id, Code = s.Units
 0516                    .ForMember(d => d.CountryId, e => e.MapFrom(s => s.Country.Id))
 0517                    .ForMember(d => d.MainBarcode, e => e.MapFrom(
 0518                        s => new BarCodeDTO
 0519                        {
 0520                            Id = s.GoodBarcodes.FirstOrDefault(b => b.IsPrimary) != null ?
 0521                                s.GoodBarcodes.FirstOrDefault(b => b.IsPrimary).BarCode.Id
 0522                                : s.DefaultBarCode.Id,
 0523                            Code = s.GoodBarcodes.FirstOrDefault(b => b.IsPrimary) != null ?
 0524                                s.GoodBarcodes.FirstOrDefault(b => b.IsPrimary).BarCode.Code
 0525                                : s.DefaultBarCode.Code
 0526                        }))
 0527                    .ForMember(d => d.Barcodes, e =>
 0528                        e.MapFrom(s => s.GoodBarcodes.Where(b => !b.IsPrimary).Select(b => new BarCodeDTO{Code = b.BarCo
 0529                    .ForMember(d => d.IsActive, e => e.MapFrom(s => s.RecState.Code == RecordState.Active.ToString()));
 0530                cfg.CreateMap<Photo, PhotoDTO>();
 0531                cfg.CreateMap<Category, IdNameDTO>()
 0532                    .ForMember(d => d.Id, e => e.MapFrom(s => s.Id))
 0533                    .ForMember(d => d.Name, e => e.MapFrom(s => s.Name));
 0534                cfg.CreateMap<Contragent, IdNameDTO>()
 0535                    .ForMember(d => d.Id, e => e.MapFrom(s => s.Id))
 0536                    .ForMember(d => d.Name, e => e.MapFrom(s => s.ShortName));
 0537                cfg.CreateMap<Brand, IdNameDTO>()
 0538                    .ForMember(d => d.Id, e => e.MapFrom(s => s.Id))
 0539                    .ForMember(d => d.Name, e => e.MapFrom(s => s.Name));
 0540                cfg.CreateMap<BarCode, BarCodeDTO>();
 0541                cfg.CreateMap<Country, IdNameDTO>();
 0542            });
 0543            var mapper = config.CreateMapper();
 0544            return mapper;
 0545        }
 546
 547        async Task<Good> PrepareGood(GoodInputDTO dto, Good good)
 548        {
 549            dto.Name = dto.Name.NormalizeName().Required(nameof(dto.Name));
 550            dto.Barcode = dto.Barcode.NormalizeName().Required(nameof(dto.Barcode));
 551            if (_service.GetGoodsByName(dto.Name).Any(d => d.Id != good.Id))
 552            {
 553                throw new ArgumentException($"Товар с именем'{dto.Name}' уже существует");
 554            }
 555
 556            good.Country = await _countryService.GetCountry(dto.CountryId);
 557            if (good.Country == null)
 558            {
 559                throw new ArgumentException($"Страна #{dto.CountryId} не найдена");
 560            }
 561            good.GoodBarcodes ??= new List<GoodBarcode>();
 562
 563            good.Category = await _categoryService.FindCategory(dto.CategoryId);
 564            if (good.Category == null)
 565            {
 566                throw new ArgumentException($"Категория #{dto.CategoryId} не найдена");
 567            }
 568
 569            if (dto.BrandId == dto.SubBrandId)
 570            {
 571                throw new ArgumentException($"Бранд #{dto.BrandId} равен субренду #{dto.SubBrandId}");
 572            }
 573
 574            if (dto.ExpirationDays < 0)
 575            {
 576                throw new ArgumentException("Срок годности не может быть отрицательным");
 577            }
 578
 579            good.Brand = dto.BrandId != 0 ? await _brandService.GetBrand(dto.BrandId) : null;
 580
 581            good.SubBrand = dto.SubBrandId.HasValue ? await _brandService.GetBrand(dto.SubBrandId.Value) : null;
 582
 583            good.UnitsKind = await _dirService.GetUnitKindByCode(dto.UnitKindId);
 584            good.RecState = dto.IsActive ? await _dirService.GetRecordState((long)RecordState.Active) : await _dirServic
 585            good.ConformityCertNumber = dto.ConformityCertNumber;
 586            good.CustomDeclarationNumber = dto.CustomDeclarationNumber;
 587            //good.VendorCode = dto.VendorCode;
 588            good.VatsKind = await _dirService.GetVatKindByCode(dto.Vat);
 589            good.Weight = dto.Weight;
 590            good.Width = dto.Width;
 591            good.Height = dto.Height;
 592            good.Thickness = dto.Thickness;
 593            good.GroupPackNesting = dto.GroupPackNesting;
 594            good.GroupPackWidth = dto.GroupPackWidth;
 595            good.GroupPackHeight = dto.GroupPackHeight;
 596            good.GroupPackThickness = dto.GroupPackThickness;
 597            good.MinDeliveryLot = dto.MinDeliveryLot;
 598            good.ExpirationDays = dto.ExpirationDays ?? 0;
 599            good.Name = dto.Name;
 600
 601            var defaultBarcode = await _barcodeService.GetOrCreateBarcode(dto.Barcode);
 0602            if (!good.GoodBarcodes.Any(d => d.BarCodeId == defaultBarcode.Id && d.IsPrimary))
 603            {
 604                var bar = good.GoodBarcodes.FirstOrDefault(d => d.IsPrimary);
 605                if (bar != null)
 606                {
 607                    bar.IsPrimary = false;
 608                    await _barcodeService.UpdateGoodBarcode(bar);
 609                }
 610
 611                if (good.GoodBarcodes.Select(d => d.BarCode).Contains(default))
 612                {
 613                    for (int i = 0; i < good.GoodBarcodes.Count; i++)
 614                    {
 615                        if (good.GoodBarcodes[i].BarCodeId == defaultBarcode.Id)
 616                        {
 617                            good.GoodBarcodes[i].IsPrimary = true;
 618                        }
 619                    }
 620                }
 621                else
 622                {
 623                    good.GoodBarcodes.Add(new GoodBarcode { BarCode = defaultBarcode, IsPrimary = true});
 624                }
 625            }
 626
 627            if (!string.IsNullOrWhiteSpace(dto.AdditionalBarcode))
 628            {
 629                var addBarcode = await _barcodeService.GetOrCreateBarcode(dto.AdditionalBarcode);
 630
 0631                if (!good.GoodBarcodes.Any(d => d.BarCodeId == addBarcode.Id))
 632                {
 633                    good.GoodBarcodes.Add(new GoodBarcode { BarCode = addBarcode, IsPrimary = false});
 634                }
 635            }
 636
 637            return good;
 638        }
 639    }
 640}

/opt/dev/sveta_api_build/SVETA.Api/Controllers/GoodsController.Obsolete.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.IO;
 4using System.Linq;
 5using System.Threading.Tasks;
 6using AutoMapper;
 7using Microsoft.AspNetCore.Mvc;
 8using SVETA.Api.Data.DTO;
 9using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 10using ExcelDataReader;
 11using Microsoft.AspNetCore.Http;
 12using Microsoft.Extensions.Logging;
 13using Newtonsoft.Json;
 14using SVETA.Api.Helpers;
 15using Swashbuckle.AspNetCore.Annotations;
 16using WinSolutions.Sveta.Server.Data.DataModel.Kinds;
 17
 18// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
 19
 20namespace SVETA.Api.Controllers
 21{
 22    public partial class GoodsController : SvetaController
 23    {
 24        /// <summary>
 25        /// [Устарел, используйте GetAllGoodsFromCategory] Возвращает список товаров
 26        /// </summary>
 27        /// <param name="page">Любое значение ниже нуля изменится на 1, </param>
 28        /// <param name="limit">Любое значение ниже нуля изменится на 10, </param>
 29        /// <returns>List of goods</returns>
 30        /// <response code="200">List of goods</response>
 31        [HttpGet("GetGoods")]
 32        [Obsolete]
 33        public async Task<IActionResult> GetGoods(int page = 1, int limit = 10)
 034        {
 035            page = page < 1 ? 1 : page;
 036            limit = limit < 1 ? 10 : limit;
 037            var goods = await _service.GetGoods(page - 1, limit);
 038            IMapper mapper = ToGoodDtoMapper();
 039            return Ok(mapper.Map<List<Good>, List<GoodDTO>>(goods));
 040        }
 41        /// <summary>
 42        /// [Устарел, используйте GetActiveGoodsFromCategory] Возвращает список товаров с фильтрацией по активности для 
 43        /// </summary>
 44        /// <param name="page">Любое значение ниже нуля изменится на 1, </param>
 45        /// <param name="limit">Любое значение ниже нуля изменится на 10, </param>
 46        /// <returns>List of goods</returns>
 47        /// <response code="200">List of goods with active status</response>
 48        [HttpGet("GetActiveGoods")]
 49        [Obsolete]
 50        public async Task<IActionResult> GetActiveGoods(int page = 1, int limit = 10)
 051        {
 052            page = page < 1 ? 1 : page;
 053            limit = limit < 1 ? 10 : limit;
 054            var goods = await _service.GetActiveGoods(page - 1, limit);
 055            IMapper mapper = ToGoodDtoMapper();
 056            return Ok(mapper.Map<List<Good>, List<GoodDTO>>(goods));
 057        }
 58        /// <summary>
 59        /// [Устарел, используйте GetAllGoodsFromCategory] Возвращает список товаров с фильтром по категории
 60        /// </summary>
 61        /// <param name="categoryId"></param>
 62        /// <param name="page">Любое значение ниже нуля изменится на 1, </param>
 63        /// <param name="limit">Любое значение ниже нуля изменится на 10, </param>
 64        /// <returns>List of goods by category</returns>
 65        [HttpGet("GetGoodsByCategory")]
 66        [Obsolete]
 67        public async Task<IActionResult> GetGoodsByCategory(long categoryId, int page = 1, int limit = 10)
 068        {
 069            page = page < 1 ? 1 : page;
 070            limit = limit < 1 ? 10 : limit;
 071            var goods = await _service.GetGoodsByCategory(page - 1, limit, categoryId);
 072            if (goods.Count > 0)
 073            {
 074                IMapper mapper = ToGoodDtoMapper();
 075                return Ok(mapper.Map<List<Good>, List<GoodDTO>>(goods));
 76            }
 077            return Ok(goods);
 078        }
 79
 80        /// <summary>
 81        /// [Устарел, используйте GetAllGoodsFromCategory]
 82        /// </summary>
 83        /// <param name="name"></param>
 84        /// <returns></returns>
 85        [HttpGet("SearchGoods")]
 86        [Obsolete]
 87        public async Task<IActionResult> SearchGoods(string name)
 088        {
 89            try
 090            {
 091                List<Good> goods = await _service.SearchGoods(name, searchLimit);
 092                if (goods.Count > 0)
 093                {
 094                    IMapper mapper = ToGoodDtoMapper();
 095                    return Ok(mapper.Map<List<Good>, List<GoodDTO>>(goods));
 96                }
 097                return NoContent();
 98            }
 099            catch (Exception e)
 0100            {
 0101                return ServerError(e);
 102            }
 0103        }
 104        /// <summary>
 105        /// Создает товар, возвращает его Id
 106        /// </summary>
 107        /// <returns></returns>
 108        [HttpPost("CreateGood")]
 109        [Obsolete]
 110        public async Task<IActionResult> CreateGood()
 0111        {
 112            try
 0113            {
 0114                Good good = new Good()
 0115                {
 0116                    // State = RecordState.Empty,
 0117                    Category = (await _categoryService.GetCategories(0, 1, null)).FirstOrDefault(),
 0118                    DefaultBarCode = new BarCode
 0119                    {
 0120                        Code = "0000000000",
 0121                        //  State = RecordState.Empty,
 0122                    },
 0123                    Name = "",
 0124                   // VendorCode = "",
 0125                    Photos = new List<Photo>()
 0126                    {
 0127                        new Photo {
 0128                           /* PreviewUrl = _imagesSettings.ImageUrl + _imagesSettings.PreviewUrlPlaceholder,
 0129                            FullSizeUrl = _imagesSettings.ImageUrl + _imagesSettings.FullSizeUrlPlaceholder,*/
 0130                        //    State = RecordState.Active
 0131                        }
 0132                    },
 0133                    MinDeliveryLot = -1,
 0134                    ExpirationDays = -1,
 0135                    Weight = -1,
 0136                    Width = -1,
 0137                    Height = -1,
 0138                    Thickness = -1,
 0139                    //Vat = VatKind.Zero,
 0140                    CustomDeclarationNumber = "",
 0141                    //  UnitKind = UnitKind.Kg,
 0142                    ConformityCertNumber = "",
 0143                    GroupPackNesting = -1,
 0144                    GroupPackWidth = -1,
 0145                    GroupPackHeight = -1,
 0146                    GroupPackThickness = -1,
 0147                    PalletNesting = -1,
 0148                    GUID = Guid.NewGuid()
 0149                };
 0150                await _service.CreateGood(good);
 0151                IMapper mapper = ToShortGoodDtoMapper();
 0152                return CreatedAtAction("GetGood", new { Id = good.Id }, mapper.Map<Good, GoodShortDTO>(good));
 153            }
 0154            catch (Exception e)
 0155            {
 0156                return ServerError(e);
 157            }
 0158        }
 159        /// <summary>
 160        /// [Устарел, используйте PutGood] Создает товар по объекту и добавляет картинку
 161        /// </summary>
 162        /// <param name="fileInputModel"></param>
 163        /// <returns>New good</returns>
 164        /// <response code="201">New good</response>
 165        [HttpPost("PostGood")]
 166        [Obsolete]
 167        public async Task<IActionResult> PostGood([FromForm]FileInputModelDTO fileInputModel)
 0168        {
 169            try
 0170            {
 0171                GoodDTO goodDto = JsonConvert.DeserializeObject<GoodDTO>(fileInputModel.Good);
 172
 0173                IFormFile file = fileInputModel.File;
 174
 0175                if (goodDto.CategoryId == 0)
 0176                {
 0177                    return BadRequest("Category Id can not equal Zero");
 178                }
 0179                Good good = await PrepareGood(goodDto);
 0180                if (good.Photos.Count == 0)
 0181                {
 0182                    good.Photos.Add(new Photo());
 0183                }
 0184                if (file?.Length > 0)
 0185                {
 0186                    string[] extensions = null; // _imagesSettings.AllowedExtensions.Split(",");
 0187                    string fileExtension = Path.GetExtension(file.FileName);
 0188                    if (!extensions.Contains(fileExtension))
 0189                    {
 0190                        throw new NotSupportedException($"File type {fileExtension} not supported");
 191                    }
 0192                    string fileName = Transliteration.Translit(good.Name.ToLowerInvariant()) + "_" + DateTime.Now.Ticks.
 0193                    string filePath = Path.Combine(_imagesSettings.ImageSavePath + fileName);
 0194                    using (var stream = new FileStream(filePath, FileMode.Create))
 0195                    {
 0196                        await file.CopyToAsync(stream);
 0197                    }
 0198                    for (int i = 0; i < good.Photos.Count; i++)
 0199                    {
 0200                        good.Photos[i].FullSizeUrl = _imagesSettings.ImageUrl + fileName;
 0201                        good.Photos[i].PreviewUrl = _imagesSettings.ImageUrl + fileName;
 0202                    }
 203
 0204                }
 205                else
 0206                {
 0207                    for (int i = 0; i < good.Photos.Count; i++)
 0208                    {
 209                     /*   good.Photos[i].FullSizeUrl = _imagesSettings.ImageUrl + _imagesSettings.FullSizeUrlPlaceholder
 210                        good.Photos[i].PreviewUrl = _imagesSettings.ImageUrl + _imagesSettings.PreviewUrlPlaceholder;*/
 0211                    }
 0212                }
 213
 0214                await _service.CreateGood(good);
 215
 0216                IMapper toDtoMapper = ToGoodDtoMapper();
 0217                return CreatedAtAction(nameof(GetGood), new { id = good.Id }, toDtoMapper.Map<Good, GoodDTO>(good));
 218            }
 0219            catch (Exception e)
 0220            {
 0221                _logger.LogError($"{e.Message} \n {e.StackTrace}");
 0222                throw;
 223            }
 0224        }
 225        /// <summary>
 226        /// [Устарел, используйте PutGood] Разрешение товара для отображения в каталоге
 227        /// </summary>
 228        /// <param name="id"></param>
 229        /// <returns>No content</returns>
 230        /// <response code="404">If not found </response>
 231        /// <response code="400">If state good error or deleted</response>
 232        [HttpPut("ApprooveGoodForCatalog")]
 233        [Obsolete]
 234        public async Task<IActionResult> ApprooveGoodForCatalog(long id)
 0235        {
 236            try
 0237            {
 0238                Good good = await _service.GetGood(id);
 0239                if (good.RecState.Id != (long)RecordState.Error && !good.IsDeleted)
 0240                {
 0241                    await _service.ChangeGoodState(id, RecordState.Active);
 0242                    return NoContent();
 243                }
 0244                return BadRequest($"Good #{id} not be approoved for catalog");
 245            }
 0246            catch (KeyNotFoundException)
 0247            {
 0248                return NotFound();
 249            }
 0250            catch (Exception e)
 0251            {
 0252                return ServerError(e);
 253            }
 0254        }
 255        /// <summary>
 256        /// [Устарел, используйте PutGood] Отключить отображение товара в каталоге
 257        /// </summary>
 258        /// <param name="id"></param>
 259        /// <returns>No content</returns>
 260        /// <response code="404">If not found </response>
 261        /// <response code="400">If state good error or deleted</response>
 262        [HttpPut("SwitchOffGood")]
 263        [Obsolete]
 264        public async Task<IActionResult> SwitchOffGood(long id)
 0265        {
 266            try
 0267            {
 0268                Good good = await _service.GetGood(id);
 0269                if (good.RecState.Id != (long)RecordState.Error && !good.IsDeleted)
 0270                {
 0271                    await _service.ChangeGoodState(id, RecordState.Inactive);
 0272                    return NoContent();
 273                }
 0274                return BadRequest($"Good #{id} not be deactivated");
 275            }
 0276            catch (KeyNotFoundException)
 0277            {
 0278                return NotFound();
 279            }
 0280            catch (Exception e)
 0281            {
 0282                return ServerError(e);
 283            }
 0284        }
 285        /// <summary>
 286        /// Загружает товары из файла
 287        /// </summary>
 288        /// <param name="file"></param>
 289        /// <remarks>author: oboligatov</remarks>
 290        [HttpPost("UploadFromFile")]
 291        [Obsolete]
 292        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 293        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 294        public async Task<IActionResult> UploadGoodFromFile(IFormFile file)
 0295        {
 296            try
 0297            {
 0298                var stream = file.OpenReadStream();
 0299                System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
 0300                var readerConfig = new ExcelReaderConfiguration()
 0301                {
 0302                    AutodetectSeparators = new char[] { ',', ';', '\t', '|', '#' },
 0303                    AnalyzeInitialCsvRows = 0
 0304                };
 0305                var reader = file.ContentType switch
 0306                {
 0307                    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" => ExcelReaderFactory.CreateRead
 0308                    "text/csv" => ExcelReaderFactory.CreateCsvReader(stream, readerConfig),
 0309                    _ => throw new NotSupportedException($"File type {file.Name} not supported"),
 0310                };
 311                try
 0312                {
 0313                    List<Good> goods = new List<Good>();
 0314                    var conf = new ExcelDataSetConfiguration
 0315                    {
 316                        ConfigureDataTable = _ => new ExcelDataTableConfiguration
 317                        {
 318                            UseHeaderRow = true
 319                        }
 0320                    };
 0321                    var dataset = reader.AsDataSet(conf);
 0322                    var dataTable = dataset.Tables[0];
 0323                    for (var row = 0; row < dataTable.Rows.Count; row++)
 0324                    {
 0325                        Good good = new Good();
 0326                        for (var column = 0; column < dataTable.Columns.Count; column++)
 0327                        {
 328                            try
 0329                            {
 0330                                switch (column)
 331                                {
 332                                    case 0:
 0333                                        {
 0334                                            good.DefaultBarCode = new BarCode { Code = dataTable.Rows[row][column].ToStr
 0335                                            break;
 336                                        }
 337                                    case 1:
 0338                                        {
 0339                                            good.Name = dataTable.Rows[row][column].ToString();
 0340                                            break;
 341                                        }
 342                                    case 2:
 0343                                        {
 344                                           // good.VendorCode = dataTable.Rows[row][column].ToString();
 0345                                            break;
 346                                        }
 347                                    case 3:
 0348                                        {
 0349                                            string name = dataTable.Rows[row][column].ToString();
 0350                                            Contragent manufacturer = await _contragentService.GetContragentByName(name)
 0351                                            if (manufacturer == null)
 0352                                            {
 353                                                // good.State = RecordState.Error;
 0354                                            }
 0355                                            good.Manufacturer = manufacturer;
 0356                                            break;
 357                                        }
 358                                    case 4:
 0359                                        {
 0360                                            good.ExpirationDays = Convert.ToInt32(dataTable.Rows[row][column].ToString()
 0361                                            break;
 362                                        }
 363                                    case 5:
 0364                                        {
 0365                                            good.Weight = Convert.ToDecimal(dataTable.Rows[row][column].ToString());
 0366                                            break;
 367                                        }
 368                                    case 6:
 0369                                        {
 0370                                            good.Width = Convert.ToInt32(dataTable.Rows[row][column].ToString());
 0371                                            break;
 372                                        }
 373                                    case 7:
 0374                                        {
 0375                                            good.Height = Convert.ToInt32(dataTable.Rows[row][column].ToString());
 0376                                            break;
 377                                        }
 378                                    case 8:
 0379                                        {
 0380                                            good.Thickness = Convert.ToInt32(dataTable.Rows[row][column].ToString());
 0381                                            break;
 382                                        }
 383                                    case 9:
 0384                                        {
 0385                                            Guid guid = Guid.Parse(dataTable.Rows[row][column].ToString());
 0386                                            Category category = await _categoryService.GetCategoryByGuid(guid);
 0387                                            if (category == null)
 0388                                            {
 0389                                                category = (await _categoryService.GetCategories(1, 1, null)).First();
 390                                                // good.State = RecordState.Error;
 0391                                            }
 0392                                            good.Category = category;
 0393                                            break;
 394                                        }
 395                                    case 10:
 0396                                        {
 397                                            //   good.Vat = (VatKind)Enum.Parse(typeof(VatKind), dataTable.Rows[row][col
 0398                                            break;
 399                                        }
 400                                    case 11:
 0401                                        {
 0402                                            good.CustomDeclarationNumber = dataTable.Rows[row][column].ToString();
 0403                                            break;
 404                                        }
 405                                    case 12:
 0406                                        {
 407                                            //    good.UnitKind = (UnitKind)Enum.Parse(typeof(UnitKind), dataTable.Rows[
 0408                                            break;
 409                                        }
 410                                    case 13:
 0411                                        {
 0412                                            int code = Convert.ToInt32(dataTable.Rows[row][column].ToString());
 0413                                            good.Country = await _countryService.GetCountryByCode(code);
 0414                                            break;
 415                                        }
 416                                    case 14:
 0417                                        {
 0418                                            good.ConformityCertNumber = dataTable.Rows[row][column].ToString();
 0419                                            break;
 420                                        }
 421                                    case 15:
 0422                                        {
 0423                                            good.GroupPackNesting = Convert.ToInt32(dataTable.Rows[row][column].ToString
 0424                                            break;
 425                                        }
 426                                    case 16:
 0427                                        {
 0428                                            good.GroupPackWidth = Convert.ToInt32(dataTable.Rows[row][column].ToString()
 0429                                            break;
 430                                        }
 431                                    case 17:
 0432                                        {
 0433                                            good.GroupPackHeight = Convert.ToInt32(dataTable.Rows[row][column].ToString(
 0434                                            break;
 435                                        }
 436                                    case 18:
 0437                                        {
 0438                                            good.GroupPackThickness = Convert.ToInt32(dataTable.Rows[row][column].ToStri
 0439                                            break;
 440                                        }
 441                                    case 19:
 0442                                        {
 0443                                            good.PalletNesting = Convert.ToInt32(dataTable.Rows[row][column].ToString())
 0444                                            break;
 445                                        }
 446                                    case 20:
 0447                                        {
 0448                                            string name = dataTable.Rows[row][column].ToString();
 0449                                            Brand brand = await _brandService.GetBrandByName(name);
 0450                                            if (brand == null)
 0451                                            {
 452                                                // good.State = RecordState.Error;
 0453                                            }
 0454                                            good.Brand = brand;
 455
 0456                                            break;
 457                                        }
 458                                    case 21:
 0459                                        {
 0460                                            string name = dataTable.Rows[row][column].ToString();
 0461                                            good.SubBrand = await _brandService.GetBrandByName(name);
 0462                                            break;
 463                                        }
 464                                }
 0465                            }
 0466                            catch (Exception)
 0467                            {
 468                                // good.State = RecordState.Error;
 0469                                goods.Add(good);
 0470                                continue;
 471                            }
 0472                        }
 473
 474                        /* if (good.State != RecordState.Error)
 475                         {
 476                             good.State = RecordState.Inactive;
 477                         }*/
 0478                        goods.Add(good);
 0479                    }
 0480                    if (goods.Count > 0)
 0481                    {
 0482                        await _service.CreateGoodRange(goods);
 0483                    }
 484
 0485                    return Ok();
 486                }
 0487                catch (Exception e)
 0488                {
 0489                    throw e;
 490                }
 491                finally
 0492                {
 0493                    reader.Dispose();
 0494                }
 495
 496            }
 0497            catch (Exception e)
 0498            {
 0499                return ServerError(e);
 500            }
 0501        }
 502        private async Task<Good> PrepareGood(GoodDTO goodDto)
 0503        {
 0504            IMapper mapper = FromDtoMapper();
 0505            Good good = mapper.Map<GoodDTO, Good>(goodDto);
 0506            good.Category = await _categoryService.GetCategory(goodDto.CategoryId);
 0507            good.Brand = goodDto.BrandId == 0 ? null : await _brandService.GetBrand(goodDto.BrandId);
 0508            good.SubBrand = goodDto.SubBrandId == 0 ? null : await _brandService.GetBrand(goodDto.SubBrandId);
 509            //good.UnitKind = (UnitKind)Enum.Parse(typeof(UnitKind), goodDto.UnitKindId.ToString());
 0510            good.GUID = good.GUID == Guid.Empty ? Guid.NewGuid() : good.GUID;
 0511            return good;
 0512        }
 513        private static IMapper ToShortGoodDtoMapper()
 0514        {
 0515            var config = new MapperConfiguration(cfg =>
 0516            {
 0517                cfg.CreateMap<Good, GoodShortDTO>()
 0518                    .ForMember(d => d.Barcode, e => e.MapFrom(s => s.DefaultBarCode.Code));
 0519            });
 0520            return config.CreateMapper();
 0521        }
 522
 523        private static IMapper FromDtoMapper()
 0524        {
 0525            var config = new MapperConfiguration(cfg =>
 0526            {
 0527                cfg.CreateMap<GoodDTO, Good>()
 0528                    .ForMember(d => d.Manufacturer, e => e.Ignore())
 0529                    .ForMember(d => d.Supplier, e => e.Ignore())
 0530                    .ForMember(d => d.Category, e => e.Ignore())
 0531                    .ForMember(d => d.Brand, e => e.Ignore())
 0532                    .ForMember(d => d.SubBrand, e => e.Ignore())
 0533                    .ForMember(d => d.UnitsKind, e => e.Ignore());
 0534                cfg.CreateMap<PhotoDTO, Photo>();
 0535                cfg.CreateMap<BarCodeDTO, BarCode>();
 0536            });
 0537            IMapper mapper = config.CreateMapper();
 0538            return mapper;
 0539        }
 540    }
 541}

/opt/dev/sveta_api_build/SVETA.Api/Data/DTO/FileInputModelDTO.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Http;
 2
 3
 4
 5namespace SVETA.Api.Controllers
 6{
 7    public partial class GoodsController
 8    {
 9        public class FileInputModelDTO
 10        {
 011            public string Good { get; set; }
 012            public IFormFile File { get; set; }
 13        }
 14    }
 15}