< Summary

Class:SVETA.Api.Controllers.DepartmentsController
Assembly:SVETA.Api
File(s):/opt/dev/sveta_api_build/SVETA.Api/Controllers/DepartmentsController.cs
Covered lines:0
Uncovered lines:142
Coverable lines:142
Total lines:629
Line coverage:0% (0 of 142)
Covered branches:0
Total branches:82
Branch coverage:0% (0 of 82)

Metrics

MethodLine coverage Branch coverage
.ctor(...)0%100%
GetDepartmentsByContragent()0%0%
GetPartnersDepartments()0%100%
GetDepartmentsByContragentCount()0%0%
GetDepartment()0%0%
GetDepartmentDeliveryTypes()0%100%
GetAddress()0%0%
CreateDepartment()0%0%
UpdateDepartment()0%0%
BindUsersToDepartment()0%100%
UnbindUsersFromDepartment()0%100%
DeleteDepartment()0%0%
GetDepartmentCategoryRatios()0%100%
GetDepartmentCategoryRatio()0%0%
PostDepartmentCategoryRatio()0%100%
PutDepartmentCategoryRatio()0%0%
DeleteDepartmentCategoryRatio()0%100%

File(s)

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

#LineLine coverage
 1using Microsoft.AspNetCore.Authorization;
 2using SVETA.Api.Data.DTO;
 3using SVETA.Api.Data.DTO.Cluster;
 4using Microsoft.AspNetCore.Mvc;
 5using Microsoft.Extensions.Logging;
 6using Newtonsoft.Json;
 7using SVETA.Api.Data.DTO.DepartmentDTO;
 8using SVETA.Api.Helpers.Authorize;
 9using Swashbuckle.AspNetCore.Annotations;
 10using System;
 11using System.Collections.Generic;
 12using System.Linq;
 13using System.Threading.Tasks;
 14using WinSolutions.Sveta.Common;
 15using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 16using WinSolutions.Sveta.Server.Data.DataModel.Kinds;
 17using WinSolutions.Sveta.Server.Domain;
 18using WinSolutions.Sveta.Server.Services.Interfaces;
 19using SVETA.Api.Services.Interfaces;
 20using WinSolutions.Sveta.Common.Extensions;
 21using DocumentFormat.OpenXml.Office2010.Excel;
 22
 23namespace SVETA.Api.Controllers
 24{
 25
 26    [Authorize]
 27    [Route("api/v1/Departments")]
 28    [ApiController]
 29    public class DepartmentsController : SvetaController
 30    {
 31        const string _routeUrl = "api/v1/Departments";
 32        readonly IDepartmentService _departmentService;
 33        readonly IDepartmentWorker _departmentWorker;
 34        readonly IUserService _userService;
 35        readonly IContragentService _contrService;
 36        readonly IAddressService _addressService;
 37        readonly IDirectoriesService _dirService;
 38        readonly ICategoryService _categoryService;
 39        private readonly IAuthenticationService _authUserService;
 40        readonly ILogger<DepartmentsController> _logger;
 41        readonly IGoodSettingService _serviceGoodSetting;
 42        readonly ICategoryRatioService _serviceCategoryRatio;
 43        readonly IGoodService _goodService;
 44        readonly ISupplyContractService _contractService;
 45
 46        public DepartmentsController(
 47            IDepartmentService departmentService,
 48            IEventService eventService,
 49            IContragentService contrService,
 50            IAuthenticationService authUserService,
 51            IUserService userService,
 52            IDepartmentWorker departmentWorker,
 53            IAddressService addressService,
 54            ICategoryService categoryService,
 55            IGoodSettingService serviceGoodSetting,
 56            ICategoryRatioService serviceCategoryRatio,
 57            IGoodService goodService,
 58            ISupplyContractService contractService,
 59        IDirectoriesService dirService,
 060            ILogger<DepartmentsController> logger) : base(logger)
 061        {
 062            _addressService = addressService;
 063            _departmentWorker = departmentWorker;
 064            _dirService = dirService;
 065            _contrService = contrService;
 066            _authUserService = authUserService;
 067            _contractService = contractService;
 068            _userService = userService;
 069            _departmentService = departmentService;
 070            _serviceGoodSetting = serviceGoodSetting;
 071            _serviceCategoryRatio = serviceCategoryRatio;
 072            _categoryService = categoryService;
 073            _goodService = goodService;
 074            _logger = logger;
 075        }
 76
 77        #region api/v1/Departments
 78        /// <summary>
 79        /// Возвращает все подразделения  с фильтром по значимым полям  и сортировкой
 80        /// </summary>
 81        /// <remarks>author i.rebenok</remarks>
 82        /// <param name="page">Любое значение ниже нуля изменится на 1, пагинация: номер страницы</param>
 83        /// <param name="limit">Любое значение ниже нуля изменится на 10, если значение не указано, то будут возвращатьс
 84        /// <param name="filter">фильтр по значимым полям: имя магазина или номер телефона</param>
 85        /// <param name="sort">сортировка по одному из полей
 86        /// по id|desc, name,name|desc, kindName,kindName|desc postalAddress,postalAddress|desc  area,area|desc, Сортиро
 87        /// <param name="contragentId">id контрагента. Если 0, то все подраздаления выводить, если >0,то только по этому
 88        [HttpGet("")]
 89        [SwaggerResponse(200, "Успешно", typeof(BaseResponseDTO<DepartmentDTO_GET>))]
 90        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 91        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 92        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 93        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner + "," + Role.ShopMerchandi
 94        public async Task<IActionResult> GetDepartmentsByContragent(int page = 1, int? limit = 10, string filter = null,
 095        {
 096            filter = filter.NormalizeName();
 097            if (limit == null)
 098                page = 1;
 99            else
 0100            {
 0101                page = page < 1 ? 1 : page;
 0102                limit = limit < 1 ? 10 : limit;
 0103            }
 0104            contragentId = User.IsInRole(Role.SystemAdmin) ? contragentId : _authUserService.ContragentId;
 0105            var result = await _departmentService.GetDeparments(contragentId, page - 1, limit, filter, sort);
 0106            var param = $"sort={sort}&contragentId={contragentId}";
 0107            var response = new BaseResponseDTO<DepartmentDTO_GET>(_routeUrl, page, (int)limit, result.TotalFilteredCount
 0108            {
 0109                Data = result.Result.Select(x => new DepartmentDTO_GET(x)).ToList(),
 0110            };
 0111            return Ok(response);
 0112        }
 113
 114        /// <summary>
 115        /// Возвращает все подразделения , привязанные к текущему юзеру
 116        /// </summary>
 117        /// <remarks>author i.rebenok</remarks>
 118        [HttpGet("List")]
 119        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<IdNameDTO>))]
 120        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 121        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 122        [AllowAnonymous]
 123        public async Task<IActionResult> GetDepartmentsList()
 124        {
 0125            return Ok((await _departmentService.GetDeparmentsList()).Select(x => new IdNameDTO() { Id = x.Id, Name = x.N
 126        }
 127
 128        /// <summary>
 129        /// Возвращает все подразделения партнеров-контрагентов
 130        /// </summary>
 131        /// <remarks>author i.rebenok</remarks>
 132        /// <param name="filter">фильтр по названию и адресу</param>
 133        /// <param name="contragentId">по умолчанию 0. Если 0, то выводит все ТТ платформы (если админ). Если > 0, то вы
 134        /// <param name="warehouseId">по умолчанию 0. Если 0, то выводит все ТТ, иначе только те, которые не привязаны к
 135        [HttpGet("PartnersDepartments")]
 136        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<DepartmentShortWithAddressDTO>))]
 137        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 138        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 139        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner + "," + Role.ShopMerchandi
 140        public async Task<IActionResult> GetPartnersDepartments(string filter=null, long contragentId=0, long warehouseI
 0141        {
 0142            filter = filter.NormalizeName();
 0143            return Ok(await _departmentWorker.GetPartnersDepartments(filter, contragentId, warehouseId));
 0144        }
 145
 146        /// <summary>
 147        /// Возвращает количество всех подразделений  с фильтром по значимым полям
 148        /// </summary>
 149        /// <remarks>author i.rebenok</remarks>
 150        /// <param name="filter">фильтр по значимым полям: имя магазина или номер телефона</param>
 151        /// <param name="contragentId">id контрагента. Если 0, то все подраздаления выводить, если >0,то только по этому
 152        [HttpGet("Count")]
 153        [SwaggerResponse(200, "Успешно", typeof(CountDTO))]
 154        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 155        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 156        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner + "," + Role.ShopMerchandi
 157        public async Task<IActionResult> GetDepartmentsByContragentCount(string filter = null, long contragentId = 0)
 0158        {
 0159            filter = filter.NormalizeName();
 0160            contragentId = User.IsInRole(Role.SystemAdmin) ? contragentId : _authUserService.ContragentId;
 0161            int result = await Task.FromResult(_departmentService.GetDeparments(contragentId, 1, 1, filter, "id|desc").R
 0162            return Ok(new CountDTO(result));
 0163        }
 164
 165
 166        /// <summary>
 167        /// Получить подразделение по ID
 168        /// </summary>
 169        /// <remarks>author i.rebenok</remarks>
 170        /// <param name="id">id поразделения</param>
 171        [HttpGet("{id}")]
 172        [SwaggerResponse(200, "Успешно", typeof(DepartmentDTO_GET))]
 173        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 174        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 175        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 176        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner + "," + Role.ShopMerchandi
 177        public async Task<IActionResult> GetDepartment([SwaggerParameter(Required = true)] long id)
 0178        {
 0179            var result = User.IsInRole(Role.SystemAdmin) ? await _departmentService.GetDepartment(id) : await _departmen
 0180            if (result == null)
 0181                return NotFoundResult($"Подразделение с id={id} не найдено");
 0182            return Ok(new DepartmentDTO_GET(result));
 0183        }
 184
 185        /// <summary>
 186        /// Получить типы доставки для подразделения
 187        /// </summary>
 188        /// <remarks>author i.rebenok</remarks>
 189        /// <param name="id">id поразделения</param>
 190        /// <param name="clusterId">id кластера. Если в departmentId передан склад, то в этом параметре можно указать, и
 191        [HttpGet("{id}/DeliveryTypes")]
 192        [SwaggerResponse(200, "Успешно", typeof(List<ClusterDeliveryTypesResponseDTO>))]
 193        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 194        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 195        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 196        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner + "," + Role.ShopMerchandi
 197        public async Task<IActionResult> GetDepartmentDeliveryTypes([SwaggerParameter(Required = true)] long id, long cl
 0198        {
 0199            var result = await _departmentWorker.GetDepartmentDeliveryTypes(id, clusterId);
 0200            return Ok(result);
 0201        }
 202
 203        /// <summary>
 204        /// Получить доступные склады для нового магазина
 205        /// </summary>
 206        /// <remarks>author i.rebenok</remarks>
 207        [HttpGet("AvailableWarehouse")]
 208        [SwaggerResponse(200, "Успешно", typeof(List<IdNameDTO>))]
 209        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 210        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 211        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 212        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner + "," + Role.ShopMerchandi
 213        public async Task<IActionResult> GetAvailableWarehouse()
 214        {
 215            var result = await _departmentWorker.GetAvailableWarehouse();
 0216            return Ok(result.Select(x => new IdNameDTO(x.Id, x.Name)));
 217        }
 218
 219        /// <summary>
 220        /// Возвращает список подразделений, отфильтрованных по типу Склад
 221        /// </summary>
 222        /// <remarks>author i.rebenok</remarks>
 223        /// <param name="filter">фильтр по значимым полям Name</param>
 224        /// <param name="sort">по id|desc, name,name|desc, kindName,kindName|desc postalAddress,postalAddress|desc  area
 225        /// <returns>Список розничных контрагентов </returns>
 226        [HttpGet("Warehouse")]
 227        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<DepartmentShortDTO>))]
 228        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 229        [Authorize(Roles = Role.SystemAdmin + "," + Role.SystemOperator + "," + Role.SupplierOwner + "," + Role.Supplier
 230        public async Task<IActionResult> GetWarehouseDepartments(string filter = null, string sort = default)
 231        {
 232            filter = filter.NormalizeName();
 233            var departments = await _departmentService.GetDepartmentsByKind(DepartmentKind.Warehouse, filter, sort);
 0234            return Ok(departments.Select(x => new DepartmentShortDTO(x)));
 235        }
 236
 237        /// <summary>
 238        /// Возвращает список подразделений, отфильтрованных по типу Магазин
 239        /// </summary>
 240        /// <remarks>author i.rebenok</remarks>
 241        /// <param name="filter">фильтр по значимым полям Name</param>
 242        /// <param name="sort">по id|desc, name,name|desc, kindName,kindName|desc postalAddress,postalAddress|desc  area
 243        /// <returns>Список розничных контрагентов </returns>
 244        [HttpGet("Shop")]
 245        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<DepartmentShortDTO>))]
 246        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 247        [AllowAnonymous]
 248        public async Task<IActionResult> GetShopDepartments(string filter = null, string sort = default)
 249        {
 250            filter = filter.NormalizeName();
 251            var departments = await _departmentService.GetDepartmentsByKind(DepartmentKind.Shop, filter, sort);
 0252            return Ok(departments.Select(x => new DepartmentShortDTO(x)));
 253        }
 254
 255        /// <summary>
 256        /// Возвращает список подразделений, отфильтрованных по типу Завод
 257        /// </summary>
 258        /// <remarks>author i.rebenok</remarks>
 259        /// <param name="filter">фильтр по значимым полям Name</param>
 260        /// <param name="sort">по id|desc, name,name|desc, kindName,kindName|desc postalAddress,postalAddress|desc  area
 261        /// <returns>Список розничных контрагентов </returns>
 262        [HttpGet("Plant")]
 263        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<DepartmentShortDTO>))]
 264        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 265        [Authorize(Roles = Role.SystemAdmin + "," + Role.SystemOperator + "," + Role.ManufactureSpec + "," + Role.Manufa
 266        public async Task<IActionResult> GetPlantDepartments(string filter = null, string sort = default)
 267        {
 268            filter = filter.NormalizeName();
 269            var departments = await _departmentService.GetDepartmentsByKind(DepartmentKind.Plant, filter, sort);
 0270            return Ok(departments.Select(x => new DepartmentShortDTO(x)));
 271        }
 272
 273        /// <summary>
 274        /// Получить данные адреса по id адреса
 275        /// </summary>
 276        /// <param name="id">id адреса</param>
 277        /// <remarks>author i.rebenok</remarks>
 278        [HttpGet("Address")]
 279        [SwaggerResponse(200, "Успешно", typeof(DepartmentPostalAddressDTO_GET))]
 280        [SwaggerResponse(404, "Нет записей", typeof(EmptyResult))]
 281        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 282        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 283        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner + "," + Role.ShopMerchandi
 284        public async Task<IActionResult> GetAddress([SwaggerParameter(Required = true)] long id)
 0285        {
 0286            var result = await _addressService.GetAddress(id);
 0287            if (result == null)
 0288                return NotFoundResult($"Адрес с id={id} не найден");
 0289            return Ok(new DepartmentPostalAddressDTO_GET(result));
 0290        }
 291
 292        /// <summary>
 293        /// Получить список типов подразаделений
 294        /// </summary>
 295        /// <remarks>author i.rebenok</remarks>
 296        /// <param name="contragentId">id контрагента. Если 0 , то выводить все типы, иначе только те типы подразделений
 297        [HttpGet("Kind")]
 298        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<IdNameDTO>))]
 299        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 300        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 301        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner+"," + Role.SystemOperator)
 302        public async Task<IActionResult> GetKindType(long contragentId = 0)
 303        {
 304            var result = await _departmentService.GetKindType(contragentId);
 0305            return Ok(result.Select(x => new { x.Id, x.Name, x.ContragentsKindId }));
 306        }
 307
 308        /// <summary>
 309        /// Получить список статусов подразаделений
 310        /// </summary>
 311        /// <remarks>author i.rebenok</remarks>
 312        [HttpGet("Status")]
 313        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<IdNameDTO>))]
 314        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 315        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 316        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner+"," + Role.SystemOperator)
 317        public async Task<IActionResult> GetStatusType()
 318        {
 319            var result = await _departmentService.GetStatusType();
 0320            return Ok(result.Select(x => new IdNameDTO { Id = x.Id, Name = x.Name }));
 321        }
 322
 323        /// <summary>
 324        /// Создает подразделение и возвращает созданный объект
 325        /// </summary>
 326        /// <remarks>author i.rebenok</remarks>
 327        /// <param name="departmentDto">DepartmentRequestDTO</param>
 328        [HttpPost("")]
 329        [SwaggerResponse(201, "Успешно создано", typeof(DepartmentDTO_GET))]
 330        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 331        [SwaggerResponse(400, "Некорректные входные данные", typeof(ErrorDTO))]
 332        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 333        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 334        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner)]
 335        public async Task<IActionResult> CreateDepartment([FromBody] [SwaggerParameter(Required = true)] DepartmentReque
 0336        {
 0337            if (!_authUserService.IsUserPlatform() && _authUserService.ContragentId != departmentDto.ContragentId)
 0338                throw new ForbidException("Нет прав на выполнение этого действия");
 0339            var department = await PrepareDepartment(new Department(), departmentDto);
 0340            await _departmentWorker.CreateDepartment(department, departmentDto.WarehouseId);
 0341            return CreatedAtAction("GetDepartment", new { id = department.Id }, new DepartmentDTO_GET(department));
 0342        }
 343
 344        /// <summary>
 345        /// Обновляет поля подразделения  за исключением привязки/отвязки юзеров и контрагента
 346        /// </summary>
 347        /// <remarks>author i.rebenok</remarks>
 348        /// <param name="id">id подразделения</param>
 349        /// <param name="departmentDto">JSON DepartmentRequestDTO</param>
 350        [HttpPut("{id}")]
 351        [SwaggerResponse(200, "Успешно обновлено", typeof(DepartmentDTO_GET))]
 352        [SwaggerResponse(400, "Некорректные входные данные", typeof(ErrorDTO))]
 353        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 354        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 355        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 356        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner)]
 357        public async Task<IActionResult> UpdateDepartment([SwaggerParameter(Required = true)] long id, [FromBody] [Swagg
 0358        {
 0359            if (!_authUserService.IsUserPlatform() && _authUserService.ContragentId != departmentDto.ContragentId)
 0360                throw new ForbidException("Нет прав на выполнение этого действия");
 0361            var department = _authUserService.IsUserPlatform() ? await _departmentService.GetDepartment(id) : await _dep
 0362            if (department == null)
 0363                throw new KeyNotFoundException($"Подразделение с id={id} не найдено");
 0364            department = await PrepareDepartment(department, departmentDto);
 0365            await _departmentService.UpdateDepartment(department);
 0366            return Ok(new DepartmentDTO_GET(department));
 0367        }
 368
 369        /// <summary>
 370        /// Привязывает указанных пользователей к подразделению
 371        /// </summary>
 372        /// <remarks>author i.rebenok</remarks>
 373        /// <param name="id">Id подразделения</param>
 374        /// <param name="depDto">JSON DepartmentBindUserDTO_PUT</param>
 375        [HttpPut("{id}/Bind")]
 376        [SwaggerResponse(200, "Успешно обновлено", typeof(EmptyResult))]
 377        [SwaggerResponse(400, "Некорректные входные данные", typeof(ErrorDTO))]
 378        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 379        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 380        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 381        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner)]
 382        public async Task<IActionResult> BindUsersToDepartment([SwaggerParameter(Required = true)] long id, [FromBody] [
 0383        {
 0384            await _departmentWorker.BindUserToDepartment(id, depDto.UsersId);
 0385            return Ok();
 0386        }
 387
 388        /// <summary>
 389        /// Отвязывает указанных пользователей от подразделения
 390        /// </summary>
 391        /// <remarks>author i.rebenok</remarks>
 392        /// <param name="id">Id подразделения</param>
 393        /// <param name="depDto">JSON DepartmentBindUserDTO_PUT</param>
 394        [HttpPut("{id}/Unbind")]
 395        [SwaggerResponse(200, "Успешно обновлено", typeof(EmptyResult))]
 396        [SwaggerResponse(400, "Некорректные входные данные", typeof(ErrorDTO))]
 397        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 398        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 399        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 400        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner)]
 401        public async Task<IActionResult> UnbindUsersFromDepartment([SwaggerParameter(Required = true)] long id, [FromBod
 0402        {
 0403            await _departmentWorker.UnbindUserFromDepartment(id, depDto.UsersId);
 0404            return Ok();
 0405        }
 406
 407        /// <summary>
 408        /// Удаляет подразделение по id
 409        /// </summary>
 410        /// <remarks>author i.rebenok</remarks>
 411        /// <param name="id">id подразделения</param>
 412        [HttpDelete("{id}")]
 413        [SwaggerResponse(200, "Успешно удалено", typeof(EmptyResult))]
 414        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 415        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 416        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 417        [Authorize(Roles = Role.SystemAdmin + "," + Role.ShopOwner + "," + Role.SupplierOwner)]
 418        public async Task<IActionResult> DeleteDepartment([SwaggerParameter(Required = true)] long id)
 0419        {
 0420            var department = User.IsInRole(Role.SystemAdmin) ? await _departmentService.GetDepartment(id) : await _depar
 0421            if (department == null)
 0422                return NotFoundResult($"Подразделение с id={id} не найдено");
 0423            await _departmentService.DeleteDepartment(department);
 0424            return Ok();
 0425        }
 426
 427        /// <summary>
 428        /// Выводит список уникальных складов-отправителей, которые встречаются в заявках/отгрузках для текущего КА.
 429        /// </summary>
 430        /// <param name="movementType">тип документов, для которых используется фильтр. Если заявки, то передаем orders,
 431        /// <remarks>author i.rebenok</remarks>
 432        [HttpGet("ListByMovementWarehouse")]
 433        [SwaggerResponse(200, "Успешно удалено", typeof(IdNameDTO))]
 434        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 435        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 436        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 437        [Authorize]
 438        public async Task<IActionResult> GetFilterListByMovementWarehouse(string movementType = "orders")
 439        {
 440            var result = await _departmentWorker.GetFilterListByMovementDepartment(DepartmentKind.Warehouse, movementTyp
 0441            return Ok(result.Select(x=> new IdNameDTO(x.Id,x.Name)));
 442        }
 443
 444        /// <summary>
 445        /// Выводит список уникальных магазинов-получателей, которые встречаются в заявках/отгрузках для текущего КА.
 446        /// </summary>
 447        /// <param name="movementType">тип документов, для которых используется фильтр. Если заявки, то передаем orders,
 448        /// <remarks>author i.rebenok</remarks>
 449        [HttpGet("ListByMovementShop")]
 450        [SwaggerResponse(200, "Успешно удалено", typeof(IdNameDTO))]
 451        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 452        [SwaggerResponse(403, "Не разрешено для этого пользователя", typeof(ErrorDTO))]
 453        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 454        [Authorize]
 455        public async Task<IActionResult> GetFilterListByMovementShop(string movementType = "orders")
 456        {
 457            var result = await _departmentWorker.GetFilterListByMovementDepartment(DepartmentKind.Shop, movementType == 
 0458            return Ok(result.Select(x => new IdNameDTO(x.Id, x.Name)));
 459        }
 460
 461        /// <summary>
 462        /// Подготоваливает экземпляр подразделения для обновления/создания
 463        /// </summary>
 464        /// <param name="department">Класс подразделения</param>
 465        /// <param name="departmentDto">ДТО подразделения</param>
 466        /// <returns></returns>
 467        private async Task<Department> PrepareDepartment(Department department, DepartmentRequestDTO departmentDto)
 468        {
 469            if (department.Contragent?.Id != departmentDto.ContragentId)
 470            {
 471                var contragent = await _contrService.GetContragent(departmentDto.ContragentId);
 472                if (contragent == null)
 473                    throw new KeyNotFoundException($"Контрагент с id={departmentDto.ContragentId} не найден");
 474                department.Contragent = contragent;
 475                department.UsersDepartments ??= new List<UserDepartment>();
 0476                department.UsersDepartments.RemoveAll(x => x.DepartmentId == department?.Id); // удаляем привязки старог
 477                department.UsersDepartments.Add(new UserDepartment() { UserId = contragent.Owner.Id }); //по умолчанию з
 478            }
 479            var availableKinds = await _departmentService.GetKindType(departmentDto.ContragentId);//проверяем какие типы
 0480            if (!availableKinds.Any(x=>x.Id == departmentDto.KindId))
 481                throw new ArgumentException($"Для контрагента с id={departmentDto.ContragentId} недопустимо создание под
 482            department.Area = departmentDto.Area;
 0483            department.Kind = availableKinds.FirstOrDefault(x => x.Id == departmentDto.KindId);
 484            department.Kpp = departmentDto.Kpp;
 485            department.Name = departmentDto.Name;
 486            department.Email = departmentDto.Email;
 487            department.PhoneNumber = departmentDto.PhoneNumber;
 0488            department.Status = (await _departmentService.GetStatusType()).FirstOrDefault(x => x.Id == departmentDto.Sta
 489            if (departmentDto.PostalAddress.Id != 0)
 490                department.ActualAddress = await _addressService.GetAddress(departmentDto.PostalAddress.Id);
 491            if (department.ActualAddress == null)
 492                department.ActualAddress = new Address();
 493            department.ActualAddress.Building = departmentDto.PostalAddress.Building;
 494            department.ActualAddress.City = departmentDto.PostalAddress.City;
 495            department.ActualAddress.District = departmentDto.PostalAddress.District;
 496            department.ActualAddress.House = departmentDto.PostalAddress.House;
 497            department.ActualAddress.Housing = departmentDto.PostalAddress.Housing;
 498            department.ActualAddress.Index = departmentDto.PostalAddress.Index;
 499            department.ActualAddress.Locality = departmentDto.PostalAddress.Locality;
 500            department.ActualAddress.Office = departmentDto.PostalAddress.Office;
 501            department.ActualAddress.Region = departmentDto.PostalAddress.Region;
 502            department.ActualAddress.Street = departmentDto.PostalAddress.Street;
 503            department.ActualAddress.FullAddress = string.IsNullOrWhiteSpace(departmentDto.PostalAddress.FullAddress) ? 
 504                departmentDto.PostalAddress.Region + ", " + departmentDto.PostalAddress.District + ", г " + departmentDt
 505                + ", ул " + departmentDto.PostalAddress.Street + ", " + departmentDto.PostalAddress.House + (!string.IsN
 506                + (!string.IsNullOrWhiteSpace(departmentDto.PostalAddress.Building) ? ", стр " + departmentDto.PostalAdd
 507                + (!string.IsNullOrWhiteSpace(departmentDto.PostalAddress.Office) ? ", офис " + departmentDto.PostalAddr
 508            if (department.Kind == null)
 509                throw new KeyNotFoundException("Тип подразделения не найден");
 510            if (department.Status == null)
 511                throw new KeyNotFoundException("Статус подразделения не найден");
 512            return department;
 513        }
 514
 515        #endregion
 516
 517
 518
 519        #region api/v1/Department/CategoryRatio
 520        /// <summary>
 521        /// Получить торговые коэффициенты для одного подразделения по всем категориям товаров. Для тех категорий, у кот
 522        /// </summary>
 523        /// <remarks>author IPod</remarks>
 524        /// <param name="id">Id подразделения</param>
 525        /// <param name="parentId">Идентифиатор родительской категории: null - все категории, 0 - корневые категории, >1
 526        /// <param name="filter">Фильтр для поиска по названию категории</param>
 527        /// <param name="page">Любое значение ниже нуля изменится на 1, номер страницы</param>
 528        /// <param name="limit">Любое значение ниже нуля изменится на 10, лимит выдачи</param>
 529        /// <returns></returns>
 530        [HttpGet("{id}/CategoryRatios")]
 531        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<DepartmentCategoryRatioResponseDTO>))]
 532        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 533        [Authorize(Roles = Role.SystemAdmin + "," + Role.SystemOperator + "," + Role.SupplierOwner)]
 534        public async Task<IActionResult> GetDepartmentCategoryRatios(long id, long? parentId, string filter=null, int pa
 0535        {
 0536            filter = filter.NormalizeName();
 0537            var result = await _departmentWorker.GetCategoryRatios(id, parentId, filter, page, limit);
 0538            return Ok(result);
 0539        }
 540
 541        /// <summary>
 542        /// Получить торговый коэффициент для одного подразделения и одной категории товара по ключу записи
 543        /// </summary>
 544        /// <remarks>author IPod</remarks>
 545        /// <param name="id">id записи с торговым коэффициентом</param>
 546        /// <returns></returns>
 547        [HttpGet("CategoryRatios/{id}")]
 548        [SwaggerResponse(200, "Успешно", typeof(DepartmentCategoryRatioResponseDTO))]
 549        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 550        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 551        [Authorize(Roles = Role.SystemAdmin + "," + Role.SystemOperator + "," + Role.SupplierOwner)]
 552        public async Task<IActionResult> GetDepartmentCategoryRatio(long id)
 0553        {
 0554            var data = await _serviceCategoryRatio.GetDepartmentCategoryRatio(id);
 555
 0556            if (data == null || (data.Department.Contragent?.Id != _authUserService.ContragentId && !_authUserService.Is
 0557                return NotFoundResult($"Запись c id={id} не найдена");
 558
 0559            var result = new DepartmentCategoryRatioResponseDTO
 0560            {
 0561                Id = data.Id,
 0562                CategoryId = data.Category.Id,
 0563                ParentId = data.Category.Parent?.Id,
 0564                Name = data.Category.Name,
 0565                Code = data.Category.Code,
 0566                DepartmentId = data.Department.Id,
 0567                TradeRatio = data.TradeRatio,
 0568                Expandable = (await _categoryService.GetCategories(1, 10, null, data.Id)).Count() > 0
 0569            };
 0570            return Ok(result);
 0571        }
 572
 573        /// <summary>
 574        /// Создать торговый коэффициент для одного подразделения по одной категории товара.
 575        /// </summary>
 576        /// <remarks>author IPod</remarks>
 577        /// <param name="id">Id департамента</param>
 578        /// <param name="data">{CategoryId, TradeRatio - торговый коэфициент}</param>
 579        /// <returns></returns>
 580        [HttpPost("{id}/CategoryRatios")]
 581        [SwaggerResponse(200, "Успешно", typeof(DepartmentCategoryRatioResponseDTO))]
 582        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 583        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 584        [Authorize(Roles = Role.SystemAdmin + "," + Role.SupplierOwner)]
 585        public async Task<IActionResult> PostDepartmentCategoryRatio(long id, [FromBody] DepartmentCategoryRatioRequestD
 0586        {
 0587            var result = await _departmentWorker.CreateCategoryRatio(id, data.CategoryId, data.TradeRatio);
 0588            return Ok(result);
 0589        }
 590
 591        /// <summary>
 592        /// Обновить торговый коэффициент по ключу
 593        /// </summary>
 594        /// <remarks>author IPod</remarks>
 595        /// <param name="id">Id записи</param>
 596        /// <param name="data">{TradeRatio - торговый коэфициент}</param>
 597        [HttpPut("CategoryRatios/{id}")]
 598        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 599        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 600        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 601        [Authorize(Roles = Role.SystemAdmin + "," + Role.SupplierOwner)]
 602        public async Task<IActionResult> PutDepartmentCategoryRatio(long id, [FromBody] DepartmentCategoryRatioRequestDt
 0603        {
 0604            var item = await _serviceCategoryRatio.GetDepartmentCategoryRatio(id);
 0605            if (item == null || (item.Department.Contragent?.Id != _authUserService.ContragentId && !_authUserService.Is
 0606                return NotFoundResult($"Запись c id={id} не найдена");
 0607            item.TradeRatio = data.TradeRatio;
 0608            await _serviceCategoryRatio.Update(item);
 0609            return Ok(item);
 0610        }
 611
 612        /// <summary>
 613        /// Удалить запись по id
 614        /// </summary>
 615        /// <remarks>author IPod</remarks>
 616        /// <param name="id">Id записи</param>
 617        [HttpDelete("CategoryRatios/{id}")]
 618        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 619        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 620        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 621        [Authorize(Roles = Role.SystemAdmin)]
 622        public async Task<IActionResult> DeleteDepartmentCategoryRatio(long id)
 0623        {
 0624            await _serviceCategoryRatio.Delete(id);
 0625            return Ok();
 0626        }
 627        #endregion
 628    }
 629}