/// <summary> /// Resolves a damage history case that is open. /// </summary> /// <param name="damageModel">Damage model from user selection</param> /// <returns></returns> public async Task <IActionResult> ResolveDamages(DamageHistoryModel damageModel) { //Flip resolved to true so in future will only be viewable damageModel.resolved = true; //Update the db string response = await _beService.UpdateDamageHistoryAsync(DamageHistoryDTO.CreateDTO(damageModel)); if (response != "Success") { return(RedirectToAction("ViewDamageImages", damageModel)); } //Set the vehicle state to in so can be used again VehicleDTO veh = await _beService.GetVehicleAsync(damageModel.lplateNum); veh.state = "In"; response = await _beService.UpdateVehicleAsync(veh); if (response != "Success") { return(RedirectToAction("Index")); } return(RedirectToAction("Details", damageModel.lplateNum)); }
public static DamageHistoryDTO CreateDTO(DamageHistoryModel model) { DamageHistoryDTO newDTO = new DamageHistoryDTO() { Id = model.Id, driverID = model.driverID, time = model.time, lplateNum = model.lplateNum, state = model.state, resolved = model.resolved }; return(newDTO); }
/// <summary> /// Shows the images linked to the selected Damage History entry /// </summary> /// <param name="damageModel">Selected damage history entry</param> /// <returns></returns> public async Task <IActionResult> ViewDamageImages(DamageHistoryModel damageModel) { //Work out Image ID Pretext to use to search string imagePreText = ImageDTO.GenerateImagePre(damageModel.Id, damageModel.time.ToString()); //Search Image DB for images that start with the prefix IEnumerable <byte[]> foundImages = await _blobService.GetImages(imagePreText); //Set damageModel list of images to that damageModel.images = foundImages; //If it is an open investigation case if (damageModel.resolved == false) { //Return the resolve view return(View("VehicleDamageResolve", damageModel)); } else { //Reutn the view for looking at the images return(View("VehicleDamageView", damageModel)); } }
public async Task <ActionResult> ConfirmClockVehicle(ClockModel cModel) { //Due to the lack of an auth/identitfy of the driver //This would is acting as a placeholder for the current driver ID Guid driverID = Guid.NewGuid(); string updateResponse = null; //If clock in, check for damages against the AI service if (cModel.clock == "In") { //Generate a new ID for the potential damage model Guid damageID = Guid.NewGuid(); //Create ImageDTO list for each image to be added as we go through the loop of uploads. List <ImageDTO> vehicleImages = new List <ImageDTO>(); //Set state of tracking = null //Used to track the verdict. //This allows to continue processing all uploaded images but still know that one showed damage string verdictTracker = "Undamaged"; //Set counter to 0. This is used to add a suffix count to the end of the image filename when uploaded int count = 0; //Loop through uploads foreach (IFormFile img in cModel.imgs) { //Increment the count count++; //Create a new image DTO. ImageDTO newImageDTO = ImageDTO.CreateDTO(ImageDTO.GenerateImageId(damageID, cModel.time, count.ToString(), img), img); vehicleImages.Add(newImageDTO); try { //Check the damage of the images against the AI model APIDTO returnApiDto = await _damageService.DamageCheckImg(newImageDTO); //Extract at the decimal percentage of guesses for each tag double damagedGuess = returnApiDto.predictions.FirstOrDefault(x => x.tagName == "Damaged").probability; double wholeGuess = returnApiDto.predictions.FirstOrDefault(x => x.tagName == "Whole").probability; //If both results are over 0.1 then cant say for certain. i.e level of uncertainty //This is to make sure a Staff member will manually resolve it if (wholeGuess >= 0.1 && damagedGuess >= 0.1) { //If not already set to damage from previous image. //Test this because Damaged is a stronger case than Inclonclusive if (verdictTracker == "Undamaged") { verdictTracker = "Inconclusive"; } } //If the verdict is Damaged else if (damagedGuess > wholeGuess) { //If Damaged then overrules the above conclusion of a previous image verdictTracker = "Damaged"; } } catch { //In any case of an error, set to Inclousive verdictTracker = "Inconclusive"; } } //After loop of images, check the state. //If either damage or incloncsive if (verdictTracker != "Undamaged") { try { //Set the new state to if (verdictTracker == "Inconclusive") { cModel.clock = "Inconclusive"; } //Damaged else { cModel.clock = "Damaged"; } //Create and Insert a Damage history record to keep track of vehicle damages DamageHistoryDTO newDamageDTO = DamageHistoryDTO.CreateDTO(DamageHistoryModel.CreateModel(cModel, damageID, driverID)); updateResponse = await _vehicleService.InsertDamageHistoryAsync(newDamageDTO); if (updateResponse != "Success") { return(RedirectToAction("ClockVehicle")); } //Update Vehicle with new state cModel.vehicle.state = "Under Investigation"; VehicleDTO newVehDto = VehicleDTO.CreateDTO(cModel.vehicle); updateResponse = await _vehicleService.UpdateVehicleAsync(newVehDto); if (updateResponse != "Success") { return(RedirectToAction("ClockVehicle")); } //Loop and upload images to blob storage foreach (ImageDTO img in vehicleImages) { //Save Images to the blob storage. updateResponse = await _blobService.UploadImage(img); if (updateResponse != "Success") { return(RedirectToAction("ClockVehicle")); } } //Return back to confirmed view return(View("ClockConfirmed", cModel)); } catch { //if error at anypoint, restart the form by rdirecting to initial action return(RedirectToAction("ClockVehicle")); } } } //Update state of the vehicle in vehicle table cModel.vehicle.state = cModel.clock; VehicleDTO vehDTO = VehicleDTO.CreateDTO(cModel.vehicle); updateResponse = await _vehicleService.UpdateVehicleAsync(vehDTO); if (updateResponse != "Success") { return(RedirectToAction("ClockVehicle")); } //Insert into the history table. //Note: The DriverID would be replaced with identification if implemented as mentioned above Guid historyID = Guid.NewGuid(); ClockHistoryDTO newDTO = ClockHistoryDTO.CreateDTO(cModel, historyID, driverID); updateResponse = await _vehicleService.InsertClockHistoryAsync(newDTO); if (updateResponse != "Success") { return(RedirectToAction("ClockVehicle")); } //Return back to confirmed view return(View("ClockConfirmed", cModel)); }