< Summary

Class:SVETA.Api.Services.Implements.MovementStatusChecker
Assembly:SVETA.Api
File(s):/opt/dev/sveta_api_build/SVETA.Api/Services/Implements/MovementStatusChecker.cs
Covered lines:0
Uncovered lines:128
Coverable lines:128
Total lines:223
Line coverage:0% (0 of 128)
Covered branches:0
Total branches:66
Branch coverage:0% (0 of 66)

Metrics

MethodLine coverage Branch coverage
.ctor(...)0%100%
DoWork()0%0%
CheckWaitTime()0%0%
ExecuteAsync()0%0%
StopAsync()0%100%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Globalization;
 4using System.Linq;
 5using System.Runtime.InteropServices;
 6using System.Security.Claims;
 7using System.Threading;
 8using System.Threading.Tasks;
 9using Microsoft.EntityFrameworkCore;
 10using Microsoft.Extensions.DependencyInjection;
 11using Microsoft.Extensions.Hosting;
 12using Microsoft.Extensions.Logging;
 13using Org.BouncyCastle.Asn1.Cms;
 14using SVETA.Api.Services.Interfaces;
 15using WinSolutions.Sveta.Server.Data.DataModel.Contexts;
 16using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 17using WinSolutions.Sveta.Server.Services.Interfaces;
 18using WinSolutions.Sveta.Server.Data.DataModel.Kinds;
 19using WinSolutions.Sveta.Common;
 20using SVETA.Api.Helpers;
 21
 22namespace SVETA.Api.Services.Implements
 23{
 24    public class MovementStatusChecker: BackgroundService
 25    {
 26        private readonly IServiceProvider _service;
 27        private readonly ILogger<MovementStatusChecker> _logger;
 28
 029        public MovementStatusChecker(IServiceProvider service, ILogger<MovementStatusChecker> logger)
 030        {
 031            _service = service;
 032            _logger = logger;
 033        }
 34
 35        private async Task DoWork()
 036        {
 037            using (var scope = _service.CreateScope())
 038            {
 039                var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
 040                var emailService = scope.ServiceProvider.GetRequiredService<IEmailService>();
 041                var contrService = scope.ServiceProvider.GetRequiredService<IContragentService>();
 042                var authUserService = scope.ServiceProvider.GetRequiredService<IAuthenticationService>();
 043                authUserService.SwitchToServiceUser();
 044                var journalService = scope.ServiceProvider.GetRequiredService<IMovementStatusJournalService>();
 45
 046                var movementRouteService = scope.ServiceProvider.GetRequiredService<IMovementRouteService>();
 047                var movementStatusRouter = scope.ServiceProvider.GetRequiredService<IMovementStatusRouter>();
 048                var workScheduleService = scope.ServiceProvider.GetRequiredService<IWorkScheduleService>();
 49
 050                var activeJournals = await journalService.GetAllActive();
 051                var routes = await movementRouteService.GetRoutes();
 052                var jobLogger = scope.ServiceProvider.GetRequiredService<IJobService>();
 053                await jobLogger.Create(new JobLogger
 054                {
 055                    JobName = nameof(MovementStatusChecker),
 056                    LogLevel = JobLogLevel.info,
 057                    Log = $"Старт работы джоба. Количество записей для обработки: {activeJournals.Count}"
 058                });
 059                if (activeJournals != null && activeJournals.Count > 0)
 060                {
 61                    try
 062                    {
 063                        for (int i = 0; i < activeJournals.Count; i++)
 064                        {
 065                            var record = activeJournals[i];
 066                            switch (activeJournals[i].Movement.MovementType.Id)
 67                            {
 68                                // Заявки
 69                                case (long)MovementKind.Order:
 070                                    {
 071                                        switch (activeJournals[i].StatusCurrent.Id)
 72                                        {
 73                                            // В очереди на обработку
 74                                            case (long)MovementsStatus.InQueue:
 75                                            case (long)MovementsStatus.InProgress:
 076                                                {
 77                                                    //Обработка на время ожидания
 078                                                    if (await CheckWaitTime(record, (long)MovementsStatus.InQueue, route
 079                                                    {
 80
 081                                                        string comment = $"Автоматический отказ в выполнении из статуса 
 082                                                                         $" по истечении срока ожидания {DateTime.UtcNow
 083                                                                         $"в {DateTime.UtcNow.ToMoscowTime().ToString("H
 084                                                                         $" ({DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm
 085                                                        await movementStatusRouter.SetNextStatus(record.Movement.Id, "Au
 086                                                            comment);
 087                                                    }
 088                                                    break;
 89                                                }
 90                                           /* case (long)MovementsStatus.PaymentAwaiting:
 91                                            case (long)MovementsStatus.OrderDraft:
 92                                                {
 93                                                    if (await workScheduleService.CalcPeriodFromSchedule((activeJournals
 94                                                        activeJournals[i].Movement.ModificationDateTime.Value
 95                                                        : activeJournals[i].Movement.CreationDateTime), DateTime.UtcNow)
 96                                                        await emailService.Create($"Напоминание по заявке {activeJournal
 97                                                            $"находится в статусе {activeJournals[i].StatusCurrent.Name}
 98                                                    break;
 99                                                }*/
 0100                                        };
 0101                                        break;
 102                                    }
 103                                // Отгрузки
 104                                case (long)MovementKind.Shipment:
 0105                                    {
 0106                                        switch (activeJournals[i].StatusCurrent.Id)
 107                                        {
 108                                            // Ожидание оплаты
 109                                            case (long)MovementsStatus.PaymentAwaiting:
 110                                            case (long)MovementsStatus.Picking:
 111                                            case (long)MovementsStatus.Correction:
 112                                            case (long)MovementsStatus.ReadyForShipment:
 0113                                                {
 0114                                                    if (await CheckWaitTime(record, record.StatusCurrent.Id, routes, wor
 0115                                                    {
 0116                                                        string comment = $"Автоматический отказ в выполнении из статуса 
 0117                                                                         $"\"{record.StatusCurrent.Name}\" по истечении 
 0118                                                                         $"срока ожидания {DateTime.UtcNow.ToMoscowTime(
 0119                                                                         $" в {DateTime.UtcNow.ToMoscowTime().ToString("
 0120                                                                         $" по московскому времени ({DateTime.UtcNow.ToS
 0121                                                        await movementStatusRouter.SetNextStatus(record.Movement.Id, "Au
 0122                                                            comment);
 0123                                                    }
 124
 0125                                                    break;
 126                                                }
 127                                            case (long)MovementsStatus.Shipped:
 0128                                                {
 0129                                                    if (await CheckWaitTime(record, record.StatusCurrent.Id, routes, wor
 0130                                                    {
 0131                                                        string comment = $"Автоматическое принятие отгрузки из статуса \
 0132                                                                         $"{record.StatusCurrent.Name}\" {DateTime.UtcNo
 0133                                                                         $" в {DateTime.UtcNow.ToMoscowTime().ToString("
 0134                                                                         $"по московскому времени ({DateTime.UtcNow.ToSt
 0135                                                                         $" по причине истечения срока ожидания";
 0136                                                        await movementStatusRouter.SetNextStatus(record.Movement.Id, "Au
 0137                                                            comment);
 0138                                                    }
 0139                                                    break;
 140                                                }
 141                                            case (long)MovementsStatus.ClaimInProgress:
 0142                                                {
 0143                                                    if (await CheckWaitTime(record, record.StatusCurrent.Id, routes, wor
 0144                                                    {
 0145                                                        string comment = $"Автоматический перевод в статус претензия при
 0146                                                                         $" из статуса \"{record.StatusCurrent.Name}\"  
 0147                                                                         $"{DateTime.UtcNow.ToMoscowTime().ToString("yyy
 0148                                                                         $" в {DateTime.UtcNow.ToMoscowTime().ToString("
 0149                                                                         $"по московскому времени ({DateTime.UtcNow.ToSt
 0150                                                        await movementStatusRouter.SetNextStatus(record.Movement.Id, "Au
 0151                                                            comment);
 0152                                                    }
 0153                                                    break;
 154                                                }
 155                                        }
 0156                                        break;
 157                                    }
 158                            }
 0159                        }
 0160                    }
 0161                    catch (Exception e)
 0162                    {
 0163                        await jobLogger.Create(new JobLogger
 0164                        {
 0165                            JobName = nameof(MovementStatusChecker),
 0166                            LogLevel = JobLogLevel.error,
 0167                            Log = e.Message
 0168                        });
 0169                        _logger.LogError(e.Message, e);
 0170                    }
 0171                }
 0172            }
 0173        }
 174        /// <summary>
 175        /// Проверяет вышло ли рабочее время ожидания с момента вставки записи в таблицу журнала
 176        /// </summary>
 177        /// <param name="record">Запись в журнале</param>
 178        /// <param name="statusId">Текущий статус</param>
 179        /// <param name="routes">список с маршрутами</param>
 180        /// <param name="workScheduleService">Сервис производственного календаря</param>
 181        /// <returns>True - время вышло, Fals - время не вышло</returns>
 182        private async Task<bool> CheckWaitTime(MovementStatusJournal record,
 183            long statusId,
 184            List<MovementStatusRoute> routes,
 185            IWorkScheduleService workScheduleService)
 0186        {
 0187            var dateTo = DateTime.UtcNow;
 188
 0189            var diff = await workScheduleService.CalcPeriodFromSchedule(record.CreationDateTime, dateTo, record.Movement
 0190            double conformWaitTime = routes.FirstOrDefault(d => d.StatusCurrent.Id == statusId
 0191                && d.WarehouseId == record.Movement.Sender.Id
 0192                && d.RouteKey.ToLower().Equals(MovementStatusKeys.autoReject.ToLower()))?.Hour ?? 0;
 193
 0194            _logger.LogError($"Документ {record.Movement.Id} Проверка времени вхождения dateFrom: {record.CreationDateTi
 195
 0196            return conformWaitTime != 0 && diff > (conformWaitTime * 60);
 0197        }
 198        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
 0199        {
 0200            _logger.LogInformation($"Movement status checker is starting.");
 201
 0202            stoppingToken.Register(() =>
 0203                _logger.LogInformation($"Movement status checker background task is stopping."));
 204
 0205            while (!stoppingToken.IsCancellationRequested)
 0206            {
 0207                _logger.LogInformation($"Movement status checker task doing background work.");
 0208                await DoWork();
 209                // Запускаем раз в 8 часов
 0210                await Task.Delay(1000 * 60 * 5, stoppingToken);
 0211            }
 212
 0213            _logger.LogInformation($"Movement status checker background task is stopping.");
 0214        }
 215        public override async Task StopAsync(CancellationToken stoppingToken)
 0216        {
 0217            _logger.LogInformation(
 0218                "Movement status checker Service Hosted Service is stopping.");
 219
 0220            await Task.CompletedTask;
 0221        }
 222    }
 223}