361 lines
10 KiB
C#
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, "");
|
|
}
|
|
}
|
|
|