< Summary

Class:SVETA.Api.Services.Implements.ImportingExporting.ImportService
Assembly:SVETA.Api
File(s):/opt/dev/sveta_api_build/SVETA.Api/Services/Implements/ImportingExporting/ImportService.cs
Covered lines:0
Uncovered lines:126
Coverable lines:126
Total lines:210
Line coverage:0% (0 of 126)
Covered branches:0
Total branches:14
Branch coverage:0% (0 of 14)

Metrics

MethodLine coverage Branch coverage
.ctor(...)0%100%
GetGoodSettingsTemplate()0%100%
GetGoodsTemplate()0%100%
GetPricesTemplate()0%100%
GetRestsTemplate()0%100%
GetWorkSchedulesTemplate()0%100%
ImportGoodSettings()0%100%
ImportPhotos(...)0%100%
ImportPrices(...)0%100%
ImportRests()0%100%
ImportWorkSchedules(...)0%100%
ImportFromExcel()0%0%

File(s)

/opt/dev/sveta_api_build/SVETA.Api/Services/Implements/ImportingExporting/ImportService.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Http;
 2using SVETA.Api.Services.Interfaces;
 3using SVETA.Api.Services.Interfaces.ImportingExporting;
 4using System;
 5using System.Collections.Generic;
 6using System.Data;
 7using System.IO;
 8using System.Linq;
 9using System.Reflection;
 10using System.Threading.Tasks;
 11using WinSolutions.Sveta.Common.Extensions;
 12using SVETA.Api.Services.Implements.ImportingExporting.Importers;
 13using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 14using WinSolutions.Sveta.Server.Data.DataModel.Contexts;
 15using WinSolutions.Sveta.Server.Services.Implements;
 16using WinSolutions.Sveta.Common;
 17using SVETA.Api.Data.Domain;
 18using Microsoft.Extensions.Options;
 19
 20namespace SVETA.Api.Services.Implements.ImportingExporting
 21{
 22    public class ImportService : SvetaServiceBase, IImportService
 23    {
 24        private readonly IRecordImporter<GoodSettingRecord> _goodSettingImporter;
 25        private readonly IRecordImporter<RestRecord> _restImporter;
 26        private readonly IDiskStorageService _diskStorageService;
 27        private readonly SvetaDbContext _db;
 28        CommonSettings _commonSettings;
 29
 30        public ImportService(IAuthenticationService authenticationService, IRecordImporter<GoodSettingRecord> goodSettin
 31            IRecordImporter<RestRecord> restImporter,
 032            IDiskStorageService diskStorageService, SvetaDbContext db, IOptions<CommonSettings> commonSettings) : base(a
 033        {
 034            _restImporter = restImporter;
 035            _goodSettingImporter = goodSettingImporter;
 036            _diskStorageService = diskStorageService;
 037            _db = db;
 038            _commonSettings = commonSettings.Value;
 039        }
 40
 41        public async Task<MemoryStream> GetGoodSettingsTemplate()
 042        {
 043            var records = new List<GoodSettingRecord>
 044            {
 045                new GoodSettingRecord()
 046                {
 047                    UniqueCode = "DD00007762",
 048                    VendorCode = "1234578",
 049                    BarCode = "4005900487582",
 050                    GoodName = "3в1 Черная Пенка для умывания для жирной кожи, склонной к несовершенствам",
 051                    MinQuantity = "1",
 052                    PickingQuantum = "1",
 053                    ShowcaseVisible = "0"
 054                }
 055            };
 056            var template = TemplateHelper.GetTemplate(records);
 057            return CsvUtil.ToExcelStream(template);
 058        }
 59
 60        public Task<MemoryStream> GetGoodsTemplate()
 061        {
 062            throw new NotImplementedException();
 63        }
 64
 65        public Task<MemoryStream> GetPricesTemplate()
 066        {
 067            throw new NotImplementedException();
 68        }
 69
 70        public async Task<MemoryStream> GetRestsTemplate()
 071        {
 072            var records = new List<RestRecord>
 073            {
 074                new RestRecord()
 075                {
 076                    UniqueCode = "DD00007762",
 077                    VendorCode = "1234578",
 078                    BarCode = "4005900487582",
 079                    GoodName = "3в1 Черная Пенка для умывания для жирной кожи, склонной к несовершенствам",
 080                    Quantity = "1"
 081                }
 082            };
 083            var template = TemplateHelper.GetTemplate(records);
 084            return CsvUtil.ToExcelStream(template);
 085        }
 86
 87        public Task<MemoryStream> GetWorkSchedulesTemplate()
 088        {
 089            throw new NotImplementedException();
 90        }
 91
 92        public async Task<IImportResult> ImportGoodSettings(long departmentId, IFormFile file)
 093        {
 094            return await ImportFromExcel(file, _goodSettingImporter, new Dictionary<string, object> { { nameof(departmen
 095        }
 96
 97        public Task<IImportResult> ImportPhotos(IFormFile file)
 098        {
 99            //Importer.FromZip<GoodSettingRecord>(file);
 0100            throw new NotImplementedException();
 101        }
 102
 103        public Task<IImportResult> ImportPrices(long priceTrendId, IFormFile file)
 0104        {
 0105            throw new NotImplementedException();
 106        }
 107
 108        public async Task<IImportResult> ImportRests(long departmentId, IFormFile file)
 0109        {
 0110            return await ImportFromExcel(file, _restImporter, new Dictionary<string, object> { { nameof(departmentId), d
 0111        }
 112
 113        public Task<IImportResult> ImportWorkSchedules(long departmentId, IFormFile file)
 0114        {
 0115            throw new NotImplementedException();
 116        }
 117
 118        async Task<IImportResult> ImportFromExcel<TRecord>(IFormFile file, IRecordImporter<TRecord> importer, Dictionary
 0119        {
 0120            importer.Context = context ?? new Dictionary<string, object>();
 121
 0122            var upload = new Upload();
 123            DataTable dataTable;
 124            string fileName;
 0125            using (var stream = _diskStorageService.SaveUpload(file, out fileName))
 0126            {
 0127                dataTable = FileReader.ReadFromExcel(stream, file.ContentType);
 0128            }
 0129            upload.SourceFileName = fileName;
 0130            upload.CreatedByUserId = CurrentUserId;
 0131            upload.CreationDateTime = DateTime.UtcNow;
 0132            _db.Add(upload);
 0133            _db.SaveChanges();
 134
 135            // проверяем структуру таблицы на наличие всех полей
 0136            var props = TemplateHelper.GetMappedProperties<TRecord>();
 0137            foreach(var prop in props)
 0138            {
 0139                if(!dataTable.Columns.Contains(prop.Name))
 0140                {
 0141                    throw new Exception($"Поле {prop.Name} не найдено");
 142                }
 0143            }
 144
 145            // событие перед валидацией
 0146            importer.BeforeValidation();
 147
 148            // достаем все записи в DTO объект, валидируем каждый объект
 0149            List<TRecord> records = new List<TRecord>();
 0150            Dictionary<TRecord, Exception> invalidRecords = new Dictionary<TRecord, Exception>();
 0151            foreach (DataRow row in dataTable.Rows)
 0152            {
 0153                var record = new TRecord();
 154                try
 0155                {
 0156                    foreach (var prop in props)
 0157                    {
 0158                        prop.SetValue(record, row[prop.Name].ToString().NormalizeName());
 0159                    }
 0160                    importer.Validate(record);
 0161                    records.Add(record);
 0162                }
 0163                catch (Exception ex)
 0164                {
 0165                    invalidRecords.Add(record, ex);
 0166                }
 0167            }
 168
 169            // событие после валидации
 0170            importer.AfterValidation();
 171
 172            // импортируем валидные записи
 0173            records.ForEach(x =>
 0174            {
 0175                try
 0176                {
 0177                    importer.Import(x);
 0178                }
 0179                catch (Exception ex)
 0180                {
 0181                    invalidRecords.Add(x, ex);
 0182                }
 0183            });
 0184            await _db.SaveChangesAsync(CurrentUserId);
 185
 186            // событие после импорта
 0187            importer.AfterImport();
 0188            await _db.SaveChangesAsync(CurrentUserId);
 189
 190            // формирование объекта с результатами
 191            // и сохранение отчета об ошибках если были
 0192            var result = new ImportResult
 0193            {
 0194                uploadId = upload.Id,
 0195                succeed = invalidRecords.Count == 0,
 0196                errorCount = invalidRecords.Count
 0197            };
 0198            if (!result.succeed)
 0199            {
 0200                var rows = TemplateHelper.GetTemplateWithError(invalidRecords);
 201
 202                // сохраняем на диск эксель с отчетом
 0203                var stream = CsvUtil.ToExcelStream(rows);
 0204                _diskStorageService.SaveDownload($"upload-report{result.uploadId}.xlsx", stream, false);
 0205                result.reportUrl = $"{_commonSettings.BaseUrl.TrimEnd('/')}/api/v1/Upload/GetReport?id={result.uploadId}
 0206            }
 0207            return result;
 0208        }
 209    }
 210}