コード例 #1
0
        /// <summary>
        /// Adds in transit status if most recent event was a departure
        /// </summary>
        /// <param name="stopData"></param>
        /// <param name="load"></param>
        /// <returns></returns>
        public async Task <LoadStatusInTransitData> AddInTransitStopStatus(LoadStatusStopData stopData, LoadEntity load)
        {
            var mostRecentStop = stopData?.Events?.OrderBy(x => x.StopNumber).LastOrDefault();

            if (mostRecentStop?.EventType == StopEventTypeEnum.Departure)
            {
                var mostRecentLoadStop = load?.LoadStops?.FirstOrDefault(_ => _.StopNbr == mostRecentStop.StopNumber);
                if (mostRecentLoadStop != null)
                {
                    var inTransitStopData = new LoadStatusInTransitData()
                    {
                        LoadId       = load.LoadId,
                        LocationTime = mostRecentStop.EventTime,
                        // https://kbxltrans.visualstudio.com/Suite/_workitems/edit/40298
                        Latitude  = mostRecentLoadStop.Latitude,
                        Longitude = mostRecentLoadStop.Longitude
                    };

                    await AddInTransitStatus(inTransitStopData);

                    return(inTransitStopData);
                }
            }

            return(null);
        }
コード例 #2
0
            public async Task PreventsFutureTimeForTimeZone()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = VALID_LOAD_ID,
                    Events = new List <LoadStatusStopEventData>
                    {
                        new LoadStatusStopEventData
                        {
                            StopNumber = 1,
                            EventTime  = new DateTimeOffset(DateTime.Now),//Assuming this is central time and Stop one is Pacific Time (Oregon)
                            EventType  = StopEventTypeEnum.Arrival
                        }
                    }
                };

                _carrierWebApiService.Setup(_ => _.Send <StopEventData>(It.IsAny <LoadStatusEvent <StopEventData> >()))
                .ReturnsAsync(new LoadStatusEvent <CarrierApiResponseMessages>
                {
                    MessageId   = Guid.Parse("44444444-4444-4444-4444-555555555555"),
                    MessageTime = new DateTimeOffset(new DateTime(2020, 2, 11, 12, 13, 14))
                });

                _svc = CreateService();

                var response = await _svc.AddStopStatuses(stopStatuses);

                response.IsSuccess.Should().BeFalse();
                AssertHasError(response, $"urn:root:Events:0:EventTime", "Status Date/Time must be in the past");
            }
コード例 #3
0
            public async Task Success()
            {
                var stopData = new LoadStatusStopData()
                {
                    Events = new List <LoadStatusStopEventData>()
                    {
                        new LoadStatusStopEventData()
                        {
                            StopNumber = 1,
                            EventType  = StopEventTypeEnum.Arrival
                        },
                        new LoadStatusStopEventData()
                        {
                            StopNumber = 2,
                            EventType  = StopEventTypeEnum.Departure,
                            EventTime  = DateTime.Now
                        }
                    }
                };

                var load = new LoadEntity()
                {
                    LoadId    = VALID_LOAD_ID,
                    LoadStops = new List <LoadStopEntity>()
                    {
                        new LoadStopEntity()
                        {
                            StopNbr   = 2,
                            Latitude  = 10,
                            Longitude = 20
                        },
                        new LoadStopEntity()
                        {
                            StopNbr   = 3,
                            Latitude  = 20,
                            Longitude = 30
                        }
                    }
                };

                _carrierWebApiService.Setup(_ => _.Send <InTransitLoadData>(It.IsAny <LoadStatusEvent <InTransitLoadData> >()))
                .ReturnsAsync(new LoadStatusEvent <CarrierApiResponseMessages>
                {
                    MessageId   = Guid.Parse("44444444-4444-4444-4444-555555555555"),
                    MessageTime = new DateTimeOffset(new DateTime(2020, 2, 11, 12, 13, 14))
                });
                _svc = CreateService();

                var response = await _svc.AddInTransitStopStatus(stopData, load);

                response.Should().NotBeNull();
                response.LoadId.Should().Be(load.LoadId);
                response.LocationTime.Should().BeSameDateAs(stopData.Events[1].EventTime.Value);
                response.Latitude.Should().Be(load.LoadStops[0].Latitude);
                response.Longitude.Should().Be(load.LoadStops[0].Longitude);
            }
