/// <summary> /// Summary report action. /// </summary> /// <param name="tripId">Trip to be summarized.</param> /// <returns></returns> public ReportResult Summary(Trip tripId) { return tripId is PurseSeineTrip ? Summary(tripId as PurseSeineTrip) : tripId is LongLineTrip ? Summary(tripId as LongLineTrip) : new ReportResult(new Report()); }
/// <summary> /// Export a summary of the trip as an Excel spreadsheet. /// </summary> /// <example>GET: "Trip/{tripId}/LengthFrequency.xlsx</example> /// <param name="tripId"></param> /// <returns></returns> public ReportResult AllSamples(Trip tripId) { return tripId is PurseSeineTrip ? AllSamples(tripId as PurseSeineTrip) : tripId is LongLineTrip ? AllSamples(tripId as LongLineTrip) : new ReportResult(new Report()); }
public ActionResult Add(Trip tripId, int setNumber) { var repo = TubsDataService.GetRepository<PurseSeineSet>(MvcApplication.CurrentSession); var fset = repo.FilterBy( s => s.Activity.Day.Trip.Id == tripId.Id && s.SetNumber == setNumber ).FirstOrDefault(); // Shouldn't happen, but then again... if (null == fset) return RedirectToAction("List", new { tripId = tripId.Id }); var vm = new LengthFrequencyViewModel(); // Add in some properties vm.SetNumber = setNumber; vm.PageNumber = fset.SamplingHeaders.Count + 1; vm.PageCount = vm.PageNumber; vm.ActionName = "Add"; vm.SetId = fset.Id; vm.TripId = tripId.Id; vm.TripNumber = tripId.SpcTripNumber; foreach (var brailNumber in Enumerable.Range(1, 30)) { vm.Brails.Add(new LengthFrequencyViewModel.Brail() { Number = brailNumber }); } return View("_Editor", vm); }
/// <summary> /// Return all trip positions as KML. /// </summary> /// <param name="tripId">Current trip</param> /// /// <param name="extension">File extension</param> /// <returns>KML document with all trip positions.</returns> public ActionResult AllData(Trip tripId, string extension) { if (null == tripId) { return InvalidTripResponse(); } if (!IsKml(extension)) return new HttpNotFoundResult(); // Exclude any pushpins that won't display nicely var pushpins = tripId.Pushpins.Where(p => p.CanDisplay()).ToList(); // Sort by date (assumes all timestamps have the same base frame of reference for date) // which occasionally is not true. pushpins.Sort( delegate(Pushpin p1, Pushpin p2) { return Comparer<DateTime?>.Default.Compare(p1.Timestamp, p2.Timestamp); }); var tripDoc = KmlBuilder.Build(tripId.Pushpins); tripDoc.name = "All Trip Positions"; tripDoc.description = String.Format( "Positions for trip {0} generated on {1} via URL: [{2}]", tripId.ToString(), DateTime.Now.ToShortDateString(), this.HttpContext.Request.RawUrl); return new KmlResult() { Document = tripDoc, IsCompressed = IsCompressed(extension) }; }
public ActionResult Edit(Trip tripId, int setNumber, PurseSeineSetViewModel fsvm) { var trip = tripId as PurseSeineTrip; // TODO Any validation that the attributes don't cover if (!ModelState.IsValid) { if (IsApiRequest) return ModelErrorsResponse(); return View(fsvm); } // Convert to entity var fset = Mapper.Map<PurseSeineSetViewModel, PurseSeineSet>(fsvm); // Set audit trails fset.SetAuditTrail(User.Identity.Name, DateTime.Now); using (var xa = MvcApplication.CurrentSession.BeginTransaction()) { var fsrepo = TubsDataService.GetRepository<PurseSeineSet>(MvcApplication.CurrentSession); var erepo = TubsDataService.GetRepository<Activity>(MvcApplication.CurrentSession); var screpo = TubsDataService.GetRepository<PurseSeineSetCatch>(MvcApplication.CurrentSession); // A read-only property on the view model relieves us of some hassle fsvm.DeletedCatchIds.ToList().ForEach(x => screpo.DeleteById(x)); // Deletes first //fsvm.TargetCatch.DefaultIfEmpty().Where(x => null != x && x._destroy).ToList().ForEach(x => screpo.DeleteById(x.Id)); //fsvm.ByCatch.DefaultIfEmpty().Where(x => x != null && x._destroy).ToList().ForEach(x => screpo.DeleteById(x.Id)); var parent = erepo.FindById(fsvm.ActivityId) as PurseSeineActivity; fset.Activity = parent; fset.CatchList.ToList().ForEach(cl => { cl.SetAuditTrail(User.Identity.Name, DateTime.Now); screpo.Save(cl); }); fsrepo.Save(fset); xa.Commit(); fsrepo.Reload(fset); } if (IsApiRequest) { var maxSets = fsvm.MaxSets; fsvm = Mapper.Map<PurseSeineSet, PurseSeineSetViewModel>(fset); fsvm.MaxSets = maxSets; fsvm.HasNext = setNumber < maxSets; fsvm.HasPrevious = setNumber > 1; return GettableJsonNetData(fsvm); } return RedirectToAction("Edit", new { tripId = tripId.Id, setNumber = setNumber }); }
// // GET: /Gen6/ public ActionResult Index(Trip tripId, int pageNumber) { if (null == tripId) { return new NoSuchTripResult(); } var pollutionEvent = FindByTripAndPageNumber(tripId, pageNumber); ViewBag.Title = String.Format("GEN-6 page {0} of {1}", ViewBag.CurrentPage, ViewBag.MaxPages); return View(pollutionEvent); }
public ActionResult Edit(Trip tripId, int pageNumber) { if (null == tripId) { return new NoSuchTripResult(); } AddMinMaxDates(tripId); ViewBag.Title = String.Format("Edit GEN-6 page {1} for trip {0}", tripId.ToString(), pageNumber); ViewBag.TripNumber = tripId.SpcTripNumber ?? "This Trip"; var pollutionEvent = FindByTripAndPageNumber(tripId, pageNumber); return View(pollutionEvent); }
public ActionResult Add(Trip tripId) { if (null == tripId) { return new NoSuchTripResult(); } AddMinMaxDates(tripId); ViewBag.Title = String.Format("Edit GEN-6 event for trip {0}", tripId.ToString()); ViewBag.TripNumber = tripId.SpcTripNumber ?? "This Trip"; var pevent = new PollutionEvent(); pevent.Trip = tripId; return View(pevent); }
/// <summary> /// /// </summary> /// <example>GET: "Trip/{tripId}/Samples/{setNumber}/Page/{pageNumber}"</example> /// <param name="tripId">Current trip</param> /// <param name="setNumber">Set number within the trip</param> /// <param name="pageNumber">Page number within the trip</param> /// <returns></returns> public ActionResult Index(Trip tripId, int setNumber, int? pageNumber) { var trip = tripId as PurseSeineTrip; if (null == trip) { return InvalidTripResponse(); } var repo = TubsDataService.GetRepository<LengthSamplingHeader>(MvcApplication.CurrentSession); pageNumber = pageNumber ?? 1; // Or should this be set as a default in the route? var header = repo.FilterBy(h => h.Set.Activity.Day.Trip.Id == tripId.Id && h.Set.SetNumber == setNumber && h.PageNumber == pageNumber).FirstOrDefault(); var lfvm = Mapper.Map<LengthSamplingHeader, LengthFrequencyViewModel>(header); return View(lfvm); }
public ActionResult Edit(Trip tripId, PageCountViewModel pcvm) { if (null == tripId) { return InvalidTripResponse(); } if (null == pcvm) { return ViewActionImpl(tripId); } using (var xa = MvcApplication.CurrentSession.BeginTransaction()) { var repo = TubsDataService.GetRepository<PageCount>(MvcApplication.CurrentSession); // Deletes first pcvm.PageCounts.Where(pc => null != pc && pc._destroy).ToList().ForEach(x => repo.DeleteById(x.Id)); // Save or update var saves = pcvm.PageCounts.Where(pc => null != pc && !pc._destroy); foreach (var item in saves) { Logger.DebugFormat("Saving PageCount with key {0} and value {1}", item.Key, item.Value); var entity = Mapper.Map<PageCountViewModel.PageCount, PageCount>(item); if (null == entity) { continue; } Logger.DebugFormat("Entity values for Form {0} and Count {1}", entity.FormName, entity.FormCount); entity.Trip = tripId; entity.EnteredBy = User.Identity.Name; entity.EnteredDate = DateTime.Now; repo.Save(entity); } xa.Commit(); } if (IsApiRequest) { using (var trepo = TubsDataService.GetRepository<Trip>(false)) { var trip = trepo.FindById(tripId.Id); pcvm = Mapper.Map<Trip, PageCountViewModel>(trip); return GettableJsonNetData(pcvm); } } // If this isn't an API request (which shouldn't really happen) // always push to the Edit page. return RedirectToAction("Edit", "PageCount", new { tripId = tripId.Id }); }
public ActionResult EditSightings(Trip tripId, SightingViewModel svm) { if (!ModelState.IsValid) { if (IsApiRequest) return ModelErrorsResponse(); return View(svm); } var sightings = new List<Sighting>(); // I can almost get there with LINQ, but I fear I'd have problems with it // in the Brian Kernighan "twice-as-smart-to-debug" sense. foreach (var sighting in svm.Sightings) { if (null == sighting || sighting._destroy) continue; var entity = Mapper.Map<SightingViewModel.Sighting, Sighting>(sighting); if (null != entity) { entity.Trip = tripId; entity.SetAuditTrail(User.Identity.Name, DateTime.Now); sightings.Add(entity); } } using (var xa = MvcApplication.CurrentSession.BeginTransaction()) { IRepository<Sighting> repo = TubsDataService.GetRepository<Sighting>(MvcApplication.CurrentSession); // Deletes first svm.DeletedIds.ToList().ForEach(id => repo.DeleteById(id)); sightings.ForEach(s => repo.Save(s)); xa.Commit(); } if (IsApiRequest) { using (var trepo = TubsDataService.GetRepository<Trip>(false)) { var t = trepo.FindById(tripId.Id); svm = Mapper.Map<Trip, SightingViewModel>(t); } return GettableJsonNetData(svm); } return RedirectToAction("EditSightings", "Gen1", new { tripId = tripId.Id }); }
public ActionResult Edit(Trip tripId, CrewViewModel cvm) { if (!ModelState.IsValid) { if (IsApiRequest) { return ModelErrorsResponse(); } ViewBag.Title = String.Format("Edit crew list for {0}", tripId.ToString()); return View(cvm); } using (var xa = MvcApplication.CurrentSession.BeginTransaction()) { IRepository<Crew> repo = TubsDataService.GetRepository<Crew>(MvcApplication.CurrentSession); // Deletes first cvm.Deleted.ToList().ForEach(id => repo.DeleteById(id)); // AsCrewList strips out any crew marked _destroy or that don't have details var crewlist = cvm.AsCrewList(); crewlist.ToList().ForEach(c => { c.SetAuditTrail(User.Identity.Name, DateTime.Now); c.Trip = tripId; repo.Save(c); }); // Flush to database xa.Commit(); } if (IsApiRequest) { using (var repo = TubsDataService.GetRepository<Trip>(false)) { var trip = repo.FindById(tripId.Id) as PurseSeineTrip; cvm = Mapper.Map<PurseSeineTrip, CrewViewModel>(trip); } return GettableJsonNetData(cvm); } return RedirectToAction("Index", "Crew", new { tripId = tripId.Id }); }
public ActionResult Index(Trip tripId, int headerId, int offset) { // offset should be 0, 20, 40, 60, 80, or 100 // anything else and we should puke here var repo = TubsDataService.GetRepository<LengthSamplingHeader>(MvcApplication.CurrentSession); var header = repo.FindById(headerId); // TODO: What happens when header is not found? // Second check -- make sure this header is in this trip var vm = new SampleColumnViewModel(); vm.Id = header.Id; vm.Offset = offset; int maxSequence = offset + 20; var samples = header.Samples.Where(s => null != s && s.SequenceNumber > offset && s.SequenceNumber <= maxSequence).Take(20); foreach (var sample in samples.OrderBy(s => s.SequenceNumber)) { // First subtraction to get us into the right place within the column // Second subtraction moves us from a one based offset to a zero based offset var position = (sample.SequenceNumber.Value - offset) - 1; if (position < 0 || position > 19) { Logger.ErrorFormat("Sample with Id {0} has a strange offset", sample.Id); continue; } vm.Samples[position] = new PurseSeineSampleViewModel() { Id = sample.Id, Number = sample.SequenceNumber.Value, SpeciesCode = sample.SpeciesCode, Length = sample.Length }; } return View(vm); }
/// <summary> /// MVC Action for returning trip track /// </summary> /// <param name="tripId">Current trip</param> /// <param name="extension">Desired file extension</param> /// <returns>Trip track using the requested file type.</returns> public ActionResult Track(Trip tripId, string extension) { if (null == tripId) { return InvalidTripResponse(); } if (IsKml(extension)) return TrackKml(tripId, IsCompressed(extension)); if (IsJson(extension)) { var vm = Mapper.Map<Trip, TrackViewModel>(tripId); if (null == vm) { // Return a 500 error with the message that // the mapping failed } return GettableJsonNetData(vm.GeoJson); } // Caller is asking for a file type (extension) we can't create return new HttpNotFoundResult(); }
/// <summary> /// Create KML document representing just the trip positions. /// </summary> /// <param name="tripId">Current trip</param> /// <param name="isCompressed">Parameter for requesting compressed data</param> /// <returns>KML document containing trip positions.</returns> internal KmlResult PositionsKml(Trip tripId, bool isCompressed = false) { // Exclude any pushpins that won't display nicely var pushpins = tripId.Pushpins.Where(p => p.CanDisplay()).ToList(); // There's no call to sort these positions var tripDoc = KmlBuilder.Build(tripId.Pushpins, false); tripDoc.name = "All Trip Positions"; tripDoc.description = String.Format( "Positions for trip {0} generated on {1} via URL: [{2}]", tripId.ToString(), DateTime.Now.ToShortDateString(), this.HttpContext.Request.RawUrl); return new KmlResult() { Document = tripDoc, IsCompressed = isCompressed }; }
/// <summary> /// MVC Action for rendering the map plugin. /// Leaflet doesn't like living in a Bootstrap tab, so this /// has been extracted to a separate view. /// </summary> /// <param name="tripId">Current trip</param> /// <returns></returns> public ActionResult Index(Trip tripId) { if (null == tripId) { return InvalidTripResponse(); } ViewBag.Title = String.Format("{0}: Map", tripId.SpcTripNumber); ViewBag.TripNumber = tripId.SpcTripNumber; // Rather than make network calls, stuff the positions and track // into the ViewBag (and then into the page) var pvm = Mapper.Map<Trip, PositionsViewModel>(tripId); if (null != pvm) ViewBag.Positions = pvm.GeoJson; var tvm = Mapper.Map<Trip, TrackViewModel>(tripId); if (null != tvm) ViewBag.Track = tvm.GeoJson; return View(); }
/// <summary> /// MVC Action for returning all trip positions /// </summary> /// <param name="tripId">Current trip</param> /// <param name="extension">Desired file extension</param> /// <returns>All trip positions using the requested file type.</returns> public ActionResult Positions(Trip tripId, string extension) { if (null == tripId) { return InvalidTripResponse(); } if (IsKml(extension)) return PositionsKml(tripId, IsCompressed(extension)); if (IsJson(extension)) { // This (and the KML method) is the only thing that changes between // positions and track. It would be good to define these as function pointers // and then use a common implementation var vm = Mapper.Map<Trip, PositionsViewModel>(tripId); if (null == vm) { // Return a 500 error with the message that // the mapping failed } return GettableJsonNetData(vm.GeoJson); } // Caller is asking for a file type (extension) we can't create return new HttpNotFoundResult(); }
/// <summary> /// /// </summary> /// <param name="tripId"></param> /// <param name="setNumber"></param> /// <returns></returns> internal abstract ActionResult ViewActionImpl(Trip tripId, int setNumber);
public ActionResult Index(Trip tripId, int setNumber) { return ViewActionImpl(tripId, setNumber); }
internal override ActionResult ViewActionImpl(Trip tripId, int setNumber) { // This should never happen, but a little defensive coding goes a long way var trip = tripId as LongLineTrip; var sets = TubsDataService.GetRepository<LongLineSet>(MvcApplication.CurrentSession) .FilterBy(s => s.Trip.Id == trip.Id); // If I was just a _bit_ smarter, I could probably figure out how to extract the // following 10 lines into something that can be used between both PS and LL // data. // This LINQ method results in a trip to the database // (select count(1) from ... where obstrip_id = ?) // It's also worth mentioning that if an Add/Edit has // a 'bad' setNumber param, we'll be running this query twice // I expect SQL Server to be able to handle that... int maxSets = sets.Count(); var checkpoint = NeedsRedirect(trip.Id, setNumber, maxSets); if (checkpoint.Item1) return new RedirectToRouteResult(checkpoint.Item2); // One minor point. If the user passes in a completely crazy setNumber for Index // we'll re-interpret based on intent. if (IsIndex) { if (setNumber < 1) { setNumber = 1; } if (setNumber > maxSets) { setNumber = maxSets; } } // Based on NeedsRedirect, we should be okay -- the // setNumber should be perfect for the action var fset = ( from s in sets where s.SetNumber == setNumber select s).FirstOrDefault(); // This is where it gets tricky. LL doesn't have a "header" object for all bio samples // in a set -- it's just a list of entities hanging off the set. AutoMapper doesn't work // very well in that situation. var header = new LongLineCatchHeader(); header.SetId = fset.Id; header.FishingSet = fset; header.Samples = fset.CatchList; var svm = Mapper.Map<LongLineCatchHeader, LongLineSampleViewModel>(header); // Set some properties that AutoMapper can't manage for us svm.ActionName = CurrentAction; svm.HasNext = setNumber < maxSets; svm.HasPrevious = setNumber > 1; svm.SetCount = maxSets; if (IsApiRequest) return GettableJsonNetData(svm); return View(CurrentAction, svm); }
private ActionResult Load(Trip tripId, string titleFormat) { ViewBag.Title = String.Format(titleFormat, tripId.ToString()); return View(CurrentAction, tripId); }
public ActionResult Index(Trip tripId) { return Load(tripId, "GEN-1 events for trip {0}"); }
public ActionResult Edit(Trip tripId, int setNumber, LongLineSampleViewModel vm) { var trip = tripId as LongLineTrip; // TODO Validation // Possible validations: // 1) Any sample date less than start of haul // 2) Length out of range (really needs to be on client side too) if (!ModelState.IsValid) { LogModelErrors(); if (IsApiRequest) return ModelErrorsResponse(); return View(vm); } var header = Mapper.Map<LongLineSampleViewModel, LongLineCatchHeader>(vm); using (var xa = MvcApplication.CurrentSession.BeginTransaction()) { // We need a LongLineSet repository to get the set that will be the parent for all the catch IRepository<LongLineSet> srepo = TubsDataService.GetRepository<LongLineSet>(MvcApplication.CurrentSession); IRepository<LongLineCatch> crepo = TubsDataService.GetRepository<LongLineCatch>(MvcApplication.CurrentSession); vm.DeletedCatch.ToList().ForEach(id => crepo.DeleteById(id)); var fset = srepo.FindById(vm.SetId); int index = 1; foreach (var sample in header.Samples.OrderBy(s => s.Date)) { sample.SampleNumber = index; sample.FishingSet = fset; sample.SetAuditTrail(User.Identity.Name, DateTime.Now); crepo.Save(sample); ++index; } // MeasuringInstrument is recorded on the LongLineSet entity // Save here, after samples, to avoid transient object problems fset.MeasuringInstrument = vm.MeasuringInstrument.MeasuringInstrumentFromString(); srepo.Save(fset); xa.Commit(); } if (IsApiRequest) { using (var repo = TubsDataService.GetRepository<LongLineSet>(false)) { var updatedSet = repo.FindById(vm.SetId); var xheader = new LongLineCatchHeader(); xheader.SetId = updatedSet.Id; xheader.FishingSet = updatedSet; xheader.Samples = updatedSet.CatchList; var svm = Mapper.Map<LongLineCatchHeader, LongLineSampleViewModel>(xheader); // Set some properties that AutoMapper can't manage for us svm.ActionName = CurrentAction; svm.HasNext = vm.HasNext; svm.HasPrevious = setNumber > 1; svm.SetCount = vm.SetCount; return GettableJsonNetData(svm); } } // If this isn't an API request (which shouldn't really happen) // always push to the Edit page. It's been saved, so an Add is counter-productive // (besides, redirecting to Add with the current dayNumber will redirect to Edit anyways...) return RedirectToAction("Edit", "LongLineSampling", new { tripId = tripId.Id, setNumber = setNumber }); }
private PollutionEvent FindByTripAndPageNumber(Trip tripId, int pageNumber) { var events = tripId.PollutionEvents; int maxPages = events.Count(); if (pageNumber > maxPages) { pageNumber = maxPages; } ViewBag.MaxPages = maxPages; ViewBag.CurrentPage = pageNumber; return events.Skip(pageNumber - 1).Take(1).FirstOrDefault(); }
public ActionResult Transfers(Trip tripId) { return TransferViewActionImpl(tripId); }
internal ActionResult SightingViewActionImpl(Trip tripId) { var svm = Mapper.Map<Trip, SightingViewModel>(tripId); if (IsApiRequest) return GettableJsonNetData(svm); return View(CurrentAction,svm); }
/// <summary> /// Create KML document representing just the trip track. /// </summary> /// <param name="tripId">Current trip</param> /// <param name="isCompressed">Parameter for requesting compressed data</param> /// <returns>KML document containing trip track.</returns> internal KmlResult TrackKml(Trip tripId, bool isCompressed = false) { // Exclude any pushpins that won't display nicely var pushpins = tripId.Pushpins.Where(p => p.CanDisplay()).ToList(); // Sort by date (assumes all timestamps have the same base frame of reference for date) // which occasionally is not true. pushpins.Sort( delegate(Pushpin p1, Pushpin p2) { return Comparer<DateTime?>.Default.Compare(p1.Timestamp, p2.Timestamp); }); var tripDoc = KmlBuilder.BuildTrack(tripId.Pushpins); tripDoc.name = "Trip Track"; tripDoc.description = String.Format( "Positions for trip {0} generated on {1} via URL: [{2}]", tripId.ToString(), DateTime.Now.ToShortDateString(), this.HttpContext.Request.RawUrl); return new KmlResult() { Document = tripDoc, IsCompressed = isCompressed }; }
public ActionResult List(Trip tripId) { if (null == tripId) { return new NoSuchTripResult(); } ViewBag.Title = String.Format("GEN-6 events for trip {0}", tripId.ToString()); ViewBag.TripNumber = tripId.SpcTripNumber ?? "This Trip"; return View(tripId.PollutionEvents ?? new List<PollutionEvent>()); }
public ActionResult EditSightings(Trip tripId) { return SightingViewActionImpl(tripId); }
internal ActionResult TransferViewActionImpl(Trip tripId) { var tvm = Mapper.Map<Trip, TransferViewModel>(tripId); if (IsApiRequest) return GettableJsonNetData(tvm); return View(CurrentAction, tvm); }