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

294 lines
9.1 KiB
C#

using System.Globalization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using TicketOffice.Data;
using TicketOffice.Models;
using TicketOffice.Services;
using Route = TicketOffice.Models.Route;
namespace TicketOffice.Pages.Management.Routes;
public class CreateModel : 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 CreateModel(TicketOfficeContext context,
UserValidationService validationService)
{
this.context = context;
this.validationService = validationService;
}
// Object representing that will be created.
[BindProperty]
public Route Route { get; set; } = null!;
// Object holding cities' arrival/departure dates.
[BindProperty]
public DateString[] TimeStrings { get; set; } = null!;
// Amount of cities to be added to the route
[BindProperty]
public int? CitiesCount { get; set; }
// Called when GET request is sent to the page.
public IActionResult OnGet()
{
if (!validationService.IsManager(HttpContext))
{
return RedirectToPage("/Index");
}
return Page();
}
// Called when POST request is sent to the page (when user tries to add new
// route). Validates input, creates new route in the database and
// redirects to "Management/Routes" page.
public ActionResult OnPost()
{
if (CitiesCount != null)
{
Route = new Route();
Route.Cities = new List<RouteCity>();
TimeStrings = new DateString[(int) CitiesCount];
for (int i = 0; i < CitiesCount; i++)
{
TimeStrings[i] = new DateString();
Route.Cities.Add(new RouteCity());
}
NameValidationError = new string[(int) CitiesCount];
DepartureTimeValidationError = new string[(int) CitiesCount];
ArrivalTimeValidationError = new string[(int) CitiesCount];
return Page();
}
NameValidationError = new string[Route.Cities.Count];
DepartureTimeValidationError = new string[Route.Cities.Count];
ArrivalTimeValidationError = new string[Route.Cities.Count];
InsertDatesIntoCities();
if (!ValidateInput())
{
return Page();
}
context.Route.Add(Route);
context.SaveChanges();
return RedirectToPage("./Index");
}
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)
{
InitializeArray<string>(DepartureTimeValidationError,
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)
{
InitializeArray<string>(ArrivalTimeValidationError,
Route.Cities.Count,
"");
}
ArrivalTimeValidationError[i] = "Формат: dd.MM.yyyy, hh:mm";
}
}
DateTime? ConvertStringToDate(string dateStr)
{
if (String.IsNullOrWhiteSpace(dateStr) ||
String.IsNullOrEmpty(dateStr))
{
return null;
}
if (dateStr.Count(c => c == '.') != 2 &&
dateStr.Count(c => c == ':') != 2 &&
dateStr.Count(c => c == ',') != 1)
{
throw new ArgumentException("Invalid input format");
}
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 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)
{
InitializeArray<string>(NameValidationError,
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)
{
InitializeArray<string>(DepartureTimeValidationError,
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)
{
InitializeArray<string>(ArrivalTimeValidationError,
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")).Split(" ")[0]}";
return false;
}
return true;
}
}
private void InitializeArray<T>(T[] arr, int length, T initVal)
{
arr = new T[length];
for (int i = 0; i < length; i++)
{
arr[i] = initVal;
}
}
}