コード例 #4
0
            public async Task SubmitsBillingLoadId()
            {
                var load = VALID_LOAD;

                load.PlatformPlusLoadId = "PLATFORM_PLUS_ID";
                load.LatestLoadTransaction.Claim.BillingLoadId = "BILLING_LOAD_ID";
                var loads = new List <LoadEntity> {
                    load
                };

                _dbBuilder = new MockDbBuilder();
                _db        = _dbBuilder
                             .WithLoads(loads)
                             .WithUsers(new List <UserEntity> {
                    VALID_CARRIER_USER
                })
                             .Build();

                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = VALID_LOAD_ID,
                    Events = new List <LoadStatusStopEventData>
                    {
                        new LoadStatusStopEventData
                        {
                            StopNumber = 1,
                            EventTime  = new DateTimeOffset(new DateTime(2020, 2, 11, 10, 0, 0)),
                            EventType  = StopEventTypeEnum.Arrival
                        }
                    }
                };

                _carrierWebApiService.Setup(_ => _.Send <StopEventData>(It.IsAny <LoadStatusEvent <StopEventData> >()))
                .ReturnsAsync(new LoadStatusEvent <CarrierApiResponseMessages>
                {
                    MessageId   = Guid.Parse("44444444-4444-4444-4444-555555555555"),
                    MessageTime = new DateTimeOffset(new DateTime(2020, 2, 11, 12, 13, 14))
                });

                _svc = CreateService();

                var response = await _svc.AddStopStatuses(stopStatuses);

                response.IsSuccess.Should().BeTrue();

                _carrierWebApiService.Verify(_ => _.Send <StopEventData>(It.Is <LoadStatusEvent <StopEventData> >(
                                                                             e => e.MessageType == "LoadStopEvent" &&
                                                                             e.ApiVersion == "1.1" &&
                                                                             e.Payload.LoadNumber == "BILLING_LOAD_ID" &&
                                                                             e.Payload.StopNbr == 1 &&
                                                                             e.Payload.StatusDateTime == "2020-02-11T10:00:00" &&
                                                                             e.Payload.IsLocalTime == true &&
                                                                             e.Payload.Scac == "TEST"
                                                                             )));
            }
コード例 #5
0
            public async Task LoadNotAcceptedOrPending()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = UNBOOKED_LOAD_ID
                };

                _svc = CreateService();

                Func <Task> action = async() => await _svc.AddStopStatuses(stopStatuses);

                (await action.Should().ThrowAsync <Exception>()).WithMessage("Load not accepted");
            }
コード例 #6
0
            public async Task LoadNotFound()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = INVALID_LOAD_ID
                };

                _svc = CreateService();

                Func <Task> action = async() => await _svc.AddStopStatuses(stopStatuses);

                (await action.Should().ThrowAsync <Exception>()).WithMessage("Load not found");
            }
コード例 #7
0
            public async Task UserHasWrongPrimaryScac()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = VALID_LOAD_ID
                };

                _userContext.SetupGet(_ => _.UserId).Returns(INVALID_USER_ID);

                _svc = CreateService();

                Func <Task> action = async() => await _svc.AddStopStatuses(stopStatuses);

                (await action.Should().ThrowAsync <Exception>()).WithMessage("Load not found");
            }
コード例 #8
0
            public async Task MostRecentStopIsNotDeparture()
            {
                var stopData = new LoadStatusStopData()
                {
                    Events = new List <LoadStatusStopEventData>()
                    {
                        new LoadStatusStopEventData()
                        {
                            StopNumber = 1,
                            EventType  = StopEventTypeEnum.Departure
                        },
                        new LoadStatusStopEventData()
                        {
                            StopNumber = 2,
                            EventType  = StopEventTypeEnum.Arrival
                        }
                    }
                };

                var load = new LoadEntity()
                {
                    LoadId    = VALID_LOAD_ID,
                    LoadStops = new List <LoadStopEntity>()
                    {
                        new LoadStopEntity()
                        {
                            StopNbr   = 2,
                            Latitude  = 10,
                            Longitude = 20
                        },
                        new LoadStopEntity()
                        {
                            StopNbr   = 3,
                            Latitude  = 20,
                            Longitude = 30
                        }
                    }
                };

                _svc = CreateService();

                (await _svc.AddInTransitStopStatus(stopData, load)).Should().BeNull();
            }
