< Summary

Class:SVETA.Api.Controllers.OrdersController
Assembly:SVETA.Api
File(s):/opt/dev/sveta_api_build/SVETA.Api/Controllers/OrdersController.cs
Covered lines:0
Uncovered lines:204
Coverable lines:204
Total lines:686
Line coverage:0% (0 of 204)
Covered branches:0
Total branches:48
Branch coverage:0% (0 of 48)

Metrics

MethodLine coverage Branch coverage
.ctor(...)0%100%
GetOrders()0%0%
getResponseParamUrl(...)0%0%
GetCountOrders()0%100%
GetOrdersExcel()0%0%
SetDeliveryType()0%100%
GetAnonymousCaсhe()0%0%
AddAnonymousGoodToOrder()0%100%
ClearAnonymousCaсhe()0%100%
GetOrder()0%0%
GetCurrentDraft()0%0%
CreateOrder()0%0%
CreateOnBaseShipment()0%100%
CloneOrder()0%100%
GetItems()0%0%
AddItemToOrder()0%100%
ChangeQuantity()0%0%
RemoveItemFromOrder()0%100%
SendOrderToSupplier()0%100%
ConfirmOrder()0%100%
Reject()0%100%
DeleteOrder()0%100%
DownloadOrderToFile()0%0%
PrintOrder()0%100%
PlatformReject()0%100%
GetMovementHistory()0%100%
GetOrderDeliveryType()0%100%

File(s)

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

