< Summary

Class:WinSolutions.Sveta.Server.Services.Implements.RestService
Assembly:WinSolutions.Sveta.Server
File(s):/opt/dev/sveta_api_build/WinSolutions.Sveta.Server/Services/Implements/RestService.cs
Covered lines:29
Uncovered lines:96
Coverable lines:125
Total lines:248
Line coverage:23.2% (29 of 125)
Covered branches:2
Total branches:44
Branch coverage:4.5% (2 of 44)

Metrics

MethodLine coverage Branch coverage
.ctor(...)100%100%
Create()75%50%
Create()0%0%
UpdateRests()100%100%
PrepareRests()0%100%
Delete()0%0%
GetRest()0%100%
GetRests()0%100%
GetRests()100%100%
GetRest()0%100%
GetRests()0%0%
RestExists()0%100%
Update()0%100%
Sort(...)0%0%

File(s)

/opt/dev/sveta_api_build/WinSolutions.Sveta.Server/Services/Implements/RestService.cs

#LineLine coverage
 1using Clave.Expressionify;
 2using Microsoft.EntityFrameworkCore;
 3using Microsoft.Extensions.Logging;
 4using System.Collections.Generic;
 5using System.Linq;
 6using WinSolutions.Sveta.Server.Data.DataModel.Extensions;
 7using System.Threading.Tasks;
 8using WinSolutions.Sveta.Common;
 9using WinSolutions.Sveta.Server.Data.DataModel.Contexts;
 10using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 11using WinSolutions.Sveta.Server.Domain;
 12using WinSolutions.Sveta.Server.Services.Interfaces;
 13
 14namespace WinSolutions.Sveta.Server.Services.Implements
 15{
 16    public class RestService : SvetaServiceBase, IRestService
 17    {
 18        private readonly SvetaDbContext _db;
 19        private readonly IAuthenticationService _authenticationService;
 20        private readonly ILogger<RestService> _logger;
 21
 22        public RestService(SvetaDbContext db, ILogger<RestService> logger, IAuthenticationService authenticationService)
 18423            : base(authenticationService)
 18424        {
 18425            _authenticationService = authenticationService;
 18426            _db = db;
 18427            _logger = logger;
 18428        }
 29
 30        /// <summary>
 31        /// создает запись
 32        /// </summary>
 33        /// <param name="data">объект Rest</param>
 34        /// <returns></returns>
 35        public async Task<Rest> Create(Rest data)
 36836        {
 36837            var existing = await _db.Rests.FirstOrDefaultAsync(x => x.Good.Id == data.Good.Id && x.Department.Id == data
 36838            if (existing != null)
 039            {
 040                existing.Quantity = data.Quantity;
 041                existing.IsDeleted = false;
 042            }
 43            else
 36844            {
 36845                _db.Entry(data.Good).State = EntityState.Unchanged;
 36846                _db.Entry(data.Department).State = EntityState.Unchanged;
 36847                await _db.Rests.AddAsync(data);
 36848                existing = data;
 36849            }
 36850            await _db.SaveChangesAsync(CurrentUserId);
 51
 36852            return existing;
 36853        }
 54
 55        /// <summary>
 56        /// создает список записей
 57        /// </summary>
 58        /// <param name="rests">список объектов Rest</param>
 59        /// <returns></returns>
 60        public async Task Create(IEnumerable<Rest> rests)
 061        {
 062            foreach (var data in rests)
 063            {
 064                var existing = await _db.Rests.FirstOrDefaultAsync(x => x.Good.Id == data.GoodId && x.Department.Id == d
 065                if (existing != null)
 066                {
 067                    existing.Quantity = data.Quantity;
 068                    existing.IsDeleted = false;
 069                }
 70                else
 071                {
 072                    if (data.Good != null)
 073                    {
 074                        _db.Entry(data.Good).State = EntityState.Unchanged;
 075                    }
 76
 077                    if (data.Department != null)
 078                    {
 079                        _db.Entry(data.Department).State = EntityState.Unchanged;
 080                    }
 081                    await _db.Rests.AddAsync(data);
 082                }
 083            }
 084            await _db.SaveChangesAsync(CurrentUserId);
 085        }
 86
 87        /// <summary>
 88        /// обновляет список записей
 89        /// </summary>
 90        /// <param name="rests">список объектов Rest</param>
 91        /// <returns></returns>
 92        public async Task UpdateRests(List<Rest> rests)
 3993        {
 3994            _db.Rests.UpdateRange(rests);
 3995            await _db.SaveChangesAsync(CurrentUserId);
 3996        }
 97
 98        /// <summary>
 99        /// предварительная выборка
 100        /// </summary>
 101        /// <returns></returns>
 0102        private IQueryable<Rest> PrepareRests() => _db.Rests
 0103            .Include(d => d.Good)
 0104            .ThenInclude(Good => Good.Category)
 0105            .Include(d => d.Good)
 0106            .ThenInclude(Good => Good.Photos)
 0107            .Include(d => d.Good)
 0108            .ThenInclude(Good => Good.DepartmentGoodSettings)
 0109            .Include(d => d.Good)
 0110            .ThenInclude(Good => Good.GoodBarcodes).ThenInclude(d => d.BarCode)
 0111            .Include(e => e.Good).ThenInclude(x => x.DefaultBarCode)
 0112             .Include(d => d.Department).ThenInclude(Department => Department.Contragent)
 0113             .Include(d => d.RecState)
 0114             .Where(x => !x.IsDeleted && !x.Good.IsDeleted && !x.Good.Category.IsDeleted && !x.Department.IsDeleted && !
 0115            .Expressionify()
 0116             .AsQueryable();
 117
 118        /// <summary>
 119        /// удаляет запись
 120        /// </summary>
 121        /// <param name="id">id записи</param>
 122        /// <returns></returns>
 123        public async Task Delete(long id)
 0124        {
 0125            var data = await _db.Rests
 0126                .Where(d => !d.IsDeleted)
 0127                .FirstAsync(r=>r.Id == id);
 0128            if (data == null)
 0129            {
 0130                throw new KeyNotFoundException($"Остаток с id={id} не найден");
 131            }
 0132            data.IsDeleted = true;
 0133            await _db.SaveChangesAsync(CurrentUserId);
 0134        }
 135
 136        /// <summary>
 137        /// получить запись
 138        /// </summary>
 139        /// <param name="id">id записи</param>
 140        /// <returns></returns>
 0141        public async Task<Rest> GetRest(long id) => await PrepareRests()
 0142            .FirstOrDefaultAsync(d => d.Id == id);
 143
 144        /// <summary>
 145        /// получить список записей
 146        /// </summary>
 147        /// <param name="departmentId">id склада</param>
 148        /// <returns></returns>
 0149        public async Task<List<Rest>> GetRests(long departmentId) => await PrepareRests().AsNoTracking()
 0150            .Where(x => x.Department.Id == departmentId)
 0151            .ToListAsync();
 152
 153        /// <summary>
 154        /// Получить список записей
 155        /// </summary>
 156        /// <param name="departmentId">id склада</param>
 157        /// <param name="goods">список id товаров</param>
 158        /// <param name="withDeleted">true если учитывать удаленные товары. По умолчанию false</param>
 159        /// <returns></returns>
 39160        public async Task<List<Rest>> GetRests(long departmentId, List<long> goods, bool withDeleted = false) => await _
 39161            .Include(d => d.Good).ThenInclude(Good => Good.Category)
 39162            .Include(d => d.Department).ThenInclude(Department => Department.Contragent)
 39163            .Include(d => d.RecState)
 39164            .Where(d => withDeleted || !d.IsDeleted)
 39165            .Where(d => d.DepartmentId == departmentId && goods.Contains(d.GoodId))
 39166            .ToListAsync();
 167
 168        /// <summary>
 169        /// получить запись
 170        /// </summary>
 171        /// <param name="departmentId">id склада</param>
 172        /// <param name="goodId">id товара</param>
 173        /// <returns></returns>
 0174        public async Task<Rest> GetRest(long departmentId, long goodId) => await _db.Rests
 0175            .Include(d => d.Department)
 0176            .Include(d => d.RecState)
 0177            .Include(d => d.Good)
 0178            .Where(d => !d.IsDeleted)
 0179            .FirstOrDefaultAsync(d => d.Department.Id == departmentId && d.Good.Id == goodId);
 180
 181        /// <summary>
 182        /// получить записи с пагинацией, фильтрацией и сортировкой
 183        /// </summary>
 184        /// <param name="page">номер страницы</param>
 185        /// <param name="limit">размер страницы</param>
 186        /// <param name="categoryId">id категории</param>
 187        /// <param name="departmentId">id склада</param>
 188        /// <param name="filter">фильтр по имени товара или вендоркоду</param>
 189        /// <param name="sort">сортировка</param>
 190        /// <param name="rest">остаток. -1 если выводить все остатки</param>
 191        /// <returns></returns>
 192        public async Task<PaginatedData<List<Rest>>> GetRests(int page, int limit, long categoryId, long departmentId, s
 0193        {
 0194            var rests = PrepareRests().AsNoTracking();
 195            // Тотал записей для смертных считаем после прмиенения ограничения роли
 0196            int total = await rests?.CountAsync(x => _authenticationService.IsUserPlatform() || x.Department.Id == depar
 0197            rests = rests.Where(x => departmentId == 0 || x.Department.Id == departmentId)
 0198                .Where(x => categoryId == 0 || x.Good.Category.Id == categoryId)
 0199                .Where(x => string.IsNullOrWhiteSpace(filter) || x.Good.Name.ToUpper().Contains(filter.ToUpper()) || x.G
 0200                .Where(x => rest == -1 || (rest == 0 ? x.Quantity == 0 : x.Quantity > 0));
 0201            rests = Sort(rests, sort?.ToLower());
 0202            int filtered = await rests?.CountAsync();
 0203            return new PaginatedData<List<Rest>>
 0204            {
 0205                Result = await rests.Skip(page * limit).Take(limit).ToListAsync(),
 0206                TotalCount = total,
 0207                TotalFilteredCount = filtered
 0208            };
 0209        }
 210
 211        /// <summary>
 212        /// проверяет существование записи
 213        /// </summary>
 214        /// <param name="id">id записи</param>
 215        /// <returns></returns>
 0216        public async Task<bool> RestExists(long id) => await _db.Rests
 0217            .Where(e => e.Id == id)
 0218            .Where(d => !d.IsDeleted)
 0219            .AnyAsync();
 220
 221        /// <summary>
 222        /// обновляет запись
 223        /// </summary>
 224        /// <param name="data">объект Rest</param>
 225        /// <returns></returns>
 226        public async Task Update(Rest data)
 0227        {
 0228            _db.Rests.Update(data);
 0229            await _db.SaveChangesAsync(CurrentUserId);
 0230        }
 231
 232        /// <summary>
 233        /// сортировка
 234        /// </summary>
 235        /// <param name="items">выборка объектов Rest</param>
 236        /// <param name="sort">тип сортировка </param>
 237        /// <returns></returns>
 0238        private IQueryable<Rest> Sort(IQueryable<Rest> items, string sort = default) => (sort ?? "").ToLower() switch
 0239        {
 0240            "quant" => items.OrderBy(d => d.Quantity),
 0241            "quant|desc" => items.OrderByDescending(d => d.Quantity),
 0242            "vencode" => items.OrderBy(d => d.Good.GetActualVendorCode(d.DepartmentId)),
 0243            "vencode|desc" => items.OrderByDescending(d => d.Good.GetActualVendorCode(d.DepartmentId)),
 0244            "name|desc" => items.OrderByDescending(d => d.Good.Name),
 0245            _ => items.OrderBy(d => d.Good.Name),
 0246        };
 247    }
 248}