コード例 #9
0
        public async Task <IActionResult> PostStopEventStatus([FromBody] LoadStatusStopData stopData)
        {
            var response = await _loadStatusTransactionService.AddStopStatuses(stopData);

            if (!response.IsSuccess)
            {
                var problemDetails = new ValidationProblemDetails(response.ModelState)
                {
                    Title    = "Send Stop Statuses",
                    Detail   = "One or more errors occurred when trying to update the Stop statuses of the load.  See form for error details",
                    Status   = (int)HttpStatusCode.BadRequest,
                    Instance = $"urn:kbxl:error:{Guid.NewGuid()}"
                };
                return(BadRequest(problemDetails));
            }

            var data = await _loadStatusTransactionService.GetLatestStatus(stopData.LoadId);

            return(Success(data));
        }
コード例 #10
0
            public async Task UserDoesNotHaveAction()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = VALID_LOAD_ID
                };

                _securityService.Setup(_ => _.UserHasActionAsync(It.IsAny <string[]>())).ReturnsAsync(false);

                _svc = CreateService();

                Func <Task> action = async() => await _svc.AddStopStatuses(stopStatuses);

                await action.Should().ThrowAsync <Exception>();

                _securityService.Verify(_ => _.UserHasActionAsync(It.Is <string[]>(actions =>
                                                                                   actions != null && actions.Length == 1 &&
                                                                                   actions[0] == SecurityActions.Loadshop_Ui_My_Loads_Status_Update
                                                                                   )));
            }
コード例 #11
0
            public async Task SubmitsCorrectInTransitTime()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = VALID_LOAD_ID,
                    Events = new List <LoadStatusStopEventData>
                    {
                        new LoadStatusStopEventData
                        {
                            StopNumber = 1,
                            EventTime  = new DateTimeOffset(new DateTime(2020, 2, 11, 10, 0, 0)),
                            EventType  = StopEventTypeEnum.Arrival
                        }
                    }
                };

                _carrierWebApiService.Setup(_ => _.Send <StopEventData>(It.IsAny <LoadStatusEvent <StopEventData> >()))
                .ReturnsAsync(new LoadStatusEvent <CarrierApiResponseMessages>
                {
                    MessageId   = Guid.Parse("44444444-4444-4444-4444-555555555555"),
                    MessageTime = new DateTimeOffset(new DateTime(2020, 2, 11, 12, 13, 14))
                });

                _svc = CreateService();

                var response = await _svc.AddStopStatuses(stopStatuses);

                response.IsSuccess.Should().BeTrue();

                _carrierWebApiService.Verify(_ => _.Send <StopEventData>(It.Is <LoadStatusEvent <StopEventData> >(
                                                                             e => e.MessageType == "LoadStopEvent" &&
                                                                             e.ApiVersion == "1.1" &&
                                                                             e.Payload.LoadNumber == VALID_REF_LOAD_ID &&
                                                                             e.Payload.StopNbr == 1 &&
                                                                             e.Payload.StatusDateTime == "2020-02-11T10:00:00" &&
                                                                             e.Payload.IsLocalTime == true &&
                                                                             e.Payload.Scac == "TEST"
                                                                             )));
            }
コード例 #12
0
            public async Task StopDoesntExist()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = VALID_LOAD_ID,
                    Events = new List <LoadStatusStopEventData>
                    {
                        new LoadStatusStopEventData
                        {
                            StopNumber = 3,
                            EventTime  = new DateTimeOffset(new DateTime(2020, 2, 11, 10, 0, 0)),
                            EventType  = StopEventTypeEnum.Arrival
                        }
                    }
                };

                _svc = CreateService();

                var response = await _svc.AddStopStatuses(stopStatuses);

                response.IsSuccess.Should().BeFalse();
                AssertHasError(response, $"urn:root:Events:0", "Stop number does not exist");
            }
コード例 #13
0
            public async Task LocationTimeIsNull()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = VALID_LOAD_ID,
                    Events = new List <LoadStatusStopEventData>
                    {
                        new LoadStatusStopEventData
                        {
                            StopNumber = 1,
                            EventTime  = null,
                            EventType  = StopEventTypeEnum.Arrival
                        }
                    }
                };

                _svc = CreateService();

                var response = await _svc.AddStopStatuses(stopStatuses);

                response.IsSuccess.Should().BeFalse();
                AssertHasError(response, $"urn:root:Events:0:EventTime", "Status Date/Time is required");
            }