#LineLine coverage
 1using Microsoft.AspNetCore.Mvc;
 2using WinSolutions.Sveta.Common.Extensions;
 3using SVETA.Api.Data.DTO.Cluster;
 4using Microsoft.Extensions.Logging;
 5using SVETA.Api.Data.Domain;
 6using SVETA.Api.Data.DTO;
 7using SVETA.Api.Data.DTO.Movements;
 8using SVETA.Api.Services.Interfaces;
 9using Swashbuckle.AspNetCore.Annotations;
 10using System;
 11using System.Collections.Generic;
 12using System.IO;
 13using System.Threading;
 14using System.Threading.Tasks;
 15using ClosedXML.Excel;
 16using Microsoft.AspNetCore.Authorization;
 17using Microsoft.AspNetCore.Builder;
 18using Microsoft.AspNetCore.Mvc.ModelBinding;
 19using SVETA.Api.Helpers;
 20using SVETA.Api.Helpers.Authorize;
 21using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 22using WinSolutions.Sveta.Server.Data.DataModel.Kinds;
 23using WinSolutions.Sveta.Server.Domain;
 24using WinSolutions.Sveta.Server.Services.Interfaces;
 25using WinSolutions.Sveta.Common;
 26
 27namespace SVETA.Api.Controllers
 28{
 29    /// <summary>
 30    /// Контроллер обработки заявок от магазина
 31    /// </summary>
 32    /// <remarks>author: aabelentsov</remarks>
 33    [Authorize]
 34    [Route("api/v1/Orders")]
 35    [ApiController]
 36    public class OrdersController : SvetaController
 37    {
 38        const string _routeUrl = "api/v1/Orders";
 39        private readonly IMovementWorker _movementWorker;
 40        private readonly ILogger<OrdersController> _logger;
 41        private readonly IMovementStatusRouter _movementStatusRouter;
 42        private readonly IAuthenticationService _authenticationService;
 43
 44        public OrdersController(
 45            IAuthenticationService authUserService,
 46            IMovementWorker movementWorker,
 47            IMovementStatusRouter movementStatusRouter,
 048            ILogger<OrdersController> logger) : base(logger)
 049        {
 050            _movementWorker = movementWorker;
 051            _logger = logger;
 052            _movementStatusRouter = movementStatusRouter;
 053            _authenticationService = authUserService;
 054        }
 55
 56        /// <summary>
 57        /// Возвращает отфильтрованный и отсортированный список документов
 58        /// </summary>
 59        /// <remarks>author: aabelentsov, oboligatov</remarks>
 60        /// <param name="id">Идентификатор документа (0 для всех)</param>
 61        /// <param name="documentNumber">Номер документа (null для всех)</param>
 62        /// <param name="customerId">Идентификтор заказчика - (контрагент) (0 для всех)</param>
 63        /// <param name="receiverId">Идентификтор получателя - (магазин) (0 для всех)</param>
 64        /// <param name="supplierId">Идентификтор поставщика  - (контрагент) (0 для всех)</param>
 65        /// <param name="senderId">Идентификатор склада отправителя - (склад) (0 для всех)</param>
 66        /// <param name="fromDate">Дата начала отбора (null для всех)</param>
 67        /// <param name="toDate">Дата окончания отбора (null для всех)</param>
 68        /// <param name="statusId">Статус документа - 0 для всех</param>
 69        /// <param name="stateId">Состояние документа - 0 для всех</param>
 70        /// <param name="page">Любое значение ниже нуля изменится на 1, Страница</param>
 71        /// <param name="limit">Любое значение ниже нуля изменится на 10, Количество для отбора - макс 100</param>
 72        /// <param name="sort">сортировка по умолчанию по id - id|desc,created_on,created_on|desc,state,state|desc,statu
 73        /// <param name="showAnonymous">отображение анонимных заявок - по умолчанию nonanonymous, anonymousonly - только
 74        /// <returns></returns>
 75        [HttpGet()]
 76        [SwaggerResponse(200, "Успешно", typeof(BaseResponseDTO<MovementDTO>))]
 77        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 78        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 79        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 80        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpera
 81        public async Task<IActionResult> GetOrders(long id = 0, long customerId = 0, long receiverId = 0, long supplierI
 82            DateTimeOffset fromDate = default, DateTimeOffset toDate = default, int stateId = 0, int statusId = 0, strin
 83            string sort = null, int page = 1, int limit = 10, string showAnonymous = "nonanonymous")
 084        {
 085            documentNumber = documentNumber.NormalizeName();
 086            page = page < 1 ? 1 : page;
 087            limit = limit < 1 ? 10 : limit;
 88
 089            var requestParam = new MovementParam(id, customerId, receiverId, supplierId,senderId, fromDate.GetStartOfDat
 090                MovementKind.Order, stateId, statusId, documentNumber,page, limit, sort, default, showAnonymous);
 091            PaginatedData<List<MovementDTO>> orders =  await _movementWorker.GetMovements(requestParam);
 92
 093            var param = getResponseParamUrl(customerId, receiverId, supplierId, fromDate,
 094                toDate, stateId,
 095                statusId, senderId);
 096            var response = new BaseResponseDTO<MovementDTO>(_routeUrl, page, limit, orders.TotalFilteredCount,
 097                orders.TotalCount, sort, param: param)
 098            {
 099                Data = orders.Result ?? new List<MovementDTO>()
 0100            };
 0101            return Ok(response);
 0102        }
 103
 104        string getResponseParamUrl(long customerId, long receiverId, long supplierId, DateTimeOffset fromDate, DateTimeO
 0105        {
 0106            var param = "";
 0107            if (customerId != 0)
 0108                param += $"customerId={customerId}";
 0109            if (receiverId != 0)
 0110                param += $"&receiverId={receiverId}";
 0111            if (supplierId != 0)
 0112                param += $"&supplierId={supplierId}";
 0113            if (senderId != 0)
 0114                param += $"&senderId={senderId}";
 115            //if (fromDate.HasValue)
 0116                param += $"&fromDate={fromDate.ToISOString()}";
 117            //if (toDate.HasValue)
 0118                param += $"&toDate={toDate.ToISOString()}";
 0119            if (stateId != 0)
 0120                param += $"&stateId={stateId}";
 0121            if (statusId != 0)
 0122                param += $"&statusId={statusId}";
 0123            if (param.StartsWith("&"))
 0124                param = param.Trim(new char[] { '&' });
 0125            return param;
 0126        }
 127
 128        /// <summary>
 129        /// Возвращает количество заказов
 130        /// </summary>
 131        /// <remarks>author: aabelentsov</remarks>
 132        /// <param name="documentNumber">Номер документа (null для всех)</param>
 133        /// <param name="customerId">Идентификтор заказчика - (контрагент) (0 для всех)</param>
 134        /// <param name="receiverId">Идентификтор получателя - (магазин) (0 для всех)</param>
 135        /// <param name="supplierId">Идентификтор поставщика  - (контрагент) (0 для всех)</param>
 136        /// <param name="fromDate">Дата начала отбора (null для всех)</param>
 137        /// <param name="toDate">Дата окончания отбора (null для всех)</param>
 138        /// <param name="statusId">Статус документа - 0 для всех</param>
 139        /// <param name="stateId">Состояние документа - 0 для всех</param>
 140        /// <returns></returns>
 141        [HttpGet("Count")]
 142        [SwaggerResponse(200, "Успешно", typeof(CountDTO))]
 143        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 144        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 145        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 146        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpera
 147        public async Task<IActionResult> GetCountOrders(long customerId = 0, long receiverId = 0, long supplierId = 0, l
 148            DateTimeOffset fromDate = default, DateTimeOffset toDate = default, int stateId = 0, int statusId = 0,
 149            string documentNumber = null)
 0150        {
 0151            documentNumber = documentNumber.NormalizeName();
 0152            var requestParam = new MovementParam(customerId, receiverId, supplierId,senderId, fromDate.GetStartOfDate(),
 0153                MovementKind.Order, stateId, statusId, documentNumber);
 0154            return Ok(new CountDTO(await _movementWorker.GetCountMovement(requestParam)));
 0155        }
 156
 157        /// <summary>
 158        /// Возвращает отфильтрованный и отсортированный список документов
 159        /// </summary>
 160        /// <remarks>author: aabelentsov, oboligatov</remarks>
 161        /// <param name="id">Идентификатор документа (0 для всех)</param>
 162        /// <param name="documentNumber">Номер документа (null для всех)</param>
 163        /// <param name="customerId">Идентификтор заказчика - (контрагент) (0 для всех)</param>
 164        /// <param name="receiverId">Идентификтор получателя - (магазин) (0 для всех)</param>
 165        /// <param name="supplierId">Идентификтор поставщика  - (контрагент) (0 для всех)</param>
 166        /// <param name="fromDate">Дата начала отбора (null для всех)</param>
 167        /// <param name="toDate">Дата окончания отбора (null для всех)</param>
 168        /// <param name="statusId">Статус документа - 0 для всех</param>
 169        /// <param name="stateId">Состояние документа - 0 для всех</param>
 170        /// <param name="sort">сортировка по умолчанию по id - id|desc,created_on,created_on|desc,state,state|desc,statu
 171        /// <param name="showAnonymous">отображение анонимных заявок - по умолчанию nonanonymous, anonymousonly - только
 172        /// <returns></returns>
 173        [HttpGet("ExcelOrders")]
 174        [SwaggerResponse(200, "Успешно", typeof(File))]
 175        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 176        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 177        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 178        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpera
 179        public async Task<IActionResult> GetOrdersExcel(long id = 0, long customerId = 0, long receiverId = 0, long supp
 180            DateTimeOffset fromDate = default, DateTimeOffset toDate = default, int stateId = 0, int statusId = 0, strin
 181            string sort = null, string showAnonymous = "nonanonymous")
 0182        {
 0183            documentNumber = documentNumber.NormalizeName();
 184
 0185            var requestParam = new MovementParam(id, customerId, receiverId, supplierId, senderId, fromDate.GetStartOfDa
 0186                toDate.GetEndOfDate(), MovementKind.Order, stateId, statusId, documentNumber,0, Int32.MaxValue,
 0187                sort, default, showAnonymous, true);
 0188            PaginatedData<List<MovementDTO>> orders =  await _movementWorker.GetMovements(requestParam);
 0189            using var book = new XLWorkbook();
 0190            var worksheet = book.Worksheets.Add("Report");
 0191            var currentRow = 1;
 0192            worksheet.Cell(currentRow, 1).Value = "№п/п";
 0193            worksheet.Cell(currentRow, 2).Value = "Дата создания";
 0194            worksheet.Cell(currentRow, 3).Value = "Номер документа";
 0195            worksheet.Cell(currentRow, 4).Value = "Заказчик";
 0196            worksheet.Cell(currentRow, 5).Value = "Поставщик";
 0197            worksheet.Cell(currentRow, 6).Value = "Получатель";
 0198            worksheet.Cell(currentRow, 7).Value = "Отправитель";
 0199            worksheet.Cell(currentRow, 8).Value = "Статус";
 0200            worksheet.Cell(currentRow, 9).Value = "Сумма";
 0201            worksheet.Cell(currentRow, 10).Value = "Количество позиций";
 0202            worksheet.Cell(currentRow, 11).Value = "Получение заказа";
 0203            int count = 1;
 0204            foreach (var order in orders.Result)
 0205            {
 0206                currentRow++;
 0207                worksheet.Cell(currentRow, 1).Value = count;
 0208                worksheet.Cell(currentRow, 2).Value = order.CreationDateTime;
 0209                worksheet.Cell(currentRow, 3).Value = order.DocumentNumber;
 0210                worksheet.Cell(currentRow, 4).Value = order.Customer.ShortName;
 0211                worksheet.Cell(currentRow, 5).Value = order.Supplier.ShortName;
 0212                worksheet.Cell(currentRow, 6).Value = order.Receiver.Name;
 0213                worksheet.Cell(currentRow, 7).Value = order.Sender.Name;
 0214                worksheet.Cell(currentRow, 8).Value = order.MovementStatus.Name;
 0215                worksheet.Cell(currentRow, 9).Value = order.Sum;
 0216                worksheet.Cell(currentRow, 10).Value = order.ItemsCount;
 0217                worksheet.Cell(currentRow, 11).Value = order.DeliveryType?.Name;
 0218            }
 0219            using var stream = new MemoryStream();
 0220            book.SaveAs(stream);
 0221            var content = stream.ToArray();
 0222            return File(content, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
 0223                "ordersList.xlsx");
 0224        }
 225
 226        /// <summary>
 227        /// Назначает заявке тип доставки
 228        /// </summary>
 229        /// <param name="id">id заявки</param>
 230        /// <param name="data">id типа доставки</param>
 231        /// <returns></returns>
 232        [HttpPatch("{id}/DeliveryType")]
 233        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 234        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 235        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 236        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 237        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser)]
 238        public async Task<IActionResult> SetDeliveryType(long id, [FromBody] DeliveryTypeOrderRequestDTO data)
 0239        {
 0240            await _movementWorker.SetDeliveryType(id, data.DeliveryTypeId);
 0241            return Ok();
 0242        }
 243
 244        /// <summary>
 245        /// Возвращает кол-во корзин анонима с указанием товарного состава, складов и возможных магазинов для слияния
 246        /// </summary>
 247        /// <returns></returns>
 248        [HttpGet("GetAnonymousCache")]
 249        [SwaggerResponse(200, "Успешно", typeof(AnonymousMovementMergeDto))]
 250        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 251        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 252        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 253        public async Task<IActionResult> GetAnonymousCaсhe()
 0254        {
 0255            if (_authenticationService.ContragentKindId != (long)ContragentKind.Retailer)
 0256                return Ok(new AnonymousMovementMergeDto { Cache = new List<AnonymousCache>() });
 0257            return Ok(await _movementWorker.GetAnonymousCache());
 0258        }
 259
 260        /// <summary>
 261        /// Добавляет товар из анонимной заявки в заявку магазина.
 262        /// </summary>
 263        /// <param name="orderId">Идентификатор анонимной заявки</param>
 264        /// <param name="goodId">Идентификатор товара</param>
 265        /// <param name="request">Объект с идентификатором магазина для добавления</param>
 266        /// <returns>Строка с информацией об изменении цены товара</returns>
 267        [HttpPost("{orderId}/AddAnonymousGoodToOrder/{goodId}")]
 268        [SwaggerResponse(200, "Успешно", typeof(MessageDto))]
 269        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 270        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 271        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 272        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser)]
 273        public async Task<IActionResult> AddAnonymousGoodToOrder(long orderId, long goodId,
 274            [FromBody] MovementDepartmentRequestDto request)
 0275        {
 0276            return Ok(await _movementWorker.AddAnonymousGoodToOrder(orderId, goodId, request.DepartmentId));
 0277        }
 278
 279        /// <summary>
 280        /// Очищает анонимую заявку
 281        /// </summary>
 282        /// <param name="orderId"></param>
 283        /// <returns></returns>
 284        [HttpPost("ClearAnonymousCache/{orderId}")]
 285        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 286        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 287        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 288        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 289        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser)]
 290        public async Task<IActionResult> ClearAnonymousCaсhe(long orderId)
 0291        {
 0292            await _movementWorker.ClearAnonymousMovement(orderId);
 0293            return Ok();
 0294        }
 295
 296        /// <summary>
 297        /// Возвращает заказ магазина
 298        /// </summary>
 299        /// <remarks>author: aabelentsov</remarks>
 300        /// <param name="id">Идентификатор заказа</param>
 301        /// <param name="isAnonym"></param>
 302        /// <returns>Заказ магазина</returns>
 303        /// <response code="404">Не нашел заказ по id</response>
 304        /// <response code="200">Заказ</response>
 305        [HttpGet("{id}")]
 306        [SwaggerResponse(200, "Успешно", typeof(MovementDTO))]
 307        [SwaggerResponse(400, "Ошибка при подготовке документа к отдаче", typeof(ErrorDTO))]
 308        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 309        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 310        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 311        [AllowAnonymous]
 312        public async Task<IActionResult> GetOrder(long id, bool isAnonym = false)
 0313        {
 0314            isAnonym = isAnonym == false ? _authenticationService.IsAnonym() : isAnonym;
 0315            MovementDTO order = await _movementWorker.GetMovement(id, MovementKind.Order, isAnonym);
 0316            return Ok(order);
 0317        }
 318
 319        /// <summary>
 320        /// Возвращает активный черновик для магазина
 321        /// </summary>
 322        /// <param name="departmentId">департамент - магазин</param>
 323        /// <returns></returns>
 324        [HttpGet("Draft")]
 325        [SwaggerResponse(200, "Успешно", typeof(MovementDTO))]
 326        [SwaggerResponse(400, "Ошибка при подготовке документа к отдаче", typeof(ErrorDTO))]
 327        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 328        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 329        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 330        [AllowAnonymous]
 331        public async Task<IActionResult> GetCurrentDraft(long departmentId)
 0332        {
 0333            MovementDTO order = _authenticationService.IsAnonym() ? await _movementWorker.CreateAnnonymMovement(_authent
 0334                                        : await _movementWorker.CreateEmptyMovement((long)MovementKind.Order, department
 0335                ?? throw new ArgumentException();
 0336            return Ok(order);
 0337        }
 338
 339        /// <summary>
 340        /// Создает заказ
 341        /// </summary>
 342        /// <remarks>author: aabelentsov</remarks>
 343        /// <param name="requestDto">Объект с идентификатором Подразделения на которое создается заявка</param>
 344        /// <returns> Id заказа</returns>
 345        [HttpPost()]
 346        [SwaggerResponse(201, "Успешно", typeof(MovementDTO))]
 347        [SwaggerResponse(400, "Документ невозможно создать", typeof(ErrorDTO))]
 348        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 349        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 350        [AllowAnonymous]
 351        public async Task<IActionResult> CreateOrder(MovementDepartmentRequestDto requestDto)
 0352        {
 0353            MovementDTO movementDto = _authenticationService.IsAnonym()
 0354                ? await _movementWorker.CreateAnnonymMovement(_authenticationService.AnonymousUuid, requestDto.Departmen
 0355                : await _movementWorker.CreateEmptyMovement((long) MovementKind.Order, requestDto.DepartmentId);
 0356            return CreatedAtAction("GetOrder", new { id = movementDto.Id }, movementDto);
 0357        }
 358
 359        /// <summary>
 360        /// Создает заказа на базе отгрузки
 361        /// </summary>
 362        /// <param name="requestDto">Объект с документом основанием</param>
 363        /// <returns></returns>
 364        [HttpPost("CreateOnBase")]
 365        [SwaggerResponse(201, "Успешно", typeof(MovementDTO))]
 366        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 367        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 368        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 369        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 370        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser)]
 371        public async Task<IActionResult> CreateOnBaseShipment([FromBody] MovementCreateOnBaseDto requestDto)
 0372        {
 0373            MovementDTO mDto = await _movementWorker.CreateMovementOnBase(requestDto.MovementId, MovementKind.Order);
 0374            return CreatedAtAction("GetOrder", new { id = mDto.Id }, mDto);
 0375        }
 376
 377        /// <summary>
 378        /// Клонирование заявки магазина в новую заявку
 379        /// </summary>
 380        /// <remarks>author: aabelentsov</remarks>
 381        /// <param name="id">Идентификтор заявки донора</param>
 382        /// <param name="departmentId">Идентификатор магазина</param>
 383        /// <param name="request">Объект с идентификтором подразделения в который копируется документ</param>
 384        /// <returns>Объект заявки</returns>
 385        [HttpPost("{id}/Clone")]
 386        [SwaggerResponse(201, "Успешно", typeof(MovementDTO))]
 387        [SwaggerResponse(400, "Документ невозможно создать", typeof(ErrorDTO))]
 388        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 389        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 390        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 391        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser)]
 392        public async Task<IActionResult> CloneOrder(long id, MovementDepartmentRequestDto request)
 0393        {
 0394            MovementDTO mDto = await _movementWorker.CloneMovement(id, request.DepartmentId);
 0395            return CreatedAtAction("GetOrder", new { id = mDto.Id }, mDto);
 0396        }
 397
 398        /// <summary>
 399        /// Возвращает список товаров в заявке
 400        /// </summary>
 401        /// <param name="id">Идентификатор документа</param>
 402        /// <param name="filter">Строка фильтра по имени товара</param>
 403        /// <param name="sort">сортировка id - по умолчанию, id|desc, name, name|desc, created_on, created_on|desc, pric
 404        /// <param name="page">Номер страницы для отбора, 1 - по умолчанию, меньше или 0 - изменится на 1</param>
 405        /// <param name="limit">Лимит отбора, 10 - по умолчанию, меньше или 0 - изменится на 10</param>
 406        /// <returns></returns>
 407        [HttpGet("{id}/Items")]
 408        [SwaggerResponse(200, "Успешно", typeof(BaseResponseDTO<MovementItemResponseDTO>))]
 409        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 410        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 411        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 412        //[Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpe
 413        [AllowAnonymous]
 414        public async Task<IActionResult> GetItems(long id, string filter, string sort, int page = 1, int limit = 10)
 0415        {
 0416            filter = filter.NormalizeName();
 0417            page = page < 1 ? 1 : page;
 0418            limit = limit < 1 ? 10 : limit;
 0419            var result = await _movementWorker.GetMovementItems(id, MovementKind.Order, filter, sort, page, limit);
 420
 0421            var response = new BaseResponseDTO<MovementItemResponseDTO>($"{_routeUrl}/{id}/Items", page, limit,
 0422                result.TotalFilteredCount,
 0423                result.TotalCount, sort, param: $"filter={filter}")
 0424            {
 0425                Data = result.Result
 0426            };
 0427            return Ok(response);
 0428        }
 429
 430        /// <summary>
 431        /// Добавляет позицию к заказу
 432        /// </summary>
 433        /// <remarks>author: aabelentsov</remarks>
 434        /// <param name="id">Идентификатор документа</param>
 435        /// <param name="mItemDto">Объект для добавления</param>
 436        /// <returns>NoContent</returns>
 437        [HttpPost("{id}/Items")]
 438        [SwaggerResponse(200, "Успешно", typeof(MovementItemResponseDTO))]
 439        [SwaggerResponse(400, "Не найден заказ, не найден товар", typeof(ErrorDTO))]
 440        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 441        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 442        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 443        [AllowAnonymous]
 444        public async Task<IActionResult> AddItemToOrder(long id, [FromBody] MovementItemRequestDTO mItemDto)
 0445        {
 0446            return Ok(await _movementWorker.AddItemToMovement(id, mItemDto));
 0447        }
 448
 449        /// <summary>
 450        /// Изменяет количество товара в заявке
 451        /// </summary>
 452        /// <remarks>author: aabelentsov</remarks>
 453        /// <param name="id">Идентификатор документа</param>
 454        /// <param name="itemId">Идентификтора позиции</param>
 455        /// <param name="request">Объект с изменениями</param>
 456        /// <returns>No Content</returns>
 457        /// <response code="204">Количество товара изменено</response>
 458        /// <response code="404">Не найден заказ, позиция заказа</response>
 459        /// <response code="400">Количество товара не соответствует требованиям</response>
 460        [HttpPut("{id}/Items/{itemId}")]
 461        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 462        [SwaggerResponse(400, "Количество товара не соответствует требованиям", typeof(ErrorDTO))]
 463        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 464        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 465        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 466        [AllowAnonymous]
 467        public async Task<IActionResult> ChangeQuantity(long id, long itemId, [FromBody] MovementChangeQuantityRequestDt
 0468        {
 0469            if (request.Quantity <= 0)
 0470                throw new ArgumentException("Количество товара в заказе должно быть больше 0");
 471
 0472            await _movementWorker.ChangeQuantityInMovement(id, itemId, request.Quantity.Value, null);
 0473            return Ok();
 0474        }
 475        /// <summary>
 476        /// Удаляет позицию из заказа
 477        /// </summary>
 478        /// <remarks>author: aabelentsov</remarks>
 479        /// <param name="id">Идентификатор документа</param>
 480        /// <param name="itemId">Идентификатор позиции</param>
 481        /// <returns></returns>
 482        [HttpDelete("{id}/Items/{itemId}")]
 483        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 484        [SwaggerResponse(400, "Статус заказа отличен от черновика", typeof(ErrorDTO))]
 485        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 486        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 487        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 488        [AllowAnonymous]
 489        public async Task<IActionResult> RemoveItemFromOrder(long id, long itemId)
 0490        {
 0491            await _movementWorker.RemoveItemFromMovement(id, itemId);
 0492            return Ok();
 0493        }
 494
 495        /// <summary>
 496        /// Отправка заказа на выполнение
 497        /// </summary>
 498        /// <remarks>author: aabelentsov</remarks>
 499        /// <param name="id">Идентификатор документа</param>
 500        /// <returns>Переводит заказ в состояние Активен, в статус - В обработке</returns>
 501        /// <response code="404">Не найден заказ</response>
 502        /// <response code="400">В заказе есть ошибки</response>
 503        /// <response code="204">Заказ переведен в статус в Обработке</response>
 504        [HttpPost("{id}/Send")]
 505        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 506        [SwaggerResponse(400, "Статус заказа отличен от черновика", typeof(ErrorDTO))]
 507        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 508        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 509        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 510        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser)]
 511        public async Task<IActionResult> SendOrderToSupplier(long id)
 0512        {
 0513            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.send);
 0514            return Ok();
 0515        }
 516
 517
 518        /// <summary>
 519        /// Подтверждает заказ
 520        /// </summary>
 521        /// <remarks>author: aabelentsov</remarks>
 522        /// <param name="id">Идентификатор документа</param>
 523        /// <returns>Переводит заказ в статус В обработке</returns>
 524        [HttpPost("{id}/Confirm")]
 525        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 526        [SwaggerResponse(400, "Статус заказа не в обработке, стояние записи заказа не активна", typeof(ErrorDTO))]
 527        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 528        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 529        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 530        [Authorize(Roles = Role.SystemAdmin)]
 531        public async Task<IActionResult> ConfirmOrder(long id)
 0532        {
 533
 0534            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.confirm);
 535
 0536            return Ok();
 0537        }
 538
 539        /// <summary>
 540        /// Отказ от заявки
 541        /// </summary>
 542        /// <remarks>author: aabelentsov</remarks>
 543        /// <param name="id">Идентификатор заявки</param>
 544        /// <param name="request">Причина отказа в исполнении заявки</param>
 545        /// <returns></returns>
 546        [HttpPost("{id}/Reject")]
 547        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 548        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 549        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 550        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 551        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 552        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.SystemAdmin)]
 553        public async Task<IActionResult> Reject(long id, [FromBody]  MovementCommentRequestDto request)
 0554        {
 0555            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.rejectOrder, request.Comment);
 0556            return Ok();
 0557        }
 558
 559
 560        /// <summary>
 561        /// Удаление заказа
 562        /// </summary>
 563        /// <remarks>author: aabelentsov</remarks>
 564        /// <param name="id">Идентификатор документа</param>
 565        /// <returns></returns>
 566        [HttpDelete("{id}")]
 567        [SwaggerResponse(200, "Успешно", typeof(OkResult))]
 568        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 569        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 570        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 571        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 572        [Authorize(Roles = Role.ShopOwner)]
 573        public async Task<IActionResult> DeleteOrder(long id)
 0574        {
 0575            await _movementWorker.DeleteMovement(id);
 0576            return Ok();
 0577        }
 578
 579        /// <summary>
 580        /// Выгрузка документа в csv/excel
 581        /// </summary>
 582        /// <remarks>author: aabelentsov</remarks>
 583        /// <param name="id">Идентификатор документа</param>
 584        /// <param name="fileType">формат файла: excel или csv. По умолчанию csv</param>
 585        /// <returns></returns>
 586        [HttpGet("{id}/DownloadOrderToFile")]
 587        [SwaggerResponse(302, "Успешно", typeof(File))]
 588        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 589        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 590        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 591        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemAdmin
 592        public async Task<IActionResult> DownloadOrderToFile(long id, string fileType = "csv")
 0593        {
 0594            fileType = fileType.ToLower();
 0595            string fileName = "OR" + id.ToString("D8") + "_" + DateTime.UtcNow.Ticks;
 0596            fileName += fileType == "csv" ? ".csv" : ".xlsx";
 0597            var stream = await _movementWorker.GetFile(id, MovementKind.Order, fileType);
 0598            stream.Position = 0;
 0599            if (fileType == "csv")
 0600                return File(stream, "text/csv", fileName);
 601            else
 0602            {
 0603                return File(stream.ToArray(),
 0604                    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
 0605                    fileName);
 606            }
 0607        }
 608        /// <summary>
 609        /// Печать заказа по id документа в системе
 610        /// </summary>
 611        /// <remarks>author: oafadin + aabelentsov</remarks>
 612        /// <param name="id">Идентификатор заказа</param>
 613        /// <returns></returns>
 614        [HttpGet("{id}/Print")]
 615        [SwaggerResponse(200, "Файловый поток", typeof(FileStreamResult))]
 616        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 617        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 618        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 619        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 620        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemAdmin
 621        public async Task<IActionResult> PrintOrder(long id)
 0622        {
 0623            var pdfStream = await _movementWorker.PrintOrder(id, MovementKind.Order);
 0624            return new FileStreamResult(pdfStream, "application/pdf");
 0625        }
 626
 627        /// <summary>
 628        /// Отказ от заявки - Используй метод reject
 629        /// </summary>
 630        /// <remarks>author: aabelentsov</remarks>
 631        /// <param name="id">Идентификатор заявки</param>
 632        /// <param name="request">Причина отказа в исполнении заявки</param>
 633        /// <returns></returns>
 634        [HttpPost("{id}/PlatformReject")]
 635        [Obsolete]
 636        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 637        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 638        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 639        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 640        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 641        [Authorize(Roles = Role.SystemAdmin)]
 642        public async Task<IActionResult> PlatformReject(long id, [FromBody]  MovementCommentRequestDto request)
 0643        {
 0644            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.autoReject, request.Comment);
 0645            return Ok();
 0646        }
 647
 648        /// <summary>
 649        /// Возвращает историю по заявке
 650        /// </summary>
 651        /// <remarks>author: irebenok</remarks>
 652        /// <param name="id">Идентификатор заявки</param>
 653        /// <returns></returns>
 654        [HttpGet("{id}/History")]
 655        [SwaggerResponse(200, "Успешно", typeof(List<MovementHistoryResponseDTO>))]
 656        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 657        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 658        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 659        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 660        [Authorize(Roles = Role.SystemAdmin)]
 661        public async Task<IActionResult> GetMovementHistory(long id)
 0662        {
 0663            var result = await _movementWorker.GetMovementHistory(id);
 0664            return Ok(result);
 0665        }
 666
 667        /// <summary>
 668        /// Возвращает тип доставки для заявки
 669        /// </summary>
 670        /// <remarks>author: irebenok</remarks>
 671        /// <param name="id">Идентификатор заявки</param>
 672        /// <returns></returns>
 673        [HttpGet("{id}/DeliveryTypes")]
 674        [SwaggerResponse(200, "Успешно", typeof(ClusterDeliveryTypesResponseDTO))]
 675        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 676        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 677        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 678        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 679        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemAdmin
 680        public async Task<IActionResult> GetOrderDeliveryType(long id)
 0681        {
 0682            var result = await _movementWorker.GetOrderDeliveryTypes(id);
 0683            return Ok(result);
 0684        }
 685    }
 686}