public async Task <ShippingLoadData> RemoveLoad(Guid loadId, string username) { _securityService.GuardAction(SecurityActions.Loadshop_Ui_Shopit_Load_Manual_Remove); var updateLoad = await _context.Loads .Include(x => x.LoadTransactions) .Include(x => x.CarrierScacs) .Include(x => x.PostedLoadCarrierGroups) .SingleOrDefaultAsync(x => x.LoadId == loadId); if (updateLoad == null) { throw new Exception("Load not found"); } if (!AuthorizedForCustomer(updateLoad.CustomerId)) { throw new UnauthorizedAccessException($"User is not authorized for customer: {updateLoad.CustomerId}"); } if (updateLoad.LoadTransactions == null || updateLoad.LoadTransactions.Count == 0) { throw new Exception($"Load may not be removed - Load {loadId} has no transactions"); } var loadTrans = updateLoad.LoadTransactions .OrderByDescending(x => x.CreateDtTm) .ToList(); if (!_transToProcess.Contains(loadTrans[0].TransactionTypeId)) { throw new Exception("Load may not be removed - not an active Load"); } string initialState = GetLoadInitialState(loadTrans); if (string.IsNullOrWhiteSpace(initialState) || !_initialTransStates.Contains(loadTrans[0].TransactionTypeId)) { var transaction = new LoadTransactionEntity() { LoadId = updateLoad.LoadId, TransactionTypeId = string.IsNullOrWhiteSpace(initialState) ? TransactionTypes.PendingAdd : initialState, CreateDtTm = _dateTime.Now // to support unit testing }; updateLoad.LoadTransactions.Add(transaction); /** * https://kbxltrans.visualstudio.com/Suite/_workitems/edit/38578 * Delete all LoadCarrierScacs associated with this Load */ _context.LoadCarrierScacs.RemoveRange(updateLoad.CarrierScacs); _context.PostedLoadCarrierGroups.RemoveRange(updateLoad.PostedLoadCarrierGroups); _context.Loads.Update(updateLoad); await _context.SaveChangesAsync(username); } return(_mapper.Map <ShippingLoadData>(updateLoad)); }
public async Task <UserLaneData> CreateLaneAsync(UserLaneData lane, Guid identUserId, string username) { _securityService.GuardAction(SecurityActions.Loadshop_Ui_Profile_Favorites_Add_Edit); ConvertStatesToAbbreviations(lane); ValidateUserLane(lane); var dbLane = await _context.UserLanes.SingleOrDefaultAsync(x => x.UserLaneId.ToString() == lane.UserLaneId); if (dbLane != null) { throw new Exception($"User Lane already exists"); } if (lane.EquipmentIds?.Count() == 0) { throw new Exception("Must have at least on equipment type selected"); } var user = await _context.Users.SingleOrDefaultAsync(x => x.IdentUserId == identUserId); if (user == null) { throw new Exception("Invalid userId"); } lane.UserLaneId = Guid.NewGuid().ToString(); lane.UserId = user.UserId.ToString(); dbLane = _mapper.Map <UserLaneEntity>(lane); foreach (var laneNotification in lane.UserLaneMessageTypes) { if (laneNotification.Selected) { var dbLaneNotification = _mapper.Map <UserLaneMessageTypeEntity>(laneNotification); dbLane.UserLaneMessageTypes.Add(dbLaneNotification); } } if (dbLane.UserLaneEquipments == null) { dbLane.UserLaneEquipments = new List <UserLaneEquipmentEntity>(); } foreach (var equipment in lane.EquipmentIds) { var e = new UserLaneEquipmentEntity() { EquipmentId = equipment }; dbLane.UserLaneEquipments.Add(e); } _context.UserLanes.Add(dbLane); await _context.SaveChangesAsync(username); return(await GetSavedLaneAsync(dbLane.UserLaneId)); }
public async Task <SaveSpecialInstructionResponse> CreateSpecialInstructionAsync(SpecialInstructionData instruction, string username) { var response = new SaveSpecialInstructionResponse(); if (instruction == null) { response.ModelState.AddModelError($"{ErrorPrefix}", "Special Instruction is requred"); return(response); } ConvertStatesToAbbreviations(instruction); if (instruction.SpecialInstructionId > 0) { response.ModelState.AddModelError($"{ErrorPrefix}", "Special Instruction should not have an Id assigned when creating."); return(response); } var validationErrorMessage = ValidateSpecialInstruction(instruction); if (!string.IsNullOrWhiteSpace(validationErrorMessage)) { response.ModelState.AddModelError($"{ErrorPrefix}", validationErrorMessage); return(response); } instruction.Comments = _htmlSanitizer.Sanitize(instruction.Comments); var dbGroup = _mapper.Map <SpecialInstructionEntity>(instruction); //Map Equipment Types dbGroup.SpecialInstructionEquipment = new List <SpecialInstructionEquipmentEntity>(); dbGroup.SpecialInstructionEquipment.MapList(instruction.SpecialInstructionEquipment, lcgeEntity => lcgeEntity.SpecialInstructionEquipmentId, lcgeData => lcgeData.SpecialInstructionEquipmentId, _mapper); GuardCustomer(dbGroup.CustomerId); var dup = await CheckIfDuplicateExists(dbGroup); if (dup) { response.ModelState.AddModelError($"{ErrorPrefix}", GetSpecialInstructionsDupErrorMessage(instruction)); return(response); } _context.SpecialInstructions.Add(dbGroup); await _context.SaveChangesAsync(username); response.SpecialInstructionData = await GetSpecialInstructionAsync(dbGroup.SpecialInstructionId); return(response); }
public async Task <GenericResponse <decimal?> > GetSmartSpotQuoteAsync(RecaptchaRequest <LoadshopSmartSpotQuoteRequest> request) { await _recaptchaService.ValidateToken(request); AssertConfig(); var response = new GenericResponse <decimal?>(); var awsModel = await MapFromLoadshopSmartSpotQuoteRequest(request.Data, response); if (!response.IsSuccess) { return(response); } response.Data = await RequestQuoteFromAWS(awsModel); _db.Add(new SmartSpotPriceQuoteLogEntity { SmartSpotPriceQuoteLogId = Guid.NewGuid(), Miles = awsModel.DirectMiles, Weight = awsModel.Weight, EquipmentId = awsModel.EquipmentId, OrigState = awsModel.OrigState, Orig3Zip = awsModel.O3Zip, DestState = awsModel.DestState, Dest3Zip = awsModel.D3Zip, PkupDate = awsModel.PkupDate, SmartSpotPrice = response.Data ?? 0, UserId = _userContext.UserId }); await _db.SaveChangesAsync(_userContext.UserName); return(response); }
public async Task AddRatingQuestionAnswer(RatingQuestionAnswerData ratingQuestionAnswer, bool saveChanges = false) { if (ratingQuestionAnswer.RatingQuestionId == null || ratingQuestionAnswer.RatingQuestionId == Guid.Empty) { throw new ValidationException("Answer must have a question"); } if (!ratingQuestionAnswer.LoadId.HasValue) { throw new ValidationException("Answer must have a load attached"); } if (!ratingQuestionAnswer.LoadClaimId.HasValue) { throw new ValidationException("Answer must be tied to a load claim"); } var entity = _mapper.Map <RatingQuestionAnswerEntity>(ratingQuestionAnswer); _context.RatingQuestionAnswers.Add(entity); if (saveChanges) { await _context.SaveChangesAsync(); } }
public async Task UserAgreement() { // check if its the latest agreement var latest = await GetLatestAgreementDocument(AgreementDocumentTypes.TermsAndPrivacy); var user = await context.Users.FirstOrDefaultAsync(x => x.IdentUserId == userContext.UserId); // record user agreement var entity = new UserAgreementDocumentEntity() { UserId = user.UserId, AgreementDocumentId = latest.AgreementDocumentId, AgreementDtTm = DateTime.Now, CreateBy = userContext.UserName, LastChgBy = userContext.UserName, CreateDtTm = DateTime.Now, LastChgDtTm = DateTime.Now }; context.UserAgreements.Add(entity); await context.SaveChangesAsync(); }
/// <summary> /// Uploads a document to the KBX Document Service and stores metadata in Loadshop /// </summary> /// <param name="uploadPayload"></param> /// <returns></returns> public async Task <LoadDocumentMetadata> UploadDocument(LoadDocumentUploadData uploadPayload) { securityService.GuardAction(SecurityActions.Loadshop_Ui_Carrier_MyLoads_Documents_Attach); if (uploadPayload.LoadDocumentType == null || uploadPayload.LoadDocumentType.Id < 1) { throw new ValidationException("Invalid load document type"); } var load = await context.Loads.AsNoTracking().FirstOrDefaultAsync(x => x.LoadId == uploadPayload.LoadId); if (load == null) { throw new ValidationException("Load not found"); } var billingLoadId = await context.LoadTransactions.AsNoTracking() .Include(x => x.Claim) .Where(x => x.TransactionTypeId == TransactionTypes.Accepted) .Where(x => x.LoadId == load.LoadId) .Select(x => x.Claim.BillingLoadId) .FirstOrDefaultAsync(); // copy stream to request var stream = new FileMemoryStream(); await uploadPayload.File.CopyToAsync(stream); // reset position to ensure http request sends payload stream.Position = 0; stream.FileName = uploadPayload.File.FileName; stream.ContentDisposition = uploadPayload.File.ContentDisposition; stream.ContentType = uploadPayload.File.ContentType; // we hold all metadata in loadshop; however we will include some fields in case TOPS needs to query anything from there in the future var request = new DocumentService.SDK.Version.V1.Model.DocumentCreate() { Properties = new List <DocPropertyData>() { new DocPropertyData() { PropertyValue = load.LoadId.ToString(), PropertyName = DocumentServiceConstants.Property_Name_LoadshopLoadId }, new DocPropertyData() { PropertyValue = load.PlatformPlusLoadId?.ToString(), PropertyName = DocumentServiceConstants.Property_Name_PlatformPlusLoadId }, new DocPropertyData() { PropertyValue = load.ReferenceLoadId?.ToString(), PropertyName = DocumentServiceConstants.Property_Name_ReferenceLoadId }, new DocPropertyData() { PropertyValue = billingLoadId, PropertyName = DocumentServiceConstants.Property_Name_BillingLoadId } }, DocTypeId = uploadPayload.LoadDocumentType.Id, CreatedBy = userContext.UserName, CreatedDateTime = DateTime.Now, DocumentFile = stream }; try { // upload file to document API var uploadResult = await documentApiClient.CreateDocument(request); if (uploadResult.Status.Equals("Error", StringComparison.CurrentCultureIgnoreCase)) { throw new Exception($"Error while upload document to Document Service: {uploadResult.Result}"); } var entity = new LoadDocumentEntity() { LoadDocumentId = Guid.NewGuid(), DocumentServiceDocHeaderId = uploadResult.ResultData.DocHeaderId.Value, DocumentServiceDocContentId = uploadResult.ResultData.DocContentId.Value, DocumentServiceDocumentType = uploadPayload.LoadDocumentType.Id, FileName = uploadPayload.File.FileName, Comment = uploadPayload.Comment, LoadId = load.LoadId, CreateBy = userContext.UserName, CreateDtTm = DateTime.Now, LastChgBy = userContext.UserName, LastChgDtTm = DateTime.Now }; // add the new entity and in order for the DB to generate the doc id, use that to pass to the document service context.LoadDocuments.Add(entity); await context.SaveChangesAsync(); return(mapper.Map <LoadDocumentMetadata>(entity)); } catch (Exception e) { // if any errors occured, we dont want to show the record in loadshop, so remove the attachment record and return error logger.LogError($"Error while uploading document: {e.Message}", e); } return(null); }
public async Task <BaseServiceResponse> AddInTransitStatus(LoadStatusInTransitData inTransitData) { await _securityService.GuardActionAsync(SecurityActions.Loadshop_Ui_My_Loads_Status_Update); var(load, scac) = await GetLoadAndScac(inTransitData.LoadId, includeStops : false); //Adjust the time if it's close to current bool inFuture; (inTransitData.LocationTime, inFuture) = AdjustLocationTime(inTransitData.LocationTime, inTransitData.Latitude, inTransitData.Longitude); var response = new BaseServiceResponse(); if (inTransitData.LocationTime == null) { response.AddError($"urn:root:{nameof(LoadStatusInTransitData.LocationTime)}", "Status Date/Time is required"); } else if (inFuture) { response.AddError($"urn:root:{nameof(LoadStatusInTransitData.LocationTime)}", "Status Date/Time must be in the past"); } if (inTransitData.Latitude == null) { response.AddError($"urn:root:{nameof(LoadStatusInTransitData.Latitude)}", "Location is required"); } else if (inTransitData.Longitude == null) { response.AddError($"urn:root:{nameof(LoadStatusInTransitData.Longitude)}", "Location is required"); } if (!response.IsSuccess) { return(response); } 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 <InTransitLoadData> { MessageType = "LoadLocation", MessageId = Guid.NewGuid(), MessageTime = DateTimeOffset.Now, ApiVersion = "1.1", Payload = new InTransitLoadData { Loads = new InTransitEventData[] { new InTransitEventData { LoadNumber = load.LatestLoadTransaction.Claim.BillingLoadId ?? load.PlatformPlusLoadId ?? load.ReferenceLoadId, Latitude = inTransitData.Latitude.Value, Longitude = inTransitData.Longitude.Value, LocationTime = inTransitData.LocationTime?.ToString("yyyy-MM-ddTHH:mm:ss"), 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); return(response); }
public async Task <UserProfileData> GetUserProfileAsync(Guid identUserId) { var user = await _context.Users .Include(u => u.PrimaryScacEntity.Carrier) .Include(x => x.UserNotifications) .ThenInclude(x => x.MessageType) .Include(u => u.UserShippers) .ThenInclude(userShipper => userShipper.Customer) .Include(u => u.PrimaryCustomer) .SingleOrDefaultAsync(x => x.IdentUserId == identUserId); if (user == null) { // Throw exception so we can catch it and add the user throw new EntityNotFoundException($"UserProfile not found for id {identUserId}"); } var userProfile = _mapper.Map <UserProfileData>(user); // Add missing notification types the user does not have set yet var messageTypes = await _context.MessageTypes.Where(x => x.MessageTypeId != MessageTypeConstants.Email_SingleCarrierScac).ToListAsync(); foreach (var messageType in messageTypes) { var userMessageyTypeExists = userProfile.UserNotifications.Any(x => x.MessageTypeId.Equals(messageType.MessageTypeId, StringComparison.OrdinalIgnoreCase)); if (userMessageyTypeExists) { continue; } if (messageType.MessageTypeId.Equals(MessageTypeConstants.Email)) { // add a record using the user's identity email as a default var entity = new UserNotificationEntity() { MessageTypeId = MessageTypeConstants.Email, UserId = user.UserId, IsDefault = true, NotificationValue = _userContext.Email, CreateBy = user.Username, CreateDtTm = DateTime.Now, LastChgBy = user.Username, LastChgDtTm = DateTime.Now, NotificationEnabled = true }; _context.UserNotifications.Add(entity); await _context.SaveChangesAsync(); userProfile.UserNotifications.Add(_mapper.Map <UserNotificationData>(entity)); } else { userProfile.UserNotifications.Add(_mapper.Map <UserNotificationData>(messageType)); } } // check if the user has agreed to the latest terms and privacy userProfile.HasAgreedToTerms = await _agreementDocumentService.HasUserAgreedToLatestTermsAndPrivacy(user.UserId); SetSecurityProperties(user, userProfile); userProfile.CarrierVisibilityTypes = _commonService.GetCarrierVisibilityTypes(user.Username, user.PrimaryScacEntity?.CarrierId); return(userProfile); }