< Summary

Class:SVETA.Api.Services.Implements.DepartmentWorker
Assembly:SVETA.Api
File(s):/opt/dev/sveta_api_build/SVETA.Api/Services/Implements/DepartmentWorker.cs
Covered lines:62
Uncovered lines:73
Coverable lines:135
Total lines:497
Line coverage:45.9% (62 of 135)
Covered branches:17
Total branches:84
Branch coverage:20.2% (17 of 84)

Metrics

MethodLine coverage Branch coverage
.ctor(...)100%100%
CreateNotifications()100%100%
GetCategoryRatios()0%0%
CreateCategoryRatio()0%0%
GetFilterListByMovementDepartment()0%0%

File(s)

/opt/dev/sveta_api_build/SVETA.Api/Services/Implements/DepartmentWorker.cs

#LineLine coverage
 1using DocumentFormat.OpenXml.Office2013.PowerPoint.Roaming;
 2using Microsoft.AspNetCore.Mvc;
 3using Microsoft.AspNetCore.Server.IIS.Core;
 4using Microsoft.EntityFrameworkCore.Internal;
 5using Microsoft.Extensions.Logging;
 6using SVETA.Api.Data.DTO;
 7using SVETA.Api.Data.DTO.Cluster;
 8using SVETA.Api.Data.DTO.DepartmentDTO;
 9using SVETA.Api.Helpers;
 10using SVETA.Api.Helpers.Authorize;
 11using SVETA.Api.Services.Interfaces;
 12using System;
 13using System.Collections.Generic;
 14using System.Linq;
 15using System.Runtime.InteropServices.WindowsRuntime;
 16using System.Text;
 17using System.Threading.Tasks;
 18using WinSolutions.Sveta.Common;
 19using WinSolutions.Sveta.Common.Extensions;
 20using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 21using WinSolutions.Sveta.Server.Data.DataModel.Kinds;
 22using WinSolutions.Sveta.Server.Services.Interfaces;
 23
 24
 25
 26namespace SVETA.Api.Services.Implements
 27{
 28    public class DepartmentWorker : IDepartmentWorker
 29    {
 30        private readonly IDepartmentService _depService;
 31        private readonly INotificationWorker _notifyWorker;
 32        private readonly ILogger<DepartmentWorker> _logger;
 33        private readonly IAuthenticationService _authenticationService;
 34        private readonly IClusterService _clusterService;
 35        private readonly IUserService _userService;
 36        private readonly ISupplyContractService _contractService;
 37        private readonly INotificationService _notifyService;
 38        private readonly IEmailService _emailService;
 39        private readonly IDirectoriesService _dirService;
 40        private readonly IContragentService _contrService;
 41        private readonly IWorkScheduleService _scheduleService;
 42        private readonly ICategoryService _catService;
 43        private readonly ICategoryRatioService _catRatiosService;
 44        private readonly ITelegramNotificationService _telegramService;
 45        private readonly IMovementRouteService _movementRouteService;
 46        private readonly IAddressService _addressService;
 47
 18548        public DepartmentWorker(ILogger<DepartmentWorker> logger, IClusterService clusterService, ISupplyContractService
 18549            IAuthenticationService authenticationService, IUserService userService, IDirectoriesService dirService, ICon
 18550            INotificationService notifyService, IEmailService emailService, IDepartmentService depService, INotification
 18551            IMovementRouteService movementRouteService, IAddressService addressService, ICategoryService catService, ICa
 18552        {
 18553            _depService = depService;
 18554            _addressService = addressService;
 18555            _notifyWorker = notifyWorker;
 18556            _userService = userService;
 18557            _scheduleService = scheduleService;
 18558            _contrService = contrService;
 18559            _emailService = emailService;
 18560            _dirService = dirService;
 18561            _notifyService = notifyService;
 18562            _clusterService = clusterService;
 18563            _contractService = contractService;
 18564            _authenticationService = authenticationService;
 18565            _telegramService = telegramService;
 18566            _logger = logger;
 18567            _catService = catService;
 18568            _catRatiosService = catRatiosService;
 18569            _movementRouteService = movementRouteService;
 18570        }
 71
 72        /// <summary>
 73        /// Создает подразделение и выполняет первичное наполнение связанных данных (кластера, контракты, расписание, ре
 74        /// </summary>
 75        /// <param name="data">подразделение</param>
 76        /// <param name="warehouseId">id склада, с которым заключать контракт и к которому включать в кластер. Актуально
 77        /// <returns></returns>
 78        public async Task CreateDepartment(Department data, long warehouseId = 0)
 79        {
 56680            if ((await _depService.GetDeparments(data.Contragent.Id, 0, int.MaxValue, null, null)).Result.Any(x => x.Nam
 81                throw new SvetaException($"Подразделение с названием {data.Name} и контрагентом {data.Contragent.ShortNa
 82            await _depService.CreateDepartment(data);
 83            await CreateNotifications(data);
 84            await CreateDataForNewWarehouse(data);
 85            await CreateDataForNewShop(data, warehouseId);
 86            await CreateSchedule(data);
 87            await CreateMovementStatusRoutes(data);
 88        }
 89
 90        /// <summary>
 91        /// Возвращает все подразделения партнеров-контрагентов
 92        /// </summary>
 93        /// <param name="filter">фильтр по названию и адресу</param>
 94        /// <param name="contragentId">по умолчанию 0. Если 0, то выводит все ТТ платформы (если админ). Если > 0, то вы
 95        /// <param name="warehouseId">по умолчанию 0. Если 0, то выводит все ТТ, иначе только те, которые не привязаны к
 96        /// <returns>список объектов DepartmentShortWithAddressDTO</returns>
 97        public async Task<List<DepartmentShortWithAddressDTO>> GetPartnersDepartments(string filter, long contragentId, 
 98        {
 99            contragentId = _authenticationService.IsUserPlatform() ? contragentId : _authenticationService.ContragentId;
 100            var result = await Task.FromResult(_depService.GetDeparments(0, 0, int.MaxValue, filter, default).Result.Res
 101            if (contragentId == 0)
 102            {//если 0, выводим все ТТ платформы. Если warehouseId>0, то выводим ТТ, которые не привязаны к кластерам пер
 0103                result = result.Where(x => (warehouseId == 0 || x.Cluster?.WarehouseId != warehouseId) && x.Kind.Id == (
 0104                return result.Select(x => new DepartmentShortWithAddressDTO(x)).ToList();
 105            }
 106            var contracts = await _contractService.GetSupplyContractsByContragent(contragentId, true, null); //находим в
 107            List<long> contragents = new List<long>() { };
 108            foreach (var item in contracts) //выбираем его партнеров
 109            {
 110                if (contragentId != item.Seller.Id)
 111                    contragents.Add(item.Seller.Id);
 112                if (contragentId != item.Buyer.Id)
 113                    contragents.Add(item.Buyer.Id);
 114            }
 115            contragents = contragents.Distinct().ToList(); // оставляем униклальные
 116            //выбираем ТТ, у которых КА из этого массива. Если warehouseId>0, то выводим ТТ, которые не привязаны к клас
 0117            result = result.Where(x => contragents.Any(p => p == x.Contragent.Id) && (warehouseId == 0 || x.Cluster?.War
 0118            return result.Select(x => new DepartmentShortWithAddressDTO(x)).ToList();
 119        }
 120
 121        /// <summary>
 122        /// привязывает пользователей к подразделению
 123        /// </summary>
 124        /// <param name="id">id подразделения</param>
 125        /// <param name="usersId">юзеры</param>
 126        /// <returns></returns>
 127        public async Task BindUserToDepartment(long id, List<long> usersId)
 128        {
 129            if (usersId.Count > 0)
 130            {
 131                var department = _authenticationService.IsUserPlatform() ? await _depService.GetDepartment(id) : await _
 132                if (department == null)
 133                    throw new KeyNotFoundException($"Подразделение с id={id} не найдено");
 134                foreach (var listx in usersId)
 135                {
 136                    var bindUser = await _userService.GetUser(listx);
 137                    //привязывать можем только людей нашего КА или любых, но только если мы повелитель
 138                    if (bindUser != null && (bindUser.Contragent.Id == _authenticationService.ContragentId || _authentic
 139                    {
 0140                        if (!department.UsersDepartments.Any(x => x.UserId == listx))
 141                            department.UsersDepartments.Add(new UserDepartment { UserId = listx });
 142                    }
 143                    else throw new KeyNotFoundException($"Пользователь с id={listx} не найден");
 144                }
 145                await _depService.UpdateDepartment(department);
 146            }
 147            else throw new KeyNotFoundException($"Не указаны пользователи");
 148        }
 149
 150        /// <summary>
 151        /// привязывает пользователей к подразделению
 152        /// </summary>
 153        /// <param name="id">id подразделения</param>
 154        /// <param name="usersId">юзеры</param>
 155        /// <returns></returns>
 156        public async Task UnbindUserFromDepartment(long id, List<long> usersId)
 157        {
 158            if (usersId.Count > 0)
 159            {
 160                var department = _authenticationService.IsUserPlatform() ? await _depService.GetDepartment(id) : await _
 161                if (department == null)
 162                    throw new KeyNotFoundException($"Подразделение с id={id} не найдено");
 163                foreach (var listx in usersId)
 164                {
 165                    var bindUser = await _userService.GetUser(listx);
 166                    if (bindUser.Id == department.Contragent.Owner.Id)
 167                        throw new ArgumentException("Нельзя отвязывать владельца подразделения");
 168                    //отвязывать можем только людей нашего КА или любых, но только если мы повелитель
 169                    if (bindUser != null && (bindUser.Contragent.Id == _authenticationService.ContragentId || _authentic
 170                    {
 0171                        if (department.UsersDepartments.Any(x => x.UserId == listx))
 0172                            department.UsersDepartments.Remove(department.UsersDepartments.Where(x => x.UserId == listx)
 173                    }
 174                    else throw new KeyNotFoundException($"Пользователь с id={listx} не найден");
 175                }
 176                await _depService.UpdateDepartment(department);
 177            }
 178            else throw new KeyNotFoundException($"Не указаны пользователи");
 179        }
 180
 181        /// <summary>
 182        /// Создает нотификации о созданном подразделении
 183        /// </summary>
 184        /// <param name="data">подразделение</param>
 185        /// <returns></returns>
 186        private async Task CreateNotifications(Department data)
 560187        {
 560188            var sb = new StringBuilder();
 560189            sb.Append($"Создано подразделение {data.Name}.<br>");
 560190            sb.Append($"Тип - {data.Kind.Name}.<br>");
 560191            sb.Append($"Телефон - {data.PhoneNumber}.<br>");
 560192            sb.Append($"Контрагент - {data.Contragent.ShortName}.<br>");
 560193            sb.Append($"Площадь - {data.Area}.<br>");
 560194            sb.Append($"КПП - {data.Kpp}.<br>");
 560195            sb.Append($"Email - {data.Email}.<br>");
 560196            sb.Append($"Адрес - {data.ActualAddress.FullAddress}.<br>");
 560197            await _emailService.Create("Создано новое подразделение", sb.ToString(), new List<string>() { data.Email, _a
 198
 560199            if ((await _telegramService.CanSendToTelegram("#department")))
 560200            {
 560201                string textTelegram =
 560202                   $"#department " +
 560203                   $"\nСоздано подразделение {data.Name} у контрагента {data.Contragent.ShortName}. " +
 560204                   $"\nФактический адрес: {data.ActualAddress.FullAddress} " +
 560205                   $"\ne-mail: {data.Email} " +
 560206                   $"\nНомер телефона: {data.PhoneNumber}";
 560207                await Telegram.SendNotification(textTelegram);
 560208            }
 560209        }
 210
 211        /// <summary>
 212        /// Создает/проверяет для нового магазин контракт и включает в кластер
 213        /// </summary>
 214        /// <param name="department">Магазин</param>
 215        /// <param name="warehouseId">id Склада поставщика</param>
 216        private async Task CreateDataForNewShop(Department department, long warehouseId)
 217        {
 218            if (department.Kind.Id != (long)DepartmentKind.Shop)
 219                return;
 220            var warehouse = await _depService.GetDepartment(warehouseId) ?? throw new KeyNotFoundException($"Не найден у
 221            var user = await _userService.GetUser(_authenticationService.UserId);
 222            //получаем свежий активный контракт между КА магазина и КА переданного склада
 380223            var contract = (await _contractService.GetSupplyContracts(department.Contragent.Id, true)).OrderBy(x => x.Id
 224            //если контракта нет, то создаем его
 225            if (contract == null)
 226            {
 227                contract = new SupplyContract()
 228                {
 229                    Buyer = department.Contragent,
 230                    Seller = warehouse.Contragent,
 231                    BeginDate = DateTime.Now.Date,
 232                    EndDate = new DateTime(DateTime.Now.Year, 12, 31, 20, 59, 59, 999),
 233                    SignOffDate = DateTime.Now.Date,
 234                    DocumentNumber = "0",
 235                    PrepaimentPercent = 100,
 236                    TradeRatio = 100,
 237                    RecState = await _dirService.GetRecordState((long)RecordState.Active)
 238                };
 239                await _contractService.Create(contract);
 240                await _notifyService.CreateNotificationForUser("Заключение контракта", $"Заключен контракт №{contract.Do
 241            }
 242            //ищем кластера склада
 1870243            var cluster = (await _clusterService.GetClustersByWarehouse(warehouse.Id)).OrderBy(e => e.Id).FirstOrDefault
 244            if (cluster == null)
 245                throw new KeyNotFoundException($"У склада {warehouse.Name} не найдено кластеров");
 246            cluster.Departments.Add(department);
 247            await _notifyService.CreateNotificationForUser("Включение магазина в кластер", $"Магазин {department.Name} п
 248            await _clusterService.UpdateCluster(cluster);
 249        }
 250
 251        /// <summary>
 252        /// Метод для создания контракта и кластера между новым складом в БД и анонимным КА. Также создает анонимный маг
 253        /// </summary>
 254        /// <param name="department">подразделение</param>
 255        private async Task CreateDataForNewWarehouse(Department department)
 256        {
 257            if (department.Kind.Id != (long)DepartmentKind.Warehouse)
 258                return;
 259            var activeRec = await _dirService.GetRecordState((int)RecordState.Active);
 260            var anonymContragent = await _contrService.GetContragent(-1);
 261            var existContract = await _contractService.GetSupplyContract(anonymContragent.Id, department.Contragent.Id, 
 262            if (existContract == null)
 263            {
 264                var contract = new SupplyContract()
 265                {
 266                    RecState = activeRec,
 267                    Buyer = anonymContragent, //аноним
 268                    Seller = department.Contragent,
 269                    BeginDate = DateTime.UtcNow.Date,
 270                    EndDate = new DateTime(2029, 12, 31, 20, 59, 59),
 271                    SignOffDate = DateTime.Now.AddDays(-1),
 272                    DocumentNumber = "0",
 273                    PrepaimentPercent = 100,
 274                    TradeRatio = 100
 275                };
 276                await _contractService.Create(contract);
 277            }
 278            anonymContragent.Departments ??= new List<Department>();
 372279            var newShop = anonymContragent.Departments.FirstOrDefault(d => d.Cluster == null);
 280            if (newShop == null)
 281            {
 282                newShop = new Department
 283                {
 284                    Name = $"Витрина \"{department.Name}\"",
 285                    PhoneNumber = "8000000000",
 3286                    Kind = (await _depService.GetKindType(0)).FirstOrDefault(d => d.Id == (long) DepartmentKind.Shop),
 3287                    Status = (await _depService.GetStatusType()).FirstOrDefault(d => d.Code.ToUpper().Equals("ACTIVE")),
 288                    Contragent = anonymContragent,
 289                    RecState = activeRec,
 290                    ActualAddress = anonymContragent.PhysicAddress,
 291                    Kpp = anonymContragent.Kpp,
 292                    UsersDepartments = new List<UserDepartment>{new UserDepartment{UserId = anonymContragent.Owner.Id}}
 293                };
 294                await _depService.CreateDepartment(newShop);
 295                anonymContragent.Departments.Add(newShop);
 296                await _contrService.UpdateContragent(anonymContragent);
 297            }
 298
 299            var cluster = new Cluster()
 300            {
 301                RecState = activeRec,
 302                Departments = new List<Department>() { newShop }, //аноним
 303                Name = $"Демонстрационный кластер для склада {department.Name}",
 304                TradeRatio = 100,
 305                MinOrderSum = 100,
 306                Warehouse = department,
 307                ClusterDeliveryTypes = new List<ClusterDeliveryType> { new ClusterDeliveryType { DeliveryTypeId = (await
 308            };
 309            await _clusterService.CreateCluster(cluster);
 310        }
 311
 312        /// <summary>
 313        /// Создает регламент по заявкам для нового склада
 314        /// </summary>
 315        /// <param name="department">подразделение</param>
 316        /// <returns></returns>
 317        private async Task CreateMovementStatusRoutes(Department department)
 318        {
 319            if (department.Kind.Id != (long)DepartmentKind.Warehouse)
 320            {
 321                return;
 322            }
 8227323            var modelRoutes = (await _movementRouteService.GetRoutes()).Where(x => x.WarehouseId == -2); //эталонное рас
 324            var newRoutes = new List<MovementStatusRoute>();
 8184325            newRoutes.AddRange(modelRoutes.Select(p => new MovementStatusRoute
 8184326            {
 8184327                StatusCurrentId = p.StatusCurrentId,
 8184328                StatusNextId = p.StatusNextId,
 8184329                RouteKey = p.RouteKey,
 8184330                Hour = p.Hour,
 8184331                Warehouse = department
 8184332            }));
 333            await _movementRouteService.CreateRoutes(newRoutes);
 334        }
 335
 336        /// <summary>
 337        /// Создает расписание работы для нового склада
 338        /// </summary>
 339        /// <param name="department">подразделение</param>
 340        /// <returns></returns>
 341        private async Task CreateSchedule(Department department)
 342        {
 343            if (department.Kind.Id != (long)DepartmentKind.Warehouse)
 344                return;
 42721345            var modelSchedules = (await _scheduleService.GetSchedules()).Where(x=>x.WarehouseId == -2 && x.BeginTime.Dat
 346            var newSchedules = new List<WorkSchedule>();
 23808347            newSchedules.AddRange(modelSchedules.Select(p => new WorkSchedule() { Warehouse = department, BeginTime = p.
 348            await _scheduleService.Create(newSchedules);
 349        }
 350
 351        /// <summary>
 352        /// Получает типы доставки для подразделения
 353        /// </summary>
 354        /// <param name="departmentId">id подразделения</param>
 355        /// <param name="clusterId">id кластера. Если в departmentId передан склад, то в этом параметре можно указать, и
 356        /// <returns>список объектов для ClusterDeliveryTypesResponseDTO</returns>
 357        public async Task<List<ClusterDeliveryTypesResponseDTO>> GetDepartmentDeliveryTypes(long departmentId, long clus
 358        {
 359            var result = new List<ClusterDeliveryTypesResponseDTO>();
 360            var department = _authenticationService.IsUserPlatform() ? await _depService.GetDepartment(departmentId) : a
 361            if (department == null)
 362                throw new KeyNotFoundException($"Подразделение с id={departmentId} не найдено");
 363            if (department.Kind.Id == (long)DepartmentKind.Shop)
 364                result.Add(new ClusterDeliveryTypesResponseDTO()
 365                {
 366                    Cluster = new IdNameDTO(department.Cluster.Id, department.Cluster.Name),
 0367                    DeliveryTypes = new List<DeliveryTypeResponseDto>(department.Cluster.ClusterDeliveryTypes.Select(x =
 368                });
 369            if (department.Kind.Id == (long)DepartmentKind.Warehouse)
 370            {
 0371                var clusters = (await _clusterService.GetClustersByWarehouse(departmentId)).Where(x => clusterId == 0 ||
 0372                result.AddRange(clusters.Select(x => new ClusterDeliveryTypesResponseDTO()
 0373                {
 0374                    Cluster = new IdNameDTO(x.Id, x.Name),
 0375                    DeliveryTypes = new List<DeliveryTypeResponseDto>(x.ClusterDeliveryTypes.Select(z => new DeliveryTyp
 0376                }));
 377            }
 378            return result;
 379        }
 380
 381        /// <summary>
 382        /// Получить торговые коэффициенты для одного подразделения по всем категориям товаров. Для тех категорий, у кот
 383        /// </summary>
 384        /// <remarks>author IPod</remarks>
 385        /// <param name="id">Id подразделения</param>
 386        /// <param name="parentId">Идентифиатор родительской категории: null - все категории, 0 - корневые категории, >1
 387        /// <param name="filter">Фильтр для поиска по названию категории</param>
 388        /// <param name="page">Любое значение ниже нуля изменится на 1, номер страницы</param>
 389        /// <param name="limit">Любое значение ниже нуля изменится на 10, лимит выдачи</param>
 390        /// <returns>список объектов DepartmentCategoryRatioResponseDTO</returns>
 391        public async Task<List<DepartmentCategoryRatioResponseDTO>> GetCategoryRatios(long id, long? parentId, string fi
 0392        {
 0393            page = page < 1 ? 1 : page;
 0394            limit = limit < 1 ? 10 : limit;
 395
 0396            var categoryList = await _catService.GetCategories(page, limit, filter, parentId);
 397
 0398            var result = new List<DepartmentCategoryRatioResponseDTO>();
 399
 0400            foreach (var category in categoryList)
 0401            {
 0402                var existingDCR = await _catRatiosService.GetDepartmentCategoryRatio(id, category.Id);
 403
 0404                var newDCR = new DepartmentCategoryRatioResponseDTO
 0405                {
 0406                    Id = existingDCR == null ? 0 : existingDCR.Id,
 0407                    CategoryId = category.Id,
 0408                    ParentId = category.Parent?.Id,
 0409                    Name = category.Name,
 0410                    Code = category.Code,
 0411                    DepartmentId = id,
 0412                    TradeRatio = existingDCR == null ? 0 : existingDCR.TradeRatio,
 0413                    Expandable = (await _catService.GetCategoriesCount(null, category.Id)) > 0
 0414                };
 415
 0416                result.Add(newDCR);
 0417            }
 0418            return result;
 0419        }
 420
 421        /// <summary>
 422        /// Создать торговый коэффициент для одного подразделения по одной категории товара.
 423        /// </summary>
 424        /// <param name="id">id подразделения</param>
 425        /// <param name="categoryId">id категории</param>
 426        /// <param name="tradeRatio">коэффициент категории</param>
 427        /// <returns>объект DepartmentCategoryRatioResponseDTO</returns>
 428        public async Task<DepartmentCategoryRatioResponseDTO> CreateCategoryRatio(long id, long categoryId, decimal trad
 0429        {
 0430            var department = await _depService.GetDepartment(id) ?? throw new KeyNotFoundException($"Подразделение с id=
 0431            if (department.Contragent.Id != _authenticationService.ContragentId && !_authenticationService.IsUserPlatfor
 0432                throw new ForbidException();
 433
 0434            var category = await _catService.GetCategory(categoryId) ?? throw new KeyNotFoundException($"Категория с id=
 0435            var dсr = await _catRatiosService.GetDepartmentCategoryRatio(department.Id, category.Id);
 0436            if (dсr.Id != 0)
 0437                throw new ArgumentException($"Запись с категорией {category.Name} (id={category.Id}) и подразделением {d
 0438            var newSetting = new DepartmentCategoryRatio
 0439            {
 0440                Department = department,
 0441                Category = category,
 0442                TradeRatio = tradeRatio
 0443            };
 0444            newSetting = await _catRatiosService.Create(newSetting);
 0445            var result = new DepartmentCategoryRatioResponseDTO
 0446            {
 0447                Id = newSetting.Id,
 0448                CategoryId = newSetting.Category.Id,
 0449                ParentId = newSetting.Category.Parent?.Id,
 0450                Name = category.Name,
 0451                Code = category.Code,
 0452                DepartmentId = newSetting.Department.Id,
 0453                TradeRatio = newSetting.TradeRatio,
 0454                Expandable = (await _catService.GetCategories(1, 10, null, newSetting.Id)).Count() > 0
 0455            };
 0456            return result;
 0457        }
 458
 459        /// <summary>
 460        /// Получает список складов, которые доступны для текущего КА покупателя. Ключ сравнения: первые 2 цифры ИНН пок
 461        /// </summary>
 462        /// <returns>список складов</returns>
 463        public async Task<List<Department>> GetAvailableWarehouse()
 464        {
 465            //Если поставщик то возвращает пустоту
 466            if (_authenticationService.IsUserWholesaler())
 467                return new List<Department>();
 468            var allWarehouses = await _depService.GetDepartmentsByKind(DepartmentKind.Warehouse, null, null, true);
 469            //если мы админ, то возвращаем весь список складов. Пусть юзер сам определяет
 470            if (_authenticationService.IsUserPlatform())
 471                return allWarehouses;
 472            //получаем контракты с КА текущего пользователя
 0473            var contract = (await _contractService.GetSupplyContracts(_authenticationService.ContragentId, true)).OrderB
 474            //если контракт есть, то возвращаем склады продавца из контракта
 475            if (contract != null)
 0476                return allWarehouses.Where(x => x.Contragent.Id == contract.Seller.Id).ToList();
 477            //находим склады, у КА которых инн начинается с таких же 2 цифр, что и у КА текущего юзера магазина
 478            var currentContragent = await _contrService.GetContragent(_authenticationService.ContragentId);
 0479            var departments = allWarehouses.Where(x=>x.Contragent.Inn.StartsWith(currentContragent.Inn.Substring(0,2))).
 480            //если нашли, возвращаем их, иначе все склады
 481            return departments.Count > 0 ? departments : allWarehouses;
 482        }
 483
 484        /// <summary>
 485        /// Выводит список уникальных складов-отправителей или магазинов-получателей, которые встречаются в заявках/отгр
 486        /// </summary>
 487        /// <param name="kind">тип департамента, по которому надо найти уникальные подразделения</param>
 488        /// <param name="movementKind">тип документов, в которых искать</param>
 489        /// <returns></returns>
 490        public async Task<List<Department>> GetFilterListByMovementDepartment(DepartmentKind kind, MovementKind movement
 0491        {
 0492            var contragentId = _authenticationService.IsUserPlatform() ? 0 : _authenticationService.ContragentId;
 0493            var result = kind == DepartmentKind.Warehouse ? await _depService.GetFilteredListByMovementSender(contragent
 0494            return result;
 0495        }
 496    }
 497}