< Summary

Class:SVETA.Api.Controllers.ShipmentsController
Assembly:SVETA.Api
File(s):/opt/dev/sveta_api_build/SVETA.Api/Controllers/ShipmentsController.cs
Covered lines:0
Uncovered lines:285
Coverable lines:285
Total lines:1020
Line coverage:0% (0 of 285)
Covered branches:0
Total branches:58
Branch coverage:0% (0 of 58)

Metrics

MethodLine coverage Branch coverage
.ctor(...)0%100%
GetShipments()0%0%
GetCountShipments()0%100%
GetShipmentsExcel()0%0%
GetShipment()0%100%
DownloadOrderToFile()0%0%
PrintShipment()0%100%
Print()0%100%
PrintSf()0%100%
PrintTtn()0%100%
PrintTorg()0%100%
PrintTn()0%100%
PrintArchive()0%100%
GetAttachmentInfo()0%100%
GetItems()0%0%
CreateShipment()0%100%
AddItemToShipment()0%100%
ChangeQuantity()0%0%
RemoveItemFromShipment()0%100%
PaymentReserve()0%100%
ReadyToShip()0%100%
Ship()0%100%
Correction()0%100%
Accept()0%100%
Deliver()0%100%
RejectPayment()0%0%
RevertPayment()0%0%
RevertReadyToShip()0%0%
RevertDelivery()0%0%
RevertShip()0%0%
RevertClaim()0%0%
CustomerReject()0%0%
SupplierReject()0%100%
DeclineClaim()0%100%
AcceptClaim()0%100%
DeleteShipment()0%0%
CreateTransaction()0%100%
AddAttachment()0%0%
DeleteAttachment()0%100%
GetMovementHistory()0%100%
getResponseParamUrl(...)0%0%

File(s)

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

