< Summary

Class:WinSolutions.Sveta.Server.Services.Implements.ContragentService
Assembly:WinSolutions.Sveta.Server
File(s):/opt/dev/sveta_api_build/WinSolutions.Sveta.Server/Services/Implements/ContragentService.cs
Covered lines:77
Uncovered lines:69
Coverable lines:146
Total lines:310
Line coverage:52.7% (77 of 146)
Covered branches:34
Total branches:86
Branch coverage:39.5% (34 of 86)

Metrics

MethodLine coverage Branch coverage
.ctor(...)100%100%
GetContragent()100%100%
PrepareContragents(...)100%100%
GetContragents()87.5%50%
GetFilteredListByMovementSupplier()0%100%
GetFilteredListByMovementCustomer()0%100%
GetContragentUsers()0%100%
GetShortContragents()0%0%
CreateContragent()100%100%
UpdateContragent()100%100%
GetContragentByWareouse()0%100%
DeleteContragent()85.71%50%
ContragentExists()0%100%
GetContragentByName()100%100%
GetContragentsByKind()90.9%50%
GetContragents()100%100%
Sort(...)100%42.59%
GetContragentWithContracts()0%100%

File(s)

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

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Linq;
 3using System.Threading.Tasks;
 4using Microsoft.EntityFrameworkCore;
 5using Microsoft.Extensions.Logging;
 6using WinSolutions.Sveta.Server.Data.DataModel.Contexts;
 7using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 8using WinSolutions.Sveta.Server.Data.DataModel.Kinds;
 9using WinSolutions.Sveta.Server.Services.Interfaces;
 10using WinSolutions.Sveta.Common;
 11using System;
 12using WinSolutions.Sveta.Common.Extensions;
 13
 14namespace WinSolutions.Sveta.Server.Services.Implements
 15{
 16
 17    public class ContragentService : SvetaServiceBase, IContragentService
 18    {
 19        private readonly SvetaDbContext _db;
 20        private readonly ILogger<ContragentService> _logger;
 21        private readonly IAuthenticationService _authenticationService;
 22        private readonly ICommonContragentService _commonContragentService;
 23        private readonly ISupplyContractService _contractService;
 24        public ContragentService(SvetaDbContext db, ILogger<ContragentService> logger, ICommonContragentService commonCo
 18625            : base(authenticationService)
 18626        {
 18627            _commonContragentService = commonContragentService;
 18628            _contractService = contractService;
 18629            _authenticationService = authenticationService;
 18630            _db = db;
 18631            _logger = logger;
 18632        }
 33
 34        /// <summary>
 35        /// получает КА по id
 36        /// </summary>
 37        /// <param name="contragentId">id KA</param>
 38        /// <returns>контрагент</returns>
 70339        public async Task<Contragent> GetContragent(long contragentId) => await _db.Contragents
 70340                .Include(x => x.JuridicAddress)
 70341                .Include(x => x.PhysicAddress)
 70342                .Include(d => d.ContragentsKind)
 70343                .Include(d => d.RecState)
 70344                .Include(d => d.Owner)
 70345                .Include(x => x.BankAccounts)
 70346                .Include(d => d.Departments)
 70347                .ThenInclude(department => department.Cluster)
 70348                .FirstOrDefaultAsync(e => e.Id == contragentId && !e.IsDeleted);
 49
 50        /// <summary>
 51        /// предварительная выборка КА
 52        /// </summary>
 53        /// <param name="filter"></param>
 54        /// <returns></returns>
 855        private IQueryable<Contragent> PrepareContragents(string filter = null) => _db.Contragents
 856                .Include(x => x.JuridicAddress)
 857                .Include(x => x.PhysicAddress)
 858                .Include(d => d.ContragentsKind)
 859                .Include(d => d.RecState)
 860                .Include(d => d.Owner)
 861               // .Include(d => d.TaxSystem)
 862                .Include(x => x.BankAccounts)
 863                .Where(x => string.IsNullOrWhiteSpace(filter) || x.ShortName.ToUpper().Contains(filter.ToUpper()) || x.F
 864                .OrderBy(x => x.ShortName)
 865                .Where(e => !e.IsDeleted && e.Id > 0);
 66
 67        /// <summary>
 68        /// Получает список КА с пагинацией
 69        /// </summary>
 70        /// <param name="page">номер страницы</param>
 71        /// <param name="limit">размер страницы</param>
 72        /// <param name="filter">фильтр по короткому/полному наименованию</param>
 73        /// <param name="sort">сортировка</param>
 74        /// <returns></returns>
 75        public async Task<List<Contragent>> GetContragents(int page, int? limit, string filter = null, string sort = "")
 176        {
 177            var items = PrepareContragents(filter).AsNoTracking();
 178            if (!_authenticationService.IsUserPlatform())
 079                items= items.Where(x => x.Id == _authenticationService.ContragentId);
 180            items = Sort(items, sort?.ToLower());
 181            items = limit != null ? items.Skip(page * (int)limit).Take((int)limit) : items;
 82
 183            return await items.ToListAsync();
 184        }
 85
 86        /// <summary>
 87        /// Выводит список уникальных КА поставщиков, которые встречаются в заявках/отгрузках для переданного КА. КА мож
 88        /// </summary>
 89        /// <param name="contragentId">id контрагента, для которого выбираем уникальные записи  КА поставщиков в докумен
 90        /// <param name="movementKind">тип документов, в которых искать</param>
 91        /// <returns></returns>
 092        public async Task<List<Contragent>> GetFilteredListByMovementSupplier(long contragentId, MovementKind movementKi
 093            .Include(x => x.MovementsAsCustomer).ThenInclude(MovementsAsCustomer => MovementsAsCustomer.Customer)
 094            .Include(x => x.MovementsAsSupplier).ThenInclude(MovementsAsSupplier => MovementsAsSupplier.Supplier)
 095            .Include(x => x.MovementsAsSupplier).ThenInclude(MovementsAsSupplier => MovementsAsSupplier.MovementStatus)
 096            .Include(x => x.MovementsAsSupplier).ThenInclude(MovementsAsSupplier => MovementsAsSupplier.MovementType)
 097            .Where(x => !x.IsDeleted)
 098            // В зависимости от того, какой тип у переданного КА, ищем либо в покупателях, либо в продавцах. Ведь КА не 
 099            .Where(x => x.MovementsAsSupplier.Any(p => !p.IsDeleted && p.MovementType.Id == (int)movementKind && ((contr
 0100            .Distinct()
 0101            .ToListAsync();
 102
 103        /// <summary>
 104        /// Выводит список уникальных КА покупателей, которые встречаются в заявках/отгрузках для переданного КА. КА мож
 105        /// </summary>
 106        /// <param name="contragentId">id контрагента, для которого выбираем уникальные записи КА покупателей в документ
 107        /// <param name="movementKind">тип документов, в которых искать</param>
 108        /// <returns></returns>
 0109        public async Task<List<Contragent>> GetFilteredListByMovementCustomer(long contragentId, MovementKind movementKi
 0110            .Include(x => x.MovementsAsCustomer).ThenInclude(MovementsAsCustomer => MovementsAsCustomer.MovementStatus)
 0111            .Include(x => x.MovementsAsCustomer).ThenInclude(MovementsAsCustomer => MovementsAsCustomer.MovementType)
 0112            .Include(x => x.MovementsAsCustomer).ThenInclude(MovementsAsCustomer => MovementsAsCustomer.Customer)
 0113            .Include(x => x.MovementsAsSupplier).ThenInclude(MovementsAsSupplier => MovementsAsSupplier.Supplier)
 0114            .Where(x => !x.IsDeleted)
 0115            // В зависимости от того, какой тип у переданного КА, ищем либо в покупателях, либо в продавцах. Ведь КА не 
 0116            .Where(x => x.MovementsAsCustomer.Any(p => !p.IsDeleted && p.MovementType.Id == (int)movementKind && ((contr
 0117            .Distinct()
 0118            .ToListAsync();
 119
 120        /// <summary>
 121        /// Возвращает пользователей КА с переданным типом
 122        /// </summary>
 123        /// <param name="kind">тип КА</param>
 124        /// <returns></returns>
 125        public async Task<List<User>> GetContragentUsers(ContragentKind kind) =>
 0126            await PrepareContragents().Where(d => d.ContragentsKind.Id == (long) kind)
 0127                .SelectMany(d => d.User)
 0128                .ToListAsync();
 129
 130        /// <summary>
 131        /// Возвращает список контрагентов-партнеров с сокращенным набором полей с пагинацией и фильтрами
 132        /// </summary>
 133        /// <param name="page">номер страницы </param>
 134        /// <param name="limit">размер страницы </param>
 135        /// <param name="filter">фильтр по значимым полям FullName / ShortName</param>
 136        /// <param name="sort">сортировка по умолчанию по id - id|desc, created_on,created_on|desc, state,state|desc, st
 137        /// <param name="supplyOwner">true, если владелец поставщика. По умолчанию false</param>
 138        public async Task<List<Contragent>> GetShortContragents(int page, int? limit, string filter = null, string sort 
 0139        {
 0140            var items = PrepareContragents(filter).AsNoTracking();
 0141            if (supplyOwner) //если директор поставщика
 0142                items = items.Where(x => x.ContragentsKind.Id == (long)ContragentKind.Retailer || x.ContragentsKind.Id =
 0143                    .Where(x=>x.Id != _authenticationService.ContragentId);
 144            else
 0145            { //иначе выбираем всех КА на основе контрактов с нашим КА
 0146                var contracts = await _contractService.GetSupplyContractsByContragent(_authenticationService.ContragentI
 0147                List<long> contragents = new List<long>() { };
 0148                foreach (var item in contracts) //выбираем партнеров
 0149                {
 0150                        contragents.Add(item.Seller.Id);
 0151                        contragents.Add(item.Buyer.Id);
 0152                }
 0153                contragents = contragents.Distinct().Where(x=> x != _authenticationService.ContragentId).ToList(); // ос
 154                //выбираем КА, у которых КА из этого массива
 0155                items = items.Where(x => contragents.Any(p => p == x.Id));
 0156            }
 0157            items = Sort(items, sort?.ToLower());
 0158            items = limit != null ? items.Skip(page * (int)limit).Take((int)limit) : items;
 159
 0160            return await items.ToListAsync();
 0161        }
 162
 163        /// <summary>
 164        /// создает КА
 165        /// </summary>
 166        /// <param name="contragentIn">КА</param>
 167        /// <returns></returns>
 168        public async Task CreateContragent(Contragent contragentIn)
 571169        {
 571170            await _commonContragentService.Create(contragentIn, CurrentUserId);
 571171        }
 172
 173        /// <summary>
 174        /// Обновляет КА
 175        /// </summary>
 176        /// <param name="contragentIn">КА</param>
 177        /// <returns></returns>
 178        public async Task UpdateContragent(Contragent contragentIn)
 370179        {
 370180            await _commonContragentService.Update(contragentIn, CurrentUserId);
 370181        }
 182
 183        /// <summary>
 184        /// получает КА на основе ТТ
 185        /// </summary>
 186        /// <param name="departmentId">ТТ</param>
 187        /// <returns></returns>
 0188        public async Task<Contragent> GetContragentByWareouse(long departmentId) => await PrepareContragents()
 0189            .Where(x => x.Departments.Any(p => p.Id == departmentId)).FirstOrDefaultAsync();
 190
 191        /// <summary>
 192        /// удаляет КА по id
 193        /// </summary>
 194        /// <param name="contragentId">id КА</param>
 195        /// <returns></returns>
 196        public async Task DeleteContragent(long contragentId)
 1197        {
 1198            Contragent rec = await _db.Contragents.FindAsync(contragentId);
 1199            if (rec == null)
 0200                throw new KeyNotFoundException($"Контрагент с id={contragentId} не найден");
 1201            rec.IsDeleted = true;
 1202            await _db.SaveChangesAsync(CurrentUserId);
 1203        }
 204
 205        /// <summary>
 206        /// проверяет существование КА
 207        /// </summary>
 208        /// <param name="contragentId">id КА</param>
 209        /// <returns></returns>
 0210        public async Task<bool> ContragentExists(long contragentId) => await _db.Contragents
 0211            .AsNoTracking()
 0212            .Where(e => e.Id == contragentId)
 0213            .Where(e => !e.IsDeleted)
 0214            .AnyAsync();
 215
 216        /// <summary>
 217        /// получает КА по короткому/полному названию
 218        /// </summary>
 219        /// <param name="name">название</param>
 220        /// <returns></returns>
 3221        public async Task<Contragent> GetContragentByName(string name) => await PrepareContragents()
 3222            .AsNoTracking()
 3223            .FirstOrDefaultAsync(d => d.FullName.Contains(name.NormalizeName()) || d.ShortName.Contains(name.NormalizeNa
 224
 225        /// <summary>
 226        /// получает список КА на основе типа с пагинацией и фильтрацией
 227        /// </summary>
 228        /// <param name="page">номер страницы</param>
 229        /// <param name="limit">размер страницы</param>
 230        /// <param name="kind">тип КА</param>
 231        /// <param name="filter">фильтр по короткому/полному названию</param>
 232        /// <param name="sort">сортировка</param>
 233        /// <returns></returns>
 234        public async Task<List<Contragent>> GetContragentsByKind(int page, int limit, ContragentKind kind, string filter
 3235        {
 3236            var items = PrepareContragents(filter)
 3237                .Where(d => d.ContragentsKind.Id == (int)kind);
 3238            if ((_authenticationService.IsUserWholesaler() && kind == ContragentKind.Wholesaler) || (_authenticationServ
 0239                items = items.Where(x => x.Id == _authenticationService.ContragentId);
 240
 3241            items = Sort(items, sort?.ToLower());
 242
 3243            return await items
 3244                .Skip(page * limit)
 3245                .Take(limit)
 3246                .ToListAsync();
 3247        }
 248
 249        /// <summary>
 250        /// получатет список КА на основе типа
 251        /// </summary>
 252        /// <param name="kind">тип КА</param>
 253        /// <returns></returns>
 1254        public async Task<List<Contragent>> GetContragents(ContragentKind kind) => await PrepareContragents().Where(d =>
 255
 256        /// <summary>
 257        /// Сортирует Contragent по полям
 258        /// </summary>
 259        /// <param name="items"></param>
 260        /// <param name="sort">сортировка по умолчанию
 261        /// по id - id|desc,
 262        /// created_on,created_on|desc,
 263        /// state,state|desc,
 264        /// status,status|desc,
 265        /// fullName,fullName|desc
 266        /// shortName,shortName|desc
 267        /// Owner,Owner|desc</param>
 268        /// <returns></returns>
 4269        private IQueryable<Contragent> Sort(IQueryable<Contragent> items, string sort = default) => (sort ?? "").ToLower
 4270        {
 4271            "created_on" => items.OrderBy(d => d.CreationDateTime),
 4272            "created_on|desc" => items.OrderByDescending(d => d.CreationDateTime),
 4273            "state" => items.OrderBy(d => d.RecState.Id),
 4274            "state|desc" => items.OrderByDescending(d => d.RecState.Id),
 4275            "fullName" => items.OrderBy(d => d.FullName),
 4276            "fullName|desc" => items.OrderByDescending(d => d.FullName),
 4277            "shortName" => items.OrderBy(d => d.ShortName),
 4278            "shortName|desc" => items.OrderByDescending(d => d.ShortName),
 4279            "Owner" => items.OrderBy(d => d.Owner),
 4280            "Owner|desc" => items.OrderByDescending(d => d.Owner),
 4281            "id|desc" => items.OrderByDescending(d => d.Id),
 4282            _ => items.OrderBy(d => d.Id),
 4283        };
 284
 285        /// <summary>
 286        /// получает контрагента с джоиниными контрактами
 287        /// </summary>
 288        /// <param name="contragentId">id КА</param>
 289        /// <returns></returns>
 290        public async Task<Contragent> GetContragentWithContracts(long contragentId)
 0291        {
 0292            return await _db.Contragents
 0293                .AsNoTracking()
 0294                .Include(x => x.BankAccounts)
 0295                .Include(d => d.JuridicAddress)
 0296                .Include(d => d.ContragentsKind)
 0297                .Include(d => d.RecState)
 0298                .Include(d => d.PhysicAddress)
 0299                .Include(d => d.Owner)
 0300               // .Include(d => d.TaxSystem)
 0301                .Include(d => d.User)
 0302                .Include(x => x.ContractsAsSeller).ThenInclude(x => x.Buyer)
 0303                .Include(x => x.ContractsAsBuyer).ThenInclude(x => x.Seller)
 0304                .Where(e => !e.IsDeleted && e.Id == contragentId)
 0305                .FirstOrDefaultAsync();
 0306        }
 307
 308
 309    }
 310}