コード例 #14
0
            public async Task AddLoadStatusTransaction()
            {
                var stopStatuses = new LoadStatusStopData
                {
                    LoadId = VALID_LOAD_ID,
                    Events = new List <LoadStatusStopEventData>
                    {
                        new LoadStatusStopEventData
                        {
                            StopNumber = 1,
                            EventTime  = new DateTimeOffset(new DateTime(2020, 2, 11, 10, 0, 0)),
                            EventType  = StopEventTypeEnum.Arrival
                        }
                    }
                };

                _carrierWebApiService.Setup(_ => _.Send <StopEventData>(It.IsAny <LoadStatusEvent <StopEventData> >()))
                .ReturnsAsync(new LoadStatusEvent <CarrierApiResponseMessages>
                {
                    MessageId   = Guid.Parse("44444444-4444-4444-4444-555555555555"),
                    MessageTime = new DateTimeOffset(new DateTime(2020, 2, 11, 12, 13, 14))
                });

                _svc = CreateService();

                var response = await _svc.AddStopStatuses(stopStatuses);

                response.IsSuccess.Should().BeTrue();

                _dbBuilder.MockLoadStatusTransactions.Verify(_ => _.Add(It.Is <LoadStatusTransactionEntity>(x =>
                                                                                                            x.MessageId == Guid.Parse("44444444-4444-4444-4444-555555555555") &&
                                                                                                            x.MessageTime == new DateTimeOffset(new DateTime(2020, 2, 11, 12, 13, 14)) &&
                                                                                                            x.LoadId == VALID_LOAD_ID
                                                                                                            //can't verity the TransactionDtTm since it's using DateTime.Now
                                                                                                            )));
            }
コード例 #15
0
        public async Task <BaseServiceResponse> AddStopStatuses(LoadStatusStopData stopData)
        {
            await _securityService.GuardActionAsync(SecurityActions.Loadshop_Ui_My_Loads_Status_Update);

            var(load, scac) = await GetLoadAndScac(stopData.LoadId, includeStops : true);

            var response = new BaseServiceResponse();

            if (stopData.Events?.Any() != true)
            {
                response.AddError($"urn:root:{nameof(LoadStatusStopData.Events)}:0:{nameof(LoadStatusStopEventData.EventTime)}", "Status Date/Time is required");
            }

            for (int i = 0; i < stopData.Events.Count; i++)
            {
                var stopEvent = stopData.Events[i];

                var stop     = load.LoadStops?.FirstOrDefault(_ => _.StopNbr == stopEvent.StopNumber);
                var inFuture = false;

                if (stop == null)
                {
                    response.AddError($"urn:root:{nameof(LoadStatusStopData.Events)}:{i}", "Stop number does not exist");
                }
                else
                {
                    //Adjust the time if it's close to current
                    (stopEvent.EventTime, inFuture) = AdjustLocationTime(stopData.Events[i].EventTime, stop?.Latitude, stop?.Longitude);

                    if (stopEvent.EventTime == null)
                    {
                        response.AddError($"urn:root:{nameof(LoadStatusStopData.Events)}:{i}:{nameof(LoadStatusStopEventData.EventTime)}", "Status Date/Time is required");
                    }
                    else if (inFuture)
                    {
                        response.AddError($"urn:root:{nameof(LoadStatusStopData.Events)}:{i}:{nameof(LoadStatusStopEventData.EventTime)}", "Status Date/Time must be in the past");
                    }
                }
            }

            if (!response.IsSuccess)
            {
                return(response);
            }


            foreach (var stopEvent in stopData.Events)
            {
                var currentTime = DateTimeOffset.UtcNow;
                var lst         = new LoadStatusTransactionEntity
                {
                    LoadId          = load.LoadId,
                    TransactionDtTm = currentTime.DateTime//this may not be needed anymore if we can send the MessageTime
                };

                var eventResponse = await _carrierWebAPIService.Send(new LoadStatusEvent <StopEventData>
                {
                    MessageType = "LoadStopEvent",
                    MessageId   = Guid.NewGuid(),
                    MessageTime = DateTimeOffset.Now,
                    ApiVersion  = "1.1",
                    Payload     = new StopEventData
                    {
                        LoadNumber     = load.LatestLoadTransaction.Claim.BillingLoadId ?? load.PlatformPlusLoadId ?? load.ReferenceLoadId,
                        StopNbr        = stopEvent.StopNumber,
                        StatusDateTime = stopEvent.EventTime?.ToString("yyyy-MM-ddTHH:mm:ss"),
                        StatusType     = stopEvent.EventType.ToString(),
                        IsLocalTime    = true, //Always true if in local status time
                        Scac           = scac
                    }
                });

                lst.MessageId   = eventResponse.MessageId;
                lst.MessageTime = eventResponse.MessageTime;
                _context.LoadStatusTransactions.Add(lst);
                await _context.SaveChangesAsync(_userContext.UserName);
            }

            await AddInTransitStopStatus(stopData, load);

            return(new BaseServiceResponse());
        }