#LineLine coverage
 1using Microsoft.AspNetCore.Authorization;
 2using Microsoft.AspNetCore.Http;
 3using Microsoft.AspNetCore.Mvc;
 4using Microsoft.Extensions.Logging;
 5using SVETA.Api.Data.Domain;
 6using SVETA.Api.Data.DTO;
 7using SVETA.Api.Services.Interfaces;
 8using Swashbuckle.AspNetCore.Annotations;
 9using System;
 10using System.Collections.Generic;
 11using System.IO;
 12using System.IO.Compression;
 13using System.Linq;
 14using System.Net;
 15using System.Threading.Tasks;
 16using ClosedXML.Excel;
 17using DocumentFormat.OpenXml.Wordprocessing;
 18using IdentityServer4.Events;
 19using Microsoft.AspNetCore.Mvc.ModelBinding;
 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 Wkhtmltopdf.NetCore;
 25using WinSolutions.Sveta.Common;
 26using SVETA.Api.Data.DTO.Movements;
 27using SVETA.Api.Helpers;
 28using SVETA.Api.Services.Implements;
 29using WinSolutions.Sveta.Server.Data.DataLoading;
 30using WinSolutions.Sveta.Common.Extensions;
 31
 32namespace SVETA.Api.Controllers
 33{
 34    /// <summary>
 35    /// Контроллер для работы с огрузками
 36    /// </summary>
 37    /// <remarks>author: aabelentsov</remarks>
 38    [Authorize]
 39    [Route("api/v1/Shipments")]
 40    [ApiController]
 41    public class ShipmentsController : SvetaController
 42    {
 43        const string _routeUrl = "api/v1/Shipments";
 44        readonly ILogger<ShipmentsController> _logger;
 45        readonly IMovementWorker _movementWorker;
 46        private readonly IMovementStatusRouter _movementStatusRouter;
 47        private readonly IWalletPaymentService _walletPaymentService;
 48        private readonly IAuthenticationService _authUserService;
 49
 50        public ShipmentsController(IMovementWorker movementWorker,
 51            IAuthenticationService authUserService,
 52            IWalletPaymentService walletPaymentService,
 53            IMovementStatusRouter movementStatusRouter,
 054            ILogger<ShipmentsController> logger) : base(logger)
 055        {
 056            _movementWorker = movementWorker;
 057            _walletPaymentService = walletPaymentService;
 058            _movementStatusRouter = movementStatusRouter;
 059            _logger = logger;
 060            _authUserService = authUserService;
 061        }
 62
 63        /// <summary>
 64        /// Возвращает список отгрузок
 65        /// </summary>
 66        /// <remarks>author: aabelentsov, oboligatov</remarks>
 67        /// <param name="id">Идентификатор документа (0 для всех)</param>
 68        /// <param name="documentNumber">Номер документа (null для всех)</param>
 69        /// <param name="customerId">Идентификтор заказчика - (контрагент) (0 для всех)</param>
 70        /// <param name="receiverId">Идентификтор получателя - (магазин) (0 для всех)</param>
 71        /// <param name="supplierId">Идентификтор поставщика - (контрагент) (0 для всех)</param>
 72        /// <param name="senderId">Идентификатор склада отправителя - (склад) (0 для всех)</param>
 73        /// <param name="fromDate">Дата начала отбора (null для всех)</param>
 74        /// <param name="toDate">Дата окончания отбора (null для всех)</param>
 75        /// <param name="contragentBuyerFilter">Строка поиска по контрагенту покупателю - полное и короткое название</pa
 76        /// <param name="statusId">Статус документа - 0 для всех</param>
 77        /// <param name="stateId">Состояние документа - 0 для всех</param>
 78        /// <param name="page">Любое значение ниже нуля изменится на 1, Страница</param>
 79        /// <param name="limit">Любое значение ниже нуля изменится на 10, Количество для отбора - макс 100</param>
 80        /// <param name="sort">сортировка по умолчанию по id - id|desc,created_on,created_on|desc,state,state|desc,statu
 81        /// <returns></returns>
 82        [HttpGet]
 83        [SwaggerResponse(200, "Успешно", typeof(BaseResponseDTO<MovementDTO>))]
 84        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 85        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 86        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 87        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpera
 88        public async Task<IActionResult> GetShipments(long id = 0, long customerId = 0, long receiverId = 0, long suppli
 89            DateTimeOffset fromDate = default, DateTimeOffset toDate = default, int stateId = 0, int statusId = 0, strin
 90            string sort = null, int page = 1, int limit = 10)
 091        {
 092            contragentBuyerFilter = contragentBuyerFilter.NormalizeName();
 093            documentNumber = documentNumber.NormalizeName();
 94
 095            page = page < 1 ? 1 : page;
 096            limit = limit < 1 ? 10 : limit;
 97
 098            var requestParam = new MovementParam(id, customerId, receiverId, supplierId, senderId, fromDate.GetStartOfDa
 099                MovementKind.Shipment, stateId, statusId, documentNumber, page, limit, sort, contragentBuyerFilter);
 0100            PaginatedData<List<MovementDTO>> data = await _movementWorker.GetMovements(requestParam);
 101
 0102            var param = getResponseParamUrl(customerId, receiverId, supplierId,
 0103                fromDate,
 0104                toDate,
 0105                stateId,
 0106                statusId, senderId);
 107
 0108            var response = new BaseResponseDTO<MovementDTO>(_routeUrl, page, limit, data.TotalFilteredCount,
 0109                data.TotalCount, sort, param: param)
 0110            {
 0111                Data = data.Result ?? new List<MovementDTO>()
 0112            };
 0113            return Ok(response);
 0114        }
 115
 116        /// <summary>
 117        /// Возвращает количество отгрузок
 118        /// </summary>
 119        /// <remarks>author: aabelentsov</remarks>
 120        /// <param name="documentNumber">Номер документа (null для всех)</param>
 121        /// <param name="customerId">Идентификтор заказчика - (контрагент) (0 для всех)</param>
 122        /// <param name="receiverId">Идентификтор получателя - (магазин) (0 для всех)</param>
 123        /// <param name="supplierId">Идентификтор поставщика  - (контрагент) (0 для всех)</param>
 124        /// <param name="fromDate">Дата начала отбора (null для всех)</param>
 125        /// <param name="toDate">Дата окончания отбора (null для всех)</param>
 126        /// <param name="statusId">Статус документа - 0 для всех</param>
 127        /// <param name="stateId">Состояние документа - 0 для всех</param>
 128        /// <returns></returns>
 129        [HttpGet("Count")]
 130        [SwaggerResponse(200, "Успешно", typeof(CountDTO))]
 131        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 132        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 133        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 134        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpera
 135        public async Task<IActionResult> GetCountShipments(long customerId = 0, long receiverId = 0, long supplierId = 0
 136            DateTimeOffset fromDate = default, DateTimeOffset toDate = default, int stateId = 0, int statusId = 0,
 137            string documentNumber = null)
 0138        {
 0139            documentNumber = documentNumber.NormalizeName();
 0140            var requestParam = new MovementParam(customerId, receiverId, supplierId,senderId, fromDate.GetStartOfDate(),
 0141                MovementKind.Shipment, stateId, statusId, documentNumber);
 0142            return Ok(new CountDTO(await _movementWorker.GetCountMovement(requestParam)));
 0143        }
 144
 145        /// <summary>
 146        /// Возвращает отфильтрованный и отсортированный список документов
 147        /// </summary>
 148        /// <remarks>author: aabelentsov, oboligatov</remarks>
 149        /// <param name="id">Идентификатор документа (0 для всех)</param>
 150        /// <param name="documentNumber">Номер документа (null для всех)</param>
 151        /// <param name="customerId">Идентификтор заказчика - (контрагент) (0 для всех)</param>
 152        /// <param name="receiverId">Идентификтор получателя - (магазин) (0 для всех)</param>
 153        /// <param name="supplierId">Идентификтор поставщика  - (контрагент) (0 для всех)</param>
 154        /// <param name="fromDate">Дата начала отбора (null для всех)</param>
 155        /// <param name="toDate">Дата окончания отбора (null для всех)</param>
 156        /// <param name="statusId">Статус документа - 0 для всех</param>
 157        /// <param name="stateId">Состояние документа - 0 для всех</param>
 158        /// <param name="sort">сортировка по умолчанию по id - id|desc,created_on,created_on|desc,state,state|desc,statu
 159        /// <param name="showAnonymous">отображение анонимных заявок - по умолчанию nonanonymous, anonymousonly - только
 160        /// <returns></returns>
 161        [HttpGet("ExcelShipments")]
 162        [SwaggerResponse(200, "Успешно", typeof(File))]
 163        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 164        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 165        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 166        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpera
 167        public async Task<IActionResult> GetShipmentsExcel(long id = 0, long customerId = 0, long receiverId = 0, long s
 168            DateTimeOffset fromDate = default, DateTimeOffset toDate = default, int stateId = 0, int statusId = 0, strin
 169            string sort = null, string showAnonymous = "nonanonymous")
 0170        {
 0171            documentNumber = documentNumber.NormalizeName();
 172
 0173            var requestParam = new MovementParam(id, customerId, receiverId, supplierId,senderId, fromDate.GetStartOfDat
 0174                toDate.GetEndOfDate(), MovementKind.Shipment, stateId, statusId, documentNumber,0, Int32.MaxValue,
 0175                sort, default, showAnonymous, true);
 0176            PaginatedData<List<MovementDTO>> orders =  await _movementWorker.GetMovements(requestParam);
 0177            using var book = new XLWorkbook();
 0178            var worksheet = book.Worksheets.Add("Report");
 0179            var currentRow = 1;
 0180            worksheet.Cell(currentRow, 1).Value = "№п/п";
 0181            worksheet.Cell(currentRow, 2).Value = "Дата создания";
 0182            worksheet.Cell(currentRow, 3).Value = "Номер документа";
 0183            worksheet.Cell(currentRow, 4).Value = "Заказчик";
 0184            worksheet.Cell(currentRow, 5).Value = "Поставщик";
 0185            worksheet.Cell(currentRow, 6).Value = "Получатель";
 0186            worksheet.Cell(currentRow, 7).Value = "Отправитель";
 0187            worksheet.Cell(currentRow, 8).Value = "Статус";
 0188            worksheet.Cell(currentRow, 9).Value = "Сумма";
 0189            worksheet.Cell(currentRow, 10).Value = "Количество позиций";
 0190            worksheet.Cell(currentRow, 11).Value = "Получение заказа";
 0191            int count = 1;
 0192            foreach (var order in orders.Result)
 0193            {
 0194                currentRow++;
 0195                worksheet.Cell(currentRow, 1).Value = count;
 0196                worksheet.Cell(currentRow, 2).Value = order.CreationDateTime;
 0197                worksheet.Cell(currentRow, 3).Value = order.DocumentNumber;
 0198                worksheet.Cell(currentRow, 4).Value = order.Customer.ShortName;
 0199                worksheet.Cell(currentRow, 5).Value = order.Supplier.ShortName;
 0200                worksheet.Cell(currentRow, 6).Value = order.Receiver.Name;
 0201                worksheet.Cell(currentRow, 7).Value = order.Sender.Name;
 0202                worksheet.Cell(currentRow, 8).Value = order.MovementStatus.Name;
 0203                worksheet.Cell(currentRow, 9).Value = order.Sum;
 0204                worksheet.Cell(currentRow, 10).Value = order.ItemsCount;
 0205                worksheet.Cell(currentRow, 11).Value = order.DeliveryType?.Name;
 0206            }
 0207            using var stream = new MemoryStream();
 0208            book.SaveAs(stream);
 0209            var content = stream.ToArray();
 0210            return File(content, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
 0211                "shipmentsList.xlsx");
 0212        }
 213
 214        /// <summary>
 215        /// Возвращает отгрузку по id
 216        /// </summary>
 217        /// <remarks>author: aabelentsov</remarks>
 218        /// <param name="id">Идентификатор документа</param>
 219        /// <returns></returns>
 220        [HttpGet("{id}")]
 221        [SwaggerResponse(200, "Успешно", typeof(MovementDTO))]
 222        [SwaggerResponse(400, "Ошибка при подготовке документа к отдаче", typeof(ErrorDTO))]
 223        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 224        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 225        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 226        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpera
 227        public async Task<IActionResult> GetShipment(long id)
 0228        {
 0229            MovementDTO shipment = await _movementWorker.GetMovement(id, MovementKind.Shipment);
 0230            return Ok(shipment);
 0231        }
 232
 233        /// <summary>
 234        /// Выгрузка документа в csv/excel
 235        /// </summary>
 236        /// <remarks>author: aabelentsov</remarks>
 237        /// <param name="id">Идентификатор документа</param>
 238        /// <param name="fileType">формат файла: excel или csv. По умолчанию csv</param>
 239        /// <returns></returns>
 240        [HttpGet("{id}/DownloadShipmentToFile")]
 241        [SwaggerResponse(302, "Успешно", typeof(File))]
 242        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 243        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 244        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 245        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemAdmin
 246        public async Task<IActionResult> DownloadOrderToFile(long id, string fileType = "csv")
 0247        {
 0248            fileType = fileType.ToLower();
 0249            string fileName = "SH" + id.ToString("D8") + "_" + DateTime.UtcNow.Ticks;
 0250            fileName += fileType == "csv" ? ".csv" : ".xlsx";
 0251            var stream = await _movementWorker.GetFile(id, MovementKind.Shipment, fileType);
 0252            stream.Position = 0;
 0253            if (fileType == "csv")
 0254                return File(stream, "text/csv", fileName);
 255            else
 0256            {
 0257                return File(stream.ToArray(),
 0258                    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
 0259                    fileName);
 260            }
 0261        }
 262        /// <summary>
 263        /// Печать УПД по id документа в системе
 264        /// </summary>
 265        /// <remarks>author: aabelentsov</remarks>
 266        /// <param name="id">Идентификатор документа</param>
 267        /// <returns></returns>
 268        [HttpGet("{id}/Print")]
 269        [SwaggerResponse(200, "Файловый поток", typeof(FileStreamResult))]
 270        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 271        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 272        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 273        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 274        [Authorize]
 275        public async Task<IActionResult> PrintShipment(long id)
 0276        {
 0277            var pdfStream = await _movementWorker.PrintUpd(id);
 0278            return new FileStreamResult(pdfStream, "application/pdf");
 0279        }
 280        /// <summary>
 281        /// Печать по id документа в системе
 282        /// </summary>
 283        /// <remarks>author: aabelentsov</remarks>
 284        /// <param name="id">Идентификатор документа</param>
 285        /// <returns></returns>
 286        [HttpGet("{id}/SimplePrint")]
 287        [SwaggerResponse(200, "Файловый поток", typeof(FileStreamResult))]
 288        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 289        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 290        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 291        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 292        [Authorize]
 293        public async Task<IActionResult> Print(long id)
 0294        {
 0295            var pdfStream = await _movementWorker.PrintOrder(id, MovementKind.Shipment);
 0296            return new FileStreamResult(pdfStream, "application/pdf");
 0297        }
 298        /// <summary>
 299        /// Печать по id документа счетфактуры
 300        /// </summary>
 301        /// <remarks>author: aabelentsov</remarks>
 302        /// <param name="id">Идентификатор документа</param>
 303        /// <returns></returns>
 304        [HttpGet("{id}/PrintSf")]
 305        [SwaggerResponse(200, "Файловый поток", typeof(FileStreamResult))]
 306        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 307        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 308        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 309        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 310        [Authorize]
 311        public async Task<IActionResult> PrintSf(long id)
 0312        {
 0313            var pdfStream = await _movementWorker.PrintSf(id, MovementKind.Shipment);
 0314            return new FileStreamResult(pdfStream, "application/pdf");
 0315        }
 316        /// <summary>
 317        /// Печать по id документа ТТН
 318        /// </summary>
 319        /// <remarks>author: aabelentsov</remarks>
 320        /// <param name="id">Идентификатор документа</param>
 321        /// <returns></returns>
 322        [HttpGet("{id}/PrintTtn")]
 323        [SwaggerResponse(200, "Файловый поток", typeof(FileStreamResult))]
 324        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 325        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 326        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 327        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 328        [Authorize]
 329        public async Task<IActionResult> PrintTtn(long id)
 0330        {
 0331            var pdfStream = await _movementWorker.PrintTtn(id, MovementKind.Shipment);
 0332            return new FileStreamResult(pdfStream, "application/pdf");
 0333        }
 334        /// <summary>
 335        /// Печать по id документа ТОРГ12
 336        /// </summary>
 337        /// <remarks>author: aabelentsov</remarks>
 338        /// <param name="id">Идентификатор документа</param>
 339        /// <returns></returns>
 340        [HttpGet("{id}/PrintTorg")]
 341        [SwaggerResponse(200, "Файловый поток", typeof(FileStreamResult))]
 342        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 343        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 344        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 345        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 346        [Authorize]
 347        public async Task<IActionResult> PrintTorg(long id)
 0348        {
 0349            var pdfStream = await _movementWorker.PrintTorg(id, MovementKind.Shipment);
 0350            return new FileStreamResult(pdfStream, "application/pdf");
 0351        }
 352        /// <summary>
 353        /// Печать по id документа Траснпортной накладной
 354        /// </summary>
 355        /// <remarks>author: aabelentsov</remarks>
 356        /// <param name="id">Идентификатор документа</param>
 357        /// <returns></returns>
 358        [HttpGet("{id}/PrintTn")]
 359        [SwaggerResponse(200, "Файловый поток", typeof(FileStreamResult))]
 360        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 361        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 362        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 363        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 364        [Authorize]
 365        public async Task<IActionResult> PrintTn(long id)
 0366        {
 0367            var pdfStream = await _movementWorker.PrintTn(id, MovementKind.Shipment);
 0368            return new FileStreamResult(pdfStream, "application/pdf");
 0369        }
 370
 371        /// <summary>
 372        /// Печать по id пакет документов
 373        /// </summary>
 374        /// <remarks>author: aabelentsov</remarks>
 375        /// <param name="id">Идентификатор документа</param>
 376        /// <returns></returns>
 377        [HttpGet("{id}/PrintArchive")]
 378        [SwaggerResponse(200, "Файловый поток", typeof(FileStreamResult))]
 379        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 380        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 381        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 382        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 383        [Authorize]
 384        public async Task<IActionResult> PrintArchive(long id)
 0385        {
 0386            var stream = await _movementWorker.CreateZip(id);
 0387            return new FileStreamResult(stream, "application/zip");
 0388        }
 389
 390        /// <summary>
 391        /// Получение информации о вложениях для документа
 392        /// </summary>
 393        /// <remarks>author: aabelentsov</remarks>
 394        /// <param name="id">Идентификатор документа</param>
 395        /// <param name="page">Страница выборки - 1 по умолчанию</param>
 396        /// <param name="limit">Количество для выборки - 10 по умолчанию</param>
 397        /// <param name="filter">Фильтр по названию документа</param>
 398        /// <param name="sort">Сортировка по полям - по умолчанию id - id,id|desc,name,name|desc,created_on,created_on|d
 399        /// <returns></returns>
 400        [HttpGet("{id}/GetAttachmentInfo")]
 401        [SwaggerResponse(200, "Успешно", typeof(BaseResponseDTO<MovementAttachmentInfoDto>))]
 402        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 403        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 404        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 405        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 406        [Authorize]
 407        public async Task<IActionResult> GetAttachmentInfo(long id, int page = 1, int limit = 10, string filter = defaul
 0408        {
 0409            var result = await _movementWorker.GetAttachmentsInfo(id, page, limit, filter, sort);
 410
 0411            var pagination = new BaseResponseDTO<MovementAttachmentInfoDto>($"{_routeUrl}/{id}/GetAttachmentInfo",
 0412                page, limit, result.TotalFilteredCount, result.TotalCount, sort, $"filter={filter}")
 0413            {
 0414                Data = result.Result
 0415            };
 0416            return Ok(pagination);
 0417        }
 418
 419        /// <summary>
 420        /// Возвращает список товаров
 421        /// </summary>
 422        /// <param name="id">Идентификатор документа</param>
 423        /// <param name="filter">Строка фильтра по имени товара</param>
 424        /// <param name="sort">сортировка id - по умолчанию, id|desc, name, name|desc, created_on, created_on|desc, pric
 425        /// <param name="page">Номер страницы для отбора, 1 - по умолчанию, меньше или 0 - изменится на 1</param>
 426        /// <param name="limit">Лимит отбора, 10 - по умолчанию, меньше или 0 - изменится на 10</param>
 427        /// <returns></returns>
 428        [SwaggerResponse(200, "Успешно", typeof(List<MovementItemResponseDTO>))]
 429        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 430        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 431        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 432        [HttpGet("{id}/Items")]
 433        [Authorize(Roles = Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller + "," + Role.SystemOpera
 434        public async Task<IActionResult> GetItems(long id, string filter, string sort, int page = 1, int limit = 10)
 0435        {
 0436            filter = filter.NormalizeName();
 0437            page = page < 1 ? 1 : page;
 0438            limit = limit < 1 ? 10 : limit;
 0439            var result =
 0440                await _movementWorker.GetMovementItems(id, MovementKind.Shipment, filter, sort, page, limit);
 0441            var response = new BaseResponseDTO<MovementItemResponseDTO>($"{_routeUrl}/{id}/Items", page, limit,
 0442                result.TotalFilteredCount,
 0443                result.TotalCount, sort, param: $"filter={filter}")
 0444            {
 0445                Data = result.Result
 0446            };
 0447            return Ok(response);
 0448        }
 449
 450        /// <summary>
 451        /// Создание отгрузки на основании заказа от магазина
 452        /// </summary>
 453        /// <remarks>author: aabelentsov</remarks>
 454        /// <param name="requestDto">Объект с Идентификатором заказа, на основании которого создается отгрузка</param>
 455        /// <returns></returns>
 456        /// <response code="404">Не нашел документ по id</response>
 457        /// <response code="400">Ошибка</response>
 458        /// <response code="204"></response>
 459        [HttpPost()]
 460        [SwaggerResponse(201, "Успешно", typeof(MovementDTO))]
 461        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 462        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 463        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 464        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 465        [Authorize(Roles = Role.SystemAdmin)]
 466        private async Task<IActionResult> CreateShipment(MovementCreateOnBaseDto requestDto)
 0467        {
 0468            MovementDTO mDto = await _movementWorker.CreateMovementOnBase(requestDto.MovementId, MovementKind.Shipment);
 0469            return CreatedAtAction("GetShipment", new { id = mDto.Id }, mDto);
 0470        }
 471
 472        /// <summary>
 473        /// Добавляет позицию к отгрузке
 474        /// </summary>
 475        /// <remarks>author: oboligatov</remarks>
 476        /// <param name="id">Идентификатор документа</param>
 477        /// <param name="mItemDTO">Объект для добавления</param>
 478        /// <returns>NoContent</returns>
 479        [HttpPost("{id}/Items")]
 480        [SwaggerResponse(200, "Успешно", typeof(MovementItemResponseDTO))]
 481        [SwaggerResponse(400, "Не найдена отгрузка, не найден товар", typeof(ErrorDTO))]
 482        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 483        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 484        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 485        [Authorize(Roles = Role.SupplierOperator + "," + Role.SupplierOwner)]
 486        public async Task<IActionResult> AddItemToShipment(long id, MovementItemRequestDTO mItemDTO)
 0487        {
 0488            return Ok(await _movementWorker.AddItemToMovement(id, mItemDTO));
 0489        }
 490
 491        /// <summary>
 492        /// Изменяет количество товара в отгрузке
 493        /// </summary>
 494        /// <remarks>author: oboligatov</remarks>
 495        /// <param name="id">Идентификатор документа</param>
 496        /// <param name="itemId">Идентификтора позиции</param>
 497        /// <param name="request">Объект с изменениями</param>
 498        /// <returns>No Content</returns>
 499        /// <response code="204">Количество товара изменено</response>
 500        /// <response code="404">Не найден заказ, позиция заказа</response>
 501        /// <response code="400">Количество товара не соответствует требованиям</response>
 502        [HttpPut("{id}/Items/{itemId}")]
 503        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 504        [SwaggerResponse(400, "Количество товара не соответствует требованиям", typeof(ErrorDTO))]
 505        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 506        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 507        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 508        [Authorize(Roles = Role.SupplierOperator + "," + Role.SupplierOwner)]
 509        public async Task<IActionResult> ChangeQuantity(long id, long itemId, [FromBody] MovementChangeQuantityRequestDt
 0510        {
 0511            if (request.Quantity <= 0)
 0512                throw new ArgumentException("Количество товара в заказе должно быть больше 0");
 0513            await _movementWorker.ChangeQuantityInMovement(id, itemId, request.Quantity.Value);
 0514            return Ok();
 0515        }
 516
 517        /// <summary>
 518        /// Удаляет позицию из отгрузки
 519        /// </summary>
 520        /// <remarks>author: oboligatov</remarks>
 521        /// <param name="id">Идентификатор документа</param>
 522        /// <param name="itemId">Идентификатор позиции</param>
 523        /// <returns></returns>
 524        [HttpDelete("{id}/Items/{itemId}")]
 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.SupplierOperator + "," + Role.SupplierOwner)]
 531        public async Task<IActionResult> RemoveItemFromShipment(long id, long itemId)
 0532        {
 0533            await _movementWorker.RemoveItemFromMovement(id, itemId);
 0534            return Ok();
 0535        }
 536        /// <summary>
 537        /// Изменяет статус отгрузки на требуется внесение предоплаты
 538        /// </summary>
 539        /// <param name="id">номер документа</param>
 540        /// <returns></returns>
 541        [HttpPost("{id}/PaymentReserve")]
 542        [SwaggerResponse(201, "Успешно", typeof(OkResult))]
 543        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 544        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 545        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 546        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 547        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator)]
 548        public async Task<IActionResult> PaymentReserve(long id)
 0549        {
 0550            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.paymentReserve);
 0551            return Ok();
 0552        }
 553        /// <summary>
 554        /// Отгрузка готова к выдаче
 555        /// </summary>
 556        /// <remarks>author: aabelentsov</remarks>
 557        /// <param name="id">Идентификатор отгрузки</param>
 558        /// <returns></returns>
 559        /// <response code="404">Не нашел документ по id</response>
 560        /// <response code="400">Ошибка</response>
 561        /// <response code="204"></response>
 562        [HttpPost("{id}/ReadyToShip")]
 563        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 564        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 565        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 566        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 567        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 568        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator)]
 569        public async Task<IActionResult> ReadyToShip(long id)
 0570        {
 0571            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.readyToShip);
 0572            return NoContent();
 0573        }
 574        /// <summary>
 575        /// Выдача отгрузки
 576        /// </summary>
 577        /// <remarks>author: aabelentsov</remarks>
 578        /// <param name="id">Идентификатор отгрузки</param>
 579        /// <returns></returns>
 580        /// <response code="404">Не нашел документ по id</response>
 581        /// <response code="400">Ошибка</response>
 582        /// <response code="204"></response>
 583        [HttpPost("{id}/Ship")]
 584        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 585        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 586        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 587        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 588        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 589        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator)]
 590        public async Task<IActionResult> Ship(long id)
 0591        {
 0592            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.ship);
 0593            return NoContent();
 0594        }
 595
 596        /// <summary>
 597        /// Корректировка отгрузки
 598        /// </summary>
 599        /// <remarks>author: aabelentsov</remarks>
 600        /// <param name="id">Идентификатор отгрузки</param>
 601        /// <param name="request">Комментарий причины перевода отгрузки в корректировку</param>
 602        /// <returns></returns>
 603        [HttpPost("{id}/Correction")]
 604        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 605        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 606        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 607        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 608        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 609        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator)]
 610        public async Task<IActionResult> Correction(long id, [FromBody]  MovementCommentRequestDto request)
 0611        {
 0612            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.correctionShipment, request.Comment);
 0613            return NoContent();
 0614        }
 615        /// <summary>
 616        /// Прием отгрузки
 617        /// </summary>
 618        /// <remarks>author: aabelentsov</remarks>
 619        /// <param name="id">Идентификатор отгрузки</param>
 620        /// <returns></returns>
 621        [HttpPost("{id}/Accept")]
 622        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 623        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 624        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 625        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 626        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 627        [Authorize(Roles = Role.ShopMerchandiser + "," + Role.ShopOwner)]
 628        public async Task<IActionResult> Accept(long id)
 0629        {
 0630            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.accept);
 0631            return NoContent();
 0632        }
 633
 634        /// <summary>
 635        /// Доставка отгрузки
 636        /// </summary>
 637        /// <remarks>author: aabelentsov</remarks>
 638        /// <param name="id">Идентификатор отгрузки</param>
 639        /// <returns></returns>
 640        [HttpPost("{id}/Deliver")]
 641        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 642        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 643        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 644        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 645        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 646        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator)]
 647        public async Task<IActionResult> Deliver(long id)
 0648        {
 0649            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.deliver);
 0650            return NoContent();
 0651        }
 652
 653        /// <summary>
 654        /// Отказ от отгрузки администратором
 655        /// </summary>
 656        /// <remarks>author: aabelentsov</remarks>
 657        /// <param name="id">Идентификатор отгрузки</param>
 658        /// <param name="request">Комментарий для отказа от отгрузки</param>
 659        /// <returns></returns>
 660        [HttpPost("{id}/RejectPayment")]
 661        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 662        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 663        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 664        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 665        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 666        [Authorize(Roles = Role.SystemAdmin)]
 667        public async Task<IActionResult> RejectPayment(long id, [FromBody]  MovementCommentRequestDto request)
 0668        {
 0669            if (string.IsNullOrWhiteSpace(request.Comment))
 0670                throw new ArgumentException("Причина отказа обязательное поле");
 0671            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.rejectPayment, request.Comment);
 0672            return NoContent();
 0673        }
 674        /// <summary>
 675        /// Откат отгрузки в статус Черновик
 676        /// </summary>
 677        /// <remarks>author: aabelentsov</remarks>
 678        /// <param name="id">Идентификатор отгрузки</param>
 679        /// <param name="request">Комментарий для отказа от отгрузки</param>
 680        /// <returns></returns>
 681        [HttpPost("{id}/RevertPayment")]
 682        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 683        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 684        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 685        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 686        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 687        [Authorize(Roles = Role.SystemAdmin)]
 688        public async Task<IActionResult> RevertPayment(long id, [FromBody]  MovementCommentRequestDto request)
 0689        {
 0690            if (string.IsNullOrWhiteSpace(request.Comment))
 0691                throw new ArgumentException("Причина отказа обязательное поле");
 0692            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.revertPayment, request.Comment);
 0693            return NoContent();
 0694        }
 695
 696        /// <summary>
 697        /// Откат отгрузки в статус Сборка
 698        /// </summary>
 699        /// <remarks>author: aabelentsov</remarks>
 700        /// <param name="id">Идентификатор отгрузки</param>
 701        /// <param name="request">Комментарий для отказа от отгрузки</param>
 702        /// <returns></returns>
 703        [HttpPost("{id}/RevertReadyToShip")]
 704        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 705        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 706        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 707        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 708        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 709        [Authorize(Roles = Role.SystemAdmin)]
 710        public async Task<IActionResult> RevertReadyToShip(long id, [FromBody]  MovementCommentRequestDto request)
 0711        {
 0712            if (string.IsNullOrWhiteSpace(request.Comment))
 0713                throw new ArgumentException("Причина отказа обязательное поле");
 0714            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.revertReadyToShip, request.Comment);
 0715            return NoContent();
 0716        }
 717
 718        /// <summary>
 719        /// Откат отгрузки в статус готово к выдаче из статуса В пути
 720        /// </summary>
 721        /// <remarks>author: aabelentsov</remarks>
 722        /// <param name="id">Идентификатор отгрузки</param>
 723        /// <param name="request">Комментарий для отказа от отгрузки</param>
 724        /// <returns></returns>
 725        [HttpPost("{id}/RevertDelivery")]
 726        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 727        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 728        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 729        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 730        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 731        [Authorize(Roles = Role.SystemAdmin)]
 732        public async Task<IActionResult> RevertDelivery(long id, [FromBody]  MovementCommentRequestDto request)
 0733        {
 0734            if (string.IsNullOrWhiteSpace(request.Comment))
 0735                throw new ArgumentException("Причина отказа обязательное поле");
 0736            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.revertDelivery, request.Comment);
 0737            return NoContent();
 0738        }
 739
 740        /// <summary>
 741        /// Откат отгрузки в статус готово к выдаче из статуса Выдано
 742        /// </summary>
 743        /// <remarks>author: aabelentsov</remarks>
 744        /// <param name="id">Идентификатор отгрузки</param>
 745        /// <param name="request">Комментарий для отказа от отгрузки</param>
 746        /// <returns></returns>
 747        [HttpPost("{id}/RevertShip")]
 748        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 749        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 750        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 751        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 752        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 753        [Authorize(Roles = Role.SystemAdmin)]
 754        public async Task<IActionResult> RevertShip(long id, [FromBody]  MovementCommentRequestDto request)
 0755        {
 0756            if (string.IsNullOrWhiteSpace(request.Comment))
 0757                throw new ArgumentException("Причина отказа обязательное поле");
 0758            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.revertShip, request.Comment);
 0759            return NoContent();
 0760        }
 761
 762        /// <summary>
 763        /// Откат отгрузки в статус Корректировка
 764        /// </summary>
 765        /// <remarks>author: aabelentsov</remarks>
 766        /// <param name="id">Идентификатор отгрузки</param>
 767        /// <param name="request">Комментарий для отказа от отгрузки</param>
 768        /// <returns></returns>
 769        [HttpPost("{id}/RevertClaim")]
 770        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 771        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 772        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 773        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 774        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 775        [Authorize(Roles = Role.SystemAdmin)]
 776        public async Task<IActionResult> RevertClaim(long id, [FromBody]  MovementCommentRequestDto request)
 0777        {
 0778            if (string.IsNullOrWhiteSpace(request.Comment))
 0779                throw new ArgumentException("Причина отказа обязательное поле");
 0780            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.revertClaim, request.Comment);
 0781            return NoContent();
 0782        }
 783
 784        /// <summary>
 785        /// Отказ от отгрузки покупателем
 786        /// </summary>
 787        /// <remarks>author: aabelentsov</remarks>
 788        /// <param name="id">Идентификатор отгрузки</param>
 789        /// <param name="request">Комментарий для отказа от отгрузки</param>
 790        /// <returns></returns>
 791        [HttpPost("{id}/CustomerReject")]
 792        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 793        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 794        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 795        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 796        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 797        [Authorize(Roles = Role.ShopMerchandiser + "," + Role.ShopOwner)]
 798        public async Task<IActionResult> CustomerReject(long id, [FromBody]  MovementCommentRequestDto request)
 0799        {
 0800            if (string.IsNullOrWhiteSpace(request.Comment))
 0801                throw new ArgumentException("Причина отказа обязательное поле");
 0802            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.rejectShipment, request.Comment);
 0803            return NoContent();
 0804        }
 805        /// <summary>
 806        /// Отказ от отгрузки
 807        /// </summary>
 808        /// <remarks>author: aabelentsov</remarks>
 809        /// <param name="id">идентификатор документа</param>
 810        /// <param name="request">Причина отказа в исполнении отгрузки</param>
 811        /// <returns></returns>
 812        /// <response code="404">Не нашел документ по id</response>
 813        /// <response code="400">Ошибка</response>
 814        /// <response code="204"></response>
 815        [HttpPost("{id}/SupplierReject")]
 816        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 817        [SwaggerResponse(400, "Ошибка ", typeof(ErrorDTO))]
 818        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 819        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 820        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 821        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator)]
 822        public async Task<IActionResult> SupplierReject(long id, [FromBody]  MovementCommentRequestDto request)
 0823        {
 0824            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.supplierRejectShipment, request.Comment);
 0825            return NoContent();
 0826        }
 827
 828        /// <summary>
 829        /// Отклонение притензии по отгрузке
 830        /// </summary>
 831        /// <remarks>author: aabelentsov</remarks>
 832        /// <param name="id">Идентификатор документа</param>
 833        /// <returns></returns>
 834        /// <response code="404">Не нашел документ по id</response>
 835        /// <response code="400">Ошибка</response>
 836        /// <response code="204"></response>
 837        [HttpPost("{id}/DeclineClaim")]
 838        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 839        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 840        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 841        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 842        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 843        [Authorize(Roles = Role.SystemAdmin)]
 844        public async Task<IActionResult> DeclineClaim(long id)
 0845        {
 0846            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.claimDeclineShipment);
 0847            return NoContent();
 0848        }
 849        /// <summary>
 850        /// Подтверждение притензии по отгрузке
 851        /// </summary>
 852        /// <remarks>author: aabelentsov</remarks>
 853        /// <param name="id">Идентификатор документа</param>
 854        /// <returns></returns>
 855        /// <response code="404">Не нашел документ по id</response>
 856        /// <response code="400">Ошибка</response>
 857        /// <response code="204"></response>
 858        [HttpPost("{id}/AcceptClaim")]
 859        [SwaggerResponse(204, "Успешно", typeof(NoContentResult))]
 860        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 861        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 862        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 863        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 864        [Authorize(Roles = Role.SystemAdmin)]
 865        public async Task<IActionResult> AcceptClaim(long id)
 0866        {
 0867            await _movementStatusRouter.SetNextStatus(id, MovementStatusKeys.claimAcceptShipment);
 0868            return NoContent();
 0869        }
 870
 871        /// <summary>
 872        /// Удаление отгрузки
 873        /// </summary>
 874        /// <remarks>author: aabelentsov</remarks>
 875        /// <param name="id">Идентификатор документа</param>
 876        /// <returns></returns>
 877        [HttpDelete("{id}")]
 878        [SwaggerResponse(200, "Успешно", typeof(OkResult))]
 879        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 880        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 881        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 882        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 883        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator)]
 884        private async Task<IActionResult> DeleteShipment(long id)
 0885        {
 0886            if (!_authUserService.IsUserWholesaler() || !User.IsInRole(Role.SupplierOwner))
 0887                throw new ForbidException();
 0888            await _movementWorker.DeleteMovement(id);
 0889            return Ok();
 0890        }
 891
 892        /// <summary>
 893        /// Создание транзакции для оплаты (сделку) (холдирование средств)
 894        /// </summary>
 895        /// <remarks>author: aabelentsov</remarks>
 896        /// <param name="id">Номер документа</param>
 897        /// <returns></returns>
 898        [HttpPost("{id}/Payment")]
 899        [SwaggerResponse(200, "Успешно", typeof(OkResult))]
 900        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 901        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 902        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 903        [Authorize(Roles = Role.ShopOwner)]
 904        public async Task<IActionResult> CreateTransaction(long id)
 0905        {
 0906            await _walletPaymentService.CreateTransaction(id);
 0907            return Ok();
 0908        }
 909
 910        /// <summary>
 911        /// Добавить вложение к отгрузке
 912        /// </summary>
 913        /// <remarks>author: i.rebenok + a.belentsov</remarks>
 914        /// <param name="id">Номер документа</param>
 915        /// <param name="files">Вложения</param>
 916        /// <returns></returns>
 917        [HttpPost("{id}/Attachment")]
 918        [SwaggerResponse(200, "Успешно", typeof(UploadResultDTO))]
 919        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 920        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 921        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 922        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator + "," + Role.SystemAdmin)]
 923        public async Task<IActionResult> AddAttachment(long id, List<IFormFile> file)
 0924        {
 0925            if (file == null || file.Count == 0)
 0926            {
 0927                return BadRequest(new ErrorDTO { error = "Нет файлов для загрузки"});
 928            }
 0929            var result = await _movementWorker.AddAttachment(id, file);
 0930            return Ok(result);
 0931        }
 932
 933        /// <summary>
 934        /// Скачать вложение к отгрузке
 935        /// </summary>
 936        /// <remarks>author: i.rebenok + a.belentsov</remarks>
 937        /// <param name="id">Номер документа</param>
 938        /// <param name="attachmentsId">Список идентификаторов вложения для загрузки, через запятую - 1,2,3</param>
 939        /// <returns></returns>
 940        [HttpGet("{id}/Attachment")]
 941        [SwaggerResponse(200, "Успешно", typeof(File))]
 942        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 943        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 944        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 945        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator + "," + Role.SupplierSpec + "," + Role.Syste
 946             + "," + Role.ShopOwner + "," + Role.ShopMerchandiser + "," + Role.ShopSeller)]
 947        public async Task<IActionResult> DownloadAttachment(long id, string attachmentsId)
 948        {
 949            if (string.IsNullOrEmpty(attachmentsId))
 950                throw new ArgumentException("Укажите идентификатор для загрузки");
 951            var sep = attachmentsId?.Split(new char[] {','});
 0952            List<long> ids = sep.Select(d => Int64.Parse(d)).ToList();
 953            var result = await _movementWorker.DownloadAttachment(id, ids);
 954
 955            return File(result.Stream, result.ContentType, result.FileName);
 956        }
 957
 958        /// <summary>
 959        /// Удалить вложение у отгрузки
 960        /// </summary>
 961        /// <remarks>author: i.rebenok + a.belentsov</remarks>
 962        /// <param name="id">Номер документа</param>
 963        /// <param name="attachmentId">Идентификатор вложения для удаления</param>
 964        /// <returns></returns>
 965        [HttpDelete("{id}/Attachment")]
 966        [SwaggerResponse(200, "Успешно", typeof(OkResult))]
 967        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 968        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 969        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 970        [Authorize(Roles = Role.SupplierOwner + "," + Role.SupplierOperator)]
 971        public async Task<IActionResult> DeleteAttachment(long id, [FromBody]MovementAttachmentRemoveRequestDto requestD
 0972        {
 0973            await _movementWorker.DeleteAttachment(id, requestDto.AttachmentId);
 0974            return Ok();
 0975        }
 976
 977        /// <summary>
 978        /// Возвращает историю по отгрузке
 979        /// </summary>
 980        /// <remarks>author: irebenok</remarks>
 981        /// <param name="id">Идентификатор отгрузки</param>
 982        /// <returns></returns>
 983        [HttpGet("{id}/History")]
 984        [SwaggerResponse(200, "Успешно", typeof(List<MovementHistoryResponseDTO>))]
 985        [SwaggerResponse(400, "Ошибка", typeof(ErrorDTO))]
 986        [SwaggerResponse(403, "Ошибка прав доступа", typeof(ErrorDTO))]
 987        [SwaggerResponse(404, "Не найден документ", typeof(ErrorDTO))]
 988        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 989        [Authorize(Roles = Role.SystemAdmin)]
 990        public async Task<IActionResult> GetMovementHistory(long id)
 0991        {
 0992            var result = await _movementWorker.GetMovementHistory(id);
 0993            return Ok(result);
 0994        }
 995
 996        string getResponseParamUrl(long customerId, long receiverId, long supplierId, DateTimeOffset fromDate, DateTimeO
 0997        {
 0998            var param = "";
 0999            if (customerId != 0)
 01000                param += $"customerId={customerId}";
 01001            if (receiverId != 0)
 01002                param += $"&receiverId={receiverId}";
 01003            if (supplierId != 0)
 01004                param += $"&supplierId={supplierId}";
 01005            if (senderId != 0)
 01006                param += $"&senderId={senderId}";
 1007            //if (fromDate.HasValue)
 01008                param += $"&fromDate={fromDate.ToISOString()}";
 1009            //if (toDate.HasValue)
 01010                param += $"&toDate={toDate.ToISOString()}";
 01011            if (stateId != 0)
 01012                param += $"&stateId={stateId}";
 01013            if (statusId != 0)
 01014                param += $"&statusId={statusId}";
 01015            if (param.StartsWith("&"))
 01016                param = param.Trim(new char[] { '&' });
 01017            return param;
 01018        }
 1019    }
 1020}