private async Task ControleerWijzigingen_Statusovergang(Bestelling oudeBestelling, Bestelling nieuweBestelling) { Bestelling.EnumStatus oudeBestellingStatus = oudeBestelling == null ? Bestelling.EnumStatus.Nieuw : oudeBestelling.Status; // Eerst controleren of er wel degelijk een statusovergang gebeurt. if (oudeBestellingStatus != nieuweBestelling.Status) { // Is de statusovergang toegelaten? if (!oudeBestelling.BepaalGeldigeStatusovergangen().Contains(nieuweBestelling.Status)) { ModelState.AddModelError(nameof(Bestelling.Status), $"De statusovergang van {oudeBestelling.Status} naar {nieuweBestelling.Status} is niet toegelaten."); } else { // Indien de statusovergang toegelaten is: nog eventuele status-specifieke controles uitvoeren. switch (nieuweBestelling.Status) { case Bestelling.EnumStatus.Besteld: // Een bestelling kan enkel geplaatst worden voor een tijdslot in de toekomst. if (nieuweBestelling.Tijdslot != null && nieuweBestelling.Tijdslot.Value < DateTime.Now) { ModelState.AddModelError(nameof(Bestelling.Tijdslot), $"Het tijdslot ligt in het verleden."); } // Een bestelling kan pas besteld worden wanneer er minstens één gerecht besteld is. if (nieuweBestelling.BesteldeGerechten.Count == 0) { ModelState.AddModelError(nameof(Bestelling.Status), $"Gelieve minstens één gerecht toe te voegen."); } break; case Bestelling.EnumStatus.Geannuleerd: // Gebeurt er geen annulatie in de laatste 2 uur? if (oudeBestelling.Status != Bestelling.EnumStatus.Nieuw && nieuweBestelling.Tijdslot.Value < DateTime.Now.AddHours(2)) { ModelState.AddModelError(nameof(Bestelling.Status), $"De bestelling kan niet meer geannuleerd worden."); } break; } } } }
public async Task <IActionResult> Edit( int id, [Bind("Id,Status,Betaald,KlantId,Tijdslot,Opmerkingen")] Bestelling bestelling, [Bind("actie")] string actie) { if (id != bestelling.Id) { return(NotFound()); } // De vorige versie van de bestelling ophalen. Bestelling oudeBestelling = await _context.Bestellingen .AsNoTracking() .FirstOrDefaultAsync(b => b.Id == bestelling.Id); // Op de Edit.cshtml werden meerdere input's van het type 'submit' voorzien. // Elke submit heeft een eigen value die via deze switch omgezet wordt naar // een specifieke status op de bestelling. switch (actie) { case ACTIE_BESTELLEN: bestelling.Status = Bestelling.EnumStatus.Besteld; break; case ACTIE_AFLEVEREN: bestelling.Status = Bestelling.EnumStatus.Afgeleverd; break; case ACTIE_ANNULEREN: bestelling.Status = Bestelling.EnumStatus.Geannuleerd; break; case ACTIE_BEWAREN: // fallthrough naar 'default'. default: // Indien geen actie, geen status wijziging. // De 'oude' bestellingstatus wordt wel expliciet gezet omdat 'Status' mogelijk niet in de ge-POSTe form zit (cfr. disabled) OF omdat die gemanipuleerd zou kunnen zijn. bestelling.Status = oudeBestelling.Status; break; } // Het Bestelling-object dat aan deze action is 'gebind' is momenteel nog vrij leeg: er hangen geen child entiteiten onder. // Vandaar moeten deze dus uit de database opgehaald worden. bestelling.Klant = await(from k in _context.Klanten where k.Id == bestelling.KlantId select k).FirstAsync(); bestelling.BesteldeGerechten = await(from bg in _context.BesteldeGerechten .Include(bg => bg.Gerecht) where bg.BestellingId == bestelling.Id select bg).ToListAsync(); // Controleren of eventuele wijzigingen en statusovergangen toegestaan zijn. await ControleerWijzigingen(oudeBestelling, bestelling); if (ModelState.IsValid) { try { _context.Update(bestelling); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!BestellingExists(bestelling.Id)) { return(NotFound()); } else { throw; } } return(RedirectToAction(nameof(Edit), new { id = bestelling.Id })); } else { ViewData["GeldigeWijzigingen"] = oudeBestelling.BepaalGeldigeWijzigingen(); // Opgelet: de geldige wijzigingen mogen enkel bepaald worden op basis van de vorige versie. ViewData["GeldigeStatusovergangen"] = oudeBestelling.BepaalGeldigeStatusovergangen(); // Opgelet: de geldige statussen mogen enkel bepaald worden op basis van de vorige versie. ViewData["KlantId"] = new SelectList(_context.Klanten, "Id", "Email", bestelling.KlantId); ViewData["Prijs"] = await BerekenTotalePrijsMetKorting(bestelling); bestelling.Status = oudeBestelling.Status; // Een eventuele aangevraagde statusovergang terug ongedaan maken. return(View(bestelling)); } }