auto.bus_razor/TicketOffice/Pages/Management/Routes/Edit.cshtml.cs

361 lines
10 KiB
C#

using System.Globalization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using TicketOffice.Data;
using TicketOffice.Models;
using TicketOffice.Services;
using Route = TicketOffice.Models.Route;
namespace TicketOffice.Pages.Management.Routes;
public class EditModel : PageModel
{
// Error massage displaying when route number validation failed.
public string NumberValidationError = null!;
// Error massage displaying when route capacity validation failed.
public string CapacityValidationError = null!;
// Array of error massages displaying when route name validation failed.
public string[] NameValidationError = null!;
// Array of error massages displaying when cities
// departure time validation failed.
public string[] DepartureTimeValidationError = null!;
// Array of error massages displaying when cities
// arrival time validation failed.
public string[] ArrivalTimeValidationError = null!;
private readonly TicketOfficeContext context;
private readonly UserValidationService validationService;
public EditModel(TicketOfficeContext context,
UserValidationService validationService)
{
this.context = context;
this.validationService = validationService;
}
// Object representing that will be created.
[BindProperty]
public Route? Route { get; set; }
// Object holding cities' arrival/departure dates.
[BindProperty]
public DateString[] TimeStrings { get; set; } = null!;
// Holds cities' ids between loading and saving
[BindProperty]
public int[] CityIds { get; set; } = null!;
// Called when GET request is sent to the page.
// Retrieves route.
public IActionResult OnGet(int? id)
{
if (!validationService.IsManager(HttpContext))
{
return RedirectToPage("/Index");
}
if (id == null)
{
return NotFound();
}
Route = context.Route.Where(m => m.Id == id)
.Include(r => r.Cities)
.First();
InitializeArrays();
TimeStrings = new DateString[Route.Cities.Count];
for (int i = 0; i < TimeStrings.Length; i++)
{
TimeStrings[i] = new DateString();
}
InsertDatesIntoStrings();
SaveCityIds();
if (Route == null)
{
return NotFound();
}
return Page();
}
// Called when POST request is sent to the page.
// Saves changes made to route.
public IActionResult OnPost(int? id)
{
InitializeArrays();
InsertDatesIntoCities();
LoadCityIds();
Route!.Id = (int) id;
if (!ValidateInput())
{
return Page();
}
context.Attach(Route).State = EntityState.Modified;
foreach (var city in Route.Cities)
{
context.Attach(city).State = EntityState.Modified;
}
try
{
context.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!RouteExists(Route.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool RouteExists(int id)
{
return context.Route.Any(e => e.Id == id);
}
private void InsertDatesIntoCities()
{
for (int i = 0; i < Route!.Cities.Count; i++)
{
try
{
Route.Cities[i].DepartureTime =
ConvertStringToDate(TimeStrings[i].DepartureDate!);
}
catch(Exception)
{
if (Route.Cities.Count > 2)
{
DepartureTimeValidationError= InitializeArray<string>(
Route.Cities.Count, "");
}
DepartureTimeValidationError[i] = "Формат: dd.MM.yyyy, hh:mm";
}
try
{
Route.Cities[i].ArrivalTime =
ConvertStringToDate(TimeStrings[i].ArrivalDate!);
}
catch(Exception)
{
if (Route.Cities.Count > 2)
{
ArrivalTimeValidationError = InitializeArray<string>(
Route.Cities.Count, "");
}
ArrivalTimeValidationError[i] = "Формат: dd.MM.yyyy, hh:mm";
}
}
DateTime? ConvertStringToDate(string dateStr)
{
if (String.IsNullOrWhiteSpace(dateStr) ||
String.IsNullOrEmpty(dateStr))
{
return null;
}
string[] date = dateStr.Split(",")[0].Split(".");
string[] time = dateStr.Split(",")[1].Split(":");
date.ToList().ForEach(s => s.Trim());
time.ToList().ForEach(s => s.Trim());
return new DateTime(
Int32.Parse(date[2]),
Int32.Parse(date[1]),
Int32.Parse(date[0]),
Int32.Parse(time[0]),
Int32.Parse(time[1]),
0);
}
}
private void InsertDatesIntoStrings()
{
for (int i = 0; i < Route!.Cities.Count; i++)
{
if (Route.Cities[i].DepartureTime != null)
{
TimeStrings[i].DepartureDate = Route.Cities[i].DepartureTime!
.Value.ToString("dd.MM.yyyy, hh:mm");
}
if (Route.Cities[i].ArrivalTime != null)
{
TimeStrings[i].ArrivalDate = Route.Cities[i].ArrivalTime!
.Value.ToString("dd.MM.yyyy, hh:mm");
}
}
}
// This method doesn't actually work, but stays here for representing
// an idea. It should be removed.
private void SaveCityIds()
{
CityIds = new int[Route!.Cities.Count];
for (int i = 0; i < Route.Cities.Count; i++)
{
CityIds[i] = Route.Cities[i].Id;
}
}
private void LoadCityIds()
{
for (int i = 0; i < CityIds.Length; i++)
{
Route!.Cities[i].Id = CityIds[i];
}
}
private bool ValidateInput()
{
bool isValidNumber = ValidateNumber(Route!.Number, out NumberValidationError);
bool isValidCapacity = ValidateCapacity(Route.Capacity, out CapacityValidationError);
for (int i = 0; i < Route.Cities.Count; i++)
{
if (Route.Cities.Count > 2)
{
NameValidationError = InitializeArray<string>(
Route.Cities.Count, "");
}
ValidateName(Route.Cities[i].Name, out NameValidationError[i]);
}
for (int i = 0; i < Route.Cities.Count; i++)
{
if (Route.Cities.Count > 2)
{
DepartureTimeValidationError= InitializeArray<string>(
Route.Cities.Count, "");
}
ValidateDate(Route.Cities[i].DepartureTime, out DepartureTimeValidationError[i]);
}
for (int i = 0; i < Route.Cities.Count; i++)
{
if (Route.Cities.Count > 2)
{
ArrivalTimeValidationError = InitializeArray<string>(
Route.Cities.Count, "");
}
ValidateDate(Route.Cities[i].ArrivalTime, out ArrivalTimeValidationError[i]);
}
if (!isValidNumber || !isValidCapacity ||
NameValidationError.Any(e => e != "") ||
DepartureTimeValidationError.Any(e => e != "") ||
ArrivalTimeValidationError.Any(e => e != ""))
{
return false;
}
return true;
bool ValidateNumber(int number, out string validationError)
{
validationError = "";
if (number < 1 || number > 9999)
{
validationError = "Має бути в проміжку від 1 до 9999";
return false;
}
return true;
}
bool ValidateCapacity(int capacity, out string validationError)
{
validationError = "";
if (capacity < 1 || capacity > 40)
{
validationError = "Має бути в проміжку від 5 до 45";
return false;
}
return true;
}
bool ValidateName(string name, out string validationError)
{
validationError = "";
if (String.IsNullOrWhiteSpace(name) || String.IsNullOrEmpty(name))
{
validationError = "Поле має бути заповненим";
return false;
}
return true;
}
bool ValidateDate(DateTime? date, out string validationError)
{
validationError = "";
if (date == null)
{
return true;
}
if (date < DateTime.Today)
{
validationError = $"Має бути пізніше ніж {DateTime.Today.ToString(CultureInfo.GetCultureInfo("uk-UA"))}";
return false;
}
return true;
}
}
private T[] InitializeArray<T>(int length, T initVal)
{
T[] arr = new T[length];
for (int i = 0; i < length; i++)
{
arr[i] = initVal;
}
return arr;
}
private void InitializeArrays()
{
NameValidationError = InitializeArray<string>(Route!.Cities.Count, "");
DepartureTimeValidationError = InitializeArray<string>(Route.Cities.Count, "");
ArrivalTimeValidationError = InitializeArray<string>(Route.Cities.Count, "");
}
}