add data seeding
This commit is contained in:
parent
44dceee7b8
commit
fbe26898fa
@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using cuqmbr.TravelGuide.Persistence.PostgreSql;
|
||||
using cuqmbr.TravelGuide.Persistence.InMemory;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using cuqmbr.TravelGuide.Application.Common.Services;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Configuration.Persistence;
|
||||
|
||||
@ -76,10 +77,33 @@ public static class Configuration
|
||||
$"{configuration.Type} datastore is not supported.");
|
||||
}
|
||||
|
||||
if (configuration.Seed)
|
||||
if (configuration.SeedIdentity || configuration.SeedData)
|
||||
{
|
||||
using var serviceProvider = services.BuildServiceProvider();
|
||||
DbSeeder.Seed(serviceProvider);
|
||||
|
||||
var unitOfWork =
|
||||
serviceProvider.GetRequiredService<UnitOfWork>();
|
||||
var passwordHasher =
|
||||
serviceProvider.GetRequiredService<PasswordHasherService>();
|
||||
|
||||
using var dbSeeder = new DbSeeder(unitOfWork, passwordHasher);
|
||||
|
||||
if (configuration.SeedIdentity)
|
||||
{
|
||||
dbSeeder.SeedIdentity();
|
||||
}
|
||||
|
||||
// Data can not be seeded without seeding identity
|
||||
if (configuration.SeedData && !configuration.SeedIdentity)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Can not seed data without seeding identity.");
|
||||
}
|
||||
|
||||
if (configuration.SeedData)
|
||||
{
|
||||
dbSeeder.SeedData();
|
||||
}
|
||||
}
|
||||
|
||||
return services;
|
||||
|
@ -12,5 +12,7 @@ public sealed class ConfigurationOptions
|
||||
|
||||
public bool Migrate { get; set; } = true;
|
||||
|
||||
public bool Seed { get; set; } = false;
|
||||
public bool SeedIdentity { get; set; } = true;
|
||||
|
||||
public bool SeedData { get; set; } = false;
|
||||
}
|
||||
|
@ -4,103 +4,847 @@ using cuqmbr.TravelGuide.Application.Common.Persistence;
|
||||
using cuqmbr.TravelGuide.Application.Common.Services;
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
using cuqmbr.TravelGuide.Domain.Enums;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Persistence;
|
||||
|
||||
public static class DbSeeder
|
||||
public sealed class DbSeeder : IDisposable
|
||||
{
|
||||
public static void Seed(IServiceProvider serviceProvider)
|
||||
private readonly UnitOfWork _unitOfWork;
|
||||
|
||||
private readonly PasswordHasherService _passwordHasher;
|
||||
|
||||
public DbSeeder(UnitOfWork unitOfWork, PasswordHasherService passwordHasher)
|
||||
{
|
||||
var unitOfWork =
|
||||
serviceProvider.GetRequiredService<UnitOfWork>();
|
||||
|
||||
var passwordHasher =
|
||||
serviceProvider.GetRequiredService<PasswordHasherService>();
|
||||
|
||||
_unitOfWork = unitOfWork;
|
||||
_passwordHasher = passwordHasher;
|
||||
}
|
||||
|
||||
public void SeedIdentity()
|
||||
{
|
||||
// Seed Roles
|
||||
|
||||
var datastoreRoles = _unitOfWork.RoleRepository
|
||||
.GetPageAsync(1, IdentityRole.Enumerations.Count,
|
||||
CancellationToken.None)
|
||||
.Result.Items.Select(r => r.Value);
|
||||
|
||||
var identityRoles = IdentityRole.Enumerations.Select(r => r.Value);
|
||||
|
||||
foreach (var role in identityRoles)
|
||||
{
|
||||
var datastoreRoles = unitOfWork.RoleRepository
|
||||
.GetPageAsync(1, IdentityRole.Enumerations.Count,
|
||||
CancellationToken.None)
|
||||
.Result.Items.Select(r => r.Value);
|
||||
|
||||
var roles = IdentityRole.Enumerations.Select(r => r.Value);
|
||||
|
||||
foreach (var role in roles)
|
||||
if (datastoreRoles.Contains(role))
|
||||
{
|
||||
|
||||
if (datastoreRoles.Contains(role))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
unitOfWork.RoleRepository.AddOneAsync(
|
||||
new Role() { Value = role },
|
||||
CancellationToken.None).Wait();
|
||||
continue;
|
||||
}
|
||||
|
||||
unitOfWork.SaveAsync(CancellationToken.None).Wait();
|
||||
_unitOfWork.RoleRepository.AddOneAsync(
|
||||
new Role() { Value = role },
|
||||
CancellationToken.None).Wait();
|
||||
}
|
||||
|
||||
_unitOfWork.SaveAsync(CancellationToken.None).Wait();
|
||||
|
||||
|
||||
// Seed Accounts
|
||||
|
||||
var isAccountsPresent =
|
||||
_unitOfWork.AccountRepository.GetPageAsync(
|
||||
1, 1, CancellationToken.None)
|
||||
.Result.Items.Any();
|
||||
|
||||
if (isAccountsPresent)
|
||||
{
|
||||
var accounts =
|
||||
new (string Username, string Email,
|
||||
string Password, IdentityRole[] Roles)[]
|
||||
{
|
||||
("admin", "admin", "admin",
|
||||
new [] { IdentityRole.Administrator }),
|
||||
};
|
||||
|
||||
var roles = unitOfWork.RoleRepository
|
||||
.GetPageAsync(1, IdentityRole.Enumerations.Count,
|
||||
CancellationToken.None)
|
||||
.Result.Items;
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
var datastoreAccount =
|
||||
unitOfWork.AccountRepository.GetOneAsync(
|
||||
e => e.Email == account.Email, CancellationToken.None)
|
||||
.Result;
|
||||
|
||||
if (datastoreAccount != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var password = Encoding.UTF8.GetBytes(account.Password);
|
||||
|
||||
var salt = RandomNumberGenerator.GetBytes(128 / 8);
|
||||
var hash = passwordHasher
|
||||
.HashAsync(password, salt, CancellationToken.None)
|
||||
.Result;
|
||||
|
||||
var saltBase64 = Convert.ToBase64String(salt);
|
||||
var hashBase64 = Convert.ToBase64String(hash);
|
||||
|
||||
unitOfWork.AccountRepository.AddOneAsync(
|
||||
new Account()
|
||||
{
|
||||
Username = account.Username,
|
||||
Email = account.Email,
|
||||
PasswordHash = hashBase64,
|
||||
PasswordSalt = saltBase64,
|
||||
AccountRoles = account.Roles.Select(ar =>
|
||||
new AccountRole()
|
||||
{
|
||||
RoleId = roles.Single(dr => dr.Value.Equals(ar)).Id
|
||||
})
|
||||
.ToArray()
|
||||
},
|
||||
CancellationToken.None).Wait();
|
||||
}
|
||||
|
||||
unitOfWork.SaveAsync(CancellationToken.None).Wait();
|
||||
return;
|
||||
}
|
||||
|
||||
unitOfWork.Dispose();
|
||||
var accounts =
|
||||
new (string Username, string Email, IdentityRole[] Roles)[]
|
||||
{
|
||||
("admin", "admin@email.com",
|
||||
new [] { IdentityRole.Administrator }),
|
||||
};
|
||||
|
||||
var roles = _unitOfWork.RoleRepository
|
||||
.GetPageAsync(1, IdentityRole.Enumerations.Count,
|
||||
CancellationToken.None)
|
||||
.Result.Items;
|
||||
|
||||
var datastoreAccounts =
|
||||
_unitOfWork.AccountRepository.GetPageAsync(
|
||||
e => accounts.Select(a => a.Email).Contains(e.Email),
|
||||
1, accounts.Count(), CancellationToken.None)
|
||||
.Result.Items;
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
var datastoreAccount = datastoreAccounts
|
||||
.SingleOrDefault(a => a.Email == account.Email);
|
||||
|
||||
if (datastoreAccount != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var password = Encoding.UTF8.GetBytes(account.Username);
|
||||
|
||||
var salt = RandomNumberGenerator.GetBytes(128 / 8);
|
||||
var hash = _passwordHasher
|
||||
.HashAsync(password, salt, CancellationToken.None)
|
||||
.Result;
|
||||
|
||||
var saltBase64 = Convert.ToBase64String(salt);
|
||||
var hashBase64 = Convert.ToBase64String(hash);
|
||||
|
||||
_unitOfWork.AccountRepository.AddOneAsync(
|
||||
new Account()
|
||||
{
|
||||
Username = account.Username,
|
||||
Email = account.Email,
|
||||
PasswordHash = hashBase64,
|
||||
PasswordSalt = saltBase64,
|
||||
AccountRoles = account.Roles.Select(ar =>
|
||||
new AccountRole()
|
||||
{
|
||||
RoleId = roles.Single(dr => dr.Value.Equals(ar)).Id
|
||||
})
|
||||
.ToArray()
|
||||
},
|
||||
CancellationToken.None).Wait();
|
||||
}
|
||||
|
||||
_unitOfWork.Save();
|
||||
}
|
||||
|
||||
public void SeedData()
|
||||
{
|
||||
var isAddressesPresent =
|
||||
_unitOfWork.AddressRepository.GetPageAsync(
|
||||
1, 1, CancellationToken.None)
|
||||
.Result.Items.Any();
|
||||
|
||||
if (isAddressesPresent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var countries = new Country[]
|
||||
{
|
||||
new Country()
|
||||
{
|
||||
Name = "Country 0"
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var country in countries)
|
||||
{
|
||||
_unitOfWork.CountryRepository
|
||||
.AddOneAsync(country, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
var regions = new Region[]
|
||||
{
|
||||
new Region()
|
||||
{
|
||||
Name = "Region 0",
|
||||
Country = countries[0]
|
||||
},
|
||||
new Region()
|
||||
{
|
||||
Name = "Region 1",
|
||||
Country = countries[0]
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var region in regions)
|
||||
{
|
||||
_unitOfWork.RegionRepository
|
||||
.AddOneAsync(region, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
var cities = new City[]
|
||||
{
|
||||
new City()
|
||||
{
|
||||
Name = "City 0",
|
||||
Region = regions[0]
|
||||
},
|
||||
new City()
|
||||
{
|
||||
Name = "City 1",
|
||||
Region = regions[0]
|
||||
},
|
||||
new City()
|
||||
{
|
||||
Name = "City 2",
|
||||
Region = regions[1]
|
||||
},
|
||||
new City()
|
||||
{
|
||||
Name = "City 3",
|
||||
Region = regions[1]
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var city in cities)
|
||||
{
|
||||
_unitOfWork.CityRepository
|
||||
.AddOneAsync(city, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
var addresses = new Address[]
|
||||
{
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 0",
|
||||
Longitude = 0,
|
||||
Latitude = 0,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[0]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 1",
|
||||
Longitude = 1,
|
||||
Latitude = 1,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[0]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 2",
|
||||
Longitude = 2,
|
||||
Latitude = 2,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[0]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 3",
|
||||
Longitude = 3,
|
||||
Latitude = 3,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[1]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 4",
|
||||
Longitude = 4,
|
||||
Latitude = 4,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[1]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 5",
|
||||
Longitude = 5,
|
||||
Latitude = 5,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[1]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 6",
|
||||
Longitude = 6,
|
||||
Latitude = 6,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[2]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 7",
|
||||
Longitude = 7,
|
||||
Latitude = 7,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[2]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 8",
|
||||
Longitude = 8,
|
||||
Latitude = 8,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[3]
|
||||
},
|
||||
new Address()
|
||||
{
|
||||
Name = "Address 9",
|
||||
Longitude = 9,
|
||||
Latitude = 9,
|
||||
VehicleType = VehicleType.Bus,
|
||||
City = cities[3]
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var address in addresses)
|
||||
{
|
||||
_unitOfWork.AddressRepository
|
||||
.AddOneAsync(address, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
var routes = new Route[]
|
||||
{
|
||||
new Route()
|
||||
{
|
||||
Name = "Route 0",
|
||||
VehicleType = VehicleType.Bus,
|
||||
RouteAddresses = new RouteAddress[]
|
||||
{
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 0,
|
||||
Address = addresses[3]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 1,
|
||||
Address = addresses[6]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 2,
|
||||
Address = addresses[2]
|
||||
}
|
||||
}
|
||||
},
|
||||
new Route()
|
||||
{
|
||||
Name = "Route 1",
|
||||
VehicleType = VehicleType.Bus,
|
||||
RouteAddresses = new RouteAddress[]
|
||||
{
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 0,
|
||||
Address = addresses[1]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 1,
|
||||
Address = addresses[2]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 2,
|
||||
Address = addresses[7]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 3,
|
||||
Address = addresses[9]
|
||||
}
|
||||
}
|
||||
},
|
||||
new Route()
|
||||
{
|
||||
Name = "Route 2",
|
||||
VehicleType = VehicleType.Bus,
|
||||
RouteAddresses = new RouteAddress[]
|
||||
{
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 0,
|
||||
Address = addresses[0]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 1,
|
||||
Address = addresses[1]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 2,
|
||||
Address = addresses[3]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 3,
|
||||
Address = addresses[4]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 4,
|
||||
Address = addresses[7]
|
||||
},
|
||||
new RouteAddress()
|
||||
{
|
||||
Order = 5,
|
||||
Address = addresses[8]
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var route in routes)
|
||||
{
|
||||
_unitOfWork.RouteRepository
|
||||
.AddOneAsync(route, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
var roles = _unitOfWork.RoleRepository
|
||||
.GetPageAsync(1, IdentityRole.Enumerations.Count,
|
||||
CancellationToken.None)
|
||||
.Result.Items;
|
||||
|
||||
var companyOwnerRoleId = roles
|
||||
.SingleOrDefault(
|
||||
e => e.Value == IdentityRole.CompanyOwner)
|
||||
?.Id;
|
||||
|
||||
if (companyOwnerRoleId == null)
|
||||
{
|
||||
throw new InvalidOperationException("Can not find required role.");
|
||||
}
|
||||
|
||||
var companyOwnerAccountCredentials =
|
||||
new (string Username, string Email)[]
|
||||
{
|
||||
("company_owner0", "company_owner0@email.com")
|
||||
};
|
||||
|
||||
var companyOwnerAccounts = new List<Account>();
|
||||
|
||||
foreach (var accountCredential in companyOwnerAccountCredentials)
|
||||
{
|
||||
var password = Encoding.UTF8.GetBytes(accountCredential.Username);
|
||||
|
||||
var salt = RandomNumberGenerator.GetBytes(128 / 8);
|
||||
var hash = _passwordHasher
|
||||
.HashAsync(password, salt, CancellationToken.None)
|
||||
.Result;
|
||||
|
||||
var saltBase64 = Convert.ToBase64String(salt);
|
||||
var hashBase64 = Convert.ToBase64String(hash);
|
||||
|
||||
companyOwnerAccounts.Add(new Account()
|
||||
{
|
||||
Username = accountCredential.Username,
|
||||
Email = accountCredential.Email,
|
||||
PasswordHash = hashBase64,
|
||||
PasswordSalt = saltBase64,
|
||||
AccountRoles = new AccountRole[]
|
||||
{
|
||||
new AccountRole()
|
||||
{
|
||||
RoleId = (long)companyOwnerRoleId
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var account in companyOwnerAccounts)
|
||||
{
|
||||
_unitOfWork.AccountRepository
|
||||
.AddOneAsync(account, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
var companies = new Company[]
|
||||
{
|
||||
new Company()
|
||||
{
|
||||
Name = "Company 0",
|
||||
LegalAddress = "Country 0, Region 0, City 0, Address 0",
|
||||
ContactEmail = "company0@email.com",
|
||||
ContactPhoneNumber = "+000000000000",
|
||||
Account = companyOwnerAccounts[0]
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var company in companies)
|
||||
{
|
||||
_unitOfWork.CompanyRepository
|
||||
.AddOneAsync(company, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
var companyEmployeeRoleId = roles
|
||||
.SingleOrDefault(
|
||||
e => e.Value == IdentityRole.CompanyEmployee)
|
||||
?.Id;
|
||||
|
||||
if (companyEmployeeRoleId == null)
|
||||
{
|
||||
throw new InvalidOperationException("Can not find required role.");
|
||||
}
|
||||
|
||||
var companyEmployeeAccountCredentials =
|
||||
new (string Username, string Email)[]
|
||||
{
|
||||
("company_employee0", "company_employee0@email.com"),
|
||||
("company_employee1", "company_employee1@email.com"),
|
||||
("company_employee2", "company_employee2@email.com")
|
||||
};
|
||||
|
||||
var companyEmployeeAccounts = new List<Account>();
|
||||
var employees = new List<Employee>();
|
||||
|
||||
foreach (var accountCredential in companyEmployeeAccountCredentials)
|
||||
{
|
||||
var password = Encoding.UTF8.GetBytes(accountCredential.Username);
|
||||
|
||||
var salt = RandomNumberGenerator.GetBytes(128 / 8);
|
||||
var hash = _passwordHasher
|
||||
.HashAsync(password, salt, CancellationToken.None)
|
||||
.Result;
|
||||
|
||||
var saltBase64 = Convert.ToBase64String(salt);
|
||||
var hashBase64 = Convert.ToBase64String(hash);
|
||||
|
||||
companyEmployeeAccounts.Add(new Account()
|
||||
{
|
||||
Username = accountCredential.Username,
|
||||
Email = accountCredential.Email,
|
||||
PasswordHash = hashBase64,
|
||||
PasswordSalt = saltBase64,
|
||||
AccountRoles = new AccountRole[]
|
||||
{
|
||||
new AccountRole()
|
||||
{
|
||||
RoleId = (long)companyEmployeeRoleId
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var account in companyEmployeeAccounts)
|
||||
{
|
||||
_unitOfWork.AccountRepository
|
||||
.AddOneAsync(account, CancellationToken.None)
|
||||
.Wait();
|
||||
|
||||
employees.Add(new Employee()
|
||||
{
|
||||
FirstName = $"{account.Username}'s fname",
|
||||
LastName = $"{account.Username}'s lname",
|
||||
Patronymic = $"{account.Username}'s patronymic",
|
||||
Sex =
|
||||
DateTimeOffset.UtcNow.Ticks % 2 == 1 ?
|
||||
Sex.Male : Sex.Female,
|
||||
BirthDate = DateOnly.FromDateTime(
|
||||
DateTimeOffset.UtcNow.Subtract(
|
||||
TimeSpan.FromDays(365 * 20)).Date),
|
||||
Company = companies[0],
|
||||
Documents = new EmployeeDocument[]
|
||||
{
|
||||
new EmployeeDocument()
|
||||
{
|
||||
DocumentType = DocumentType.Passport,
|
||||
Information = $"{account.Username}'s passport"
|
||||
}
|
||||
},
|
||||
Account = account
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var employee in employees)
|
||||
{
|
||||
_unitOfWork.EmployeeRepository
|
||||
.AddOneAsync(employee, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
var vehicles = new Vehicle[]
|
||||
{
|
||||
new Bus()
|
||||
{
|
||||
Number = "XX0000XX",
|
||||
Model = "Model 0",
|
||||
Capacity = 30,
|
||||
Company = companies[0]
|
||||
},
|
||||
new Bus()
|
||||
{
|
||||
Number = "XX1111XX",
|
||||
Model = "Model 1",
|
||||
Capacity = 30,
|
||||
Company = companies[0]
|
||||
},
|
||||
new Bus()
|
||||
{
|
||||
Number = "XX2222XX",
|
||||
Model = "Model 2",
|
||||
Capacity = 30,
|
||||
Company = companies[0]
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var vehicle in vehicles)
|
||||
{
|
||||
_unitOfWork.VehicleRepository
|
||||
.AddOneAsync(vehicle, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
// Vehicle Enrollments (binding between a vehicle and a route,
|
||||
// specifying departure date and time)
|
||||
// and
|
||||
// Route Address Details (for earch address in the route specifying
|
||||
// cost and time of travel from current to next address
|
||||
// and current address stop duration)
|
||||
|
||||
// VE1: 4 -> 7 -> 3
|
||||
// \
|
||||
// VE2: 2 -> 3 -> 8 -> 10
|
||||
// \
|
||||
// VE3: 1 -> 2 -> 4 -> 5 -> 8 -> 9
|
||||
// ---------------------------------> time
|
||||
|
||||
// Vehicle Enrollment 1
|
||||
//
|
||||
// Route: 4 -> 7 -> 3
|
||||
// Departure Time: 2025-01-01 07:30:00.000
|
||||
// Time to Next Address:
|
||||
// 4: P0000-00-00T00:30:00.000
|
||||
// 7: P0000-00-00T00:30:00.000
|
||||
// 3: P0000-00-00T00:00:00.000
|
||||
// Total time moving: 60 minutes
|
||||
// Cost to Next Address:
|
||||
// 4: 5
|
||||
// 7: 11.50
|
||||
// 3: 0
|
||||
// Total: 16.50
|
||||
// Address Stop duration:
|
||||
// 4: P0000-00-00T00:00:00.000
|
||||
// 7: P0000-00-00T00:10:00.000
|
||||
// 3: P0000-00-00T00:00:00.000
|
||||
// Total time in stops: 10 minutes
|
||||
// Total time on road: 70 minutes
|
||||
//
|
||||
// Arriave to 3 at 8:40
|
||||
|
||||
// Vehicle Enrollment 2
|
||||
//
|
||||
// Route: 2 -> 3 -> 8 -> 10
|
||||
// Departure Time: 2025-01-01 08:30:00.000
|
||||
// Time to Next Address:
|
||||
// 2: P0000-00-00T00:20:00.000
|
||||
// 3: P0000-00-00T00:30:00.000
|
||||
// 8: P0000-00-00T00:20:00.000
|
||||
// 10: P0000-00-00T00:00:00.000
|
||||
// Total time moving: 70 minutes
|
||||
// Cost to Next Address:
|
||||
// 2: 4.30
|
||||
// 3: 14.71
|
||||
// 8: 12.10
|
||||
// 10: 0
|
||||
// Total: 21.11
|
||||
// Address Stop duration:
|
||||
// 2: P0000-00-00T00:00:00.000
|
||||
// 3: P0000-00-00T00:10:00.000
|
||||
// 8: P0000-00-00T00:10:00.000
|
||||
// 10: P0000-00-00T00:00:00.000
|
||||
// Total time in stops: 20 minutes
|
||||
// Total time on road: 90 minutes
|
||||
//
|
||||
// Arrive to 3 at 8:50
|
||||
// Arrive to 8 at 9:30
|
||||
|
||||
// Vehicle Enrollment 3
|
||||
//
|
||||
// Route: 1 -> 2 -> 4 -> 5 -> 8 -> 9
|
||||
// Departure Time: 2025-01-01 07:30:00.000
|
||||
// Time to Next Address:
|
||||
// 1: P0000-00-00T00:30:00.000
|
||||
// 2: P0000-00-00T00:20:00.000
|
||||
// 4: P0000-00-00T00:30:00.000
|
||||
// 5: P0000-00-00T00:30:00.000
|
||||
// 8: P0000-00-00T00:30:00.000
|
||||
// 9: P0000-00-00T00:00:00.000
|
||||
// Total time moving: 140 minutes
|
||||
// Cost to Next Address:
|
||||
// 1: 5
|
||||
// 2: 10
|
||||
// 4: 11.2
|
||||
// 5: 5.23
|
||||
// 8: 5.2
|
||||
// 9: 0
|
||||
// Total: 36.63
|
||||
// Address Stop duration:
|
||||
// 1: P0000-00-00T00:00:00.000
|
||||
// 2: P0000-00-00T00:10:00.000
|
||||
// 4: P0000-00-00T00:10:00.000
|
||||
// 5: P0000-00-00T00:10:00.000
|
||||
// 8: P0000-00-00T00:10:00.000
|
||||
// 9: P0000-00-00T00:00:00.000
|
||||
// Total time in stops: 40 minutes
|
||||
// Total time on road: 180 minutes
|
||||
//
|
||||
// Arrive to 8 at 9:40
|
||||
|
||||
var vehicleEnrollments = new VehicleEnrollment[]
|
||||
{
|
||||
new VehicleEnrollment()
|
||||
{
|
||||
DepartureTime = DateTimeOffset.UtcNow.AddDays(1),
|
||||
Currency = Currency.EUR,
|
||||
Vehicle = vehicles[0],
|
||||
Route = routes[0],
|
||||
RouteAddressDetails = new RouteAddressDetail[]
|
||||
{
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(30),
|
||||
CostToNextAddress = 5,
|
||||
CurrentAddressStopTime = TimeSpan.Zero,
|
||||
RouteAddress = routes[0].RouteAddresses.ElementAt(0)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(30),
|
||||
CostToNextAddress = 11.5M,
|
||||
CurrentAddressStopTime = TimeSpan.FromMinutes(10),
|
||||
RouteAddress = routes[0].RouteAddresses.ElementAt(1)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.Zero,
|
||||
CostToNextAddress = 0,
|
||||
CurrentAddressStopTime = TimeSpan.Zero,
|
||||
RouteAddress = routes[0].RouteAddresses.ElementAt(2)
|
||||
}
|
||||
},
|
||||
VehicleEnrollmentEmployees = new VehicleEnrollmentEmployee[]
|
||||
{
|
||||
new VehicleEnrollmentEmployee()
|
||||
{
|
||||
Employee = employees[0]
|
||||
}
|
||||
}
|
||||
},
|
||||
new VehicleEnrollment()
|
||||
{
|
||||
DepartureTime = DateTimeOffset.UtcNow.AddDays(1).AddHours(1),
|
||||
Currency = Currency.UAH,
|
||||
Vehicle = vehicles[1],
|
||||
Route = routes[1],
|
||||
RouteAddressDetails = new RouteAddressDetail[]
|
||||
{
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(20),
|
||||
CostToNextAddress = 4.3M,
|
||||
CurrentAddressStopTime = TimeSpan.Zero,
|
||||
RouteAddress = routes[1].RouteAddresses.ElementAt(0)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(30),
|
||||
CostToNextAddress = 14.71M,
|
||||
CurrentAddressStopTime = TimeSpan.FromMinutes(10),
|
||||
RouteAddress = routes[1].RouteAddresses.ElementAt(1)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(20),
|
||||
CostToNextAddress = 12.1M,
|
||||
CurrentAddressStopTime = TimeSpan.FromMinutes(10),
|
||||
RouteAddress = routes[1].RouteAddresses.ElementAt(2)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.Zero,
|
||||
CostToNextAddress = 0,
|
||||
CurrentAddressStopTime = TimeSpan.Zero,
|
||||
RouteAddress = routes[1].RouteAddresses.ElementAt(3)
|
||||
}
|
||||
},
|
||||
VehicleEnrollmentEmployees = new VehicleEnrollmentEmployee[]
|
||||
{
|
||||
new VehicleEnrollmentEmployee()
|
||||
{
|
||||
Employee = employees[1]
|
||||
}
|
||||
}
|
||||
},
|
||||
new VehicleEnrollment()
|
||||
{
|
||||
DepartureTime = DateTimeOffset.UtcNow.AddDays(1),
|
||||
Currency = Currency.USD,
|
||||
Vehicle = vehicles[2],
|
||||
Route = routes[2],
|
||||
RouteAddressDetails = new RouteAddressDetail[]
|
||||
{
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(30),
|
||||
CostToNextAddress = 5,
|
||||
CurrentAddressStopTime = TimeSpan.Zero,
|
||||
RouteAddress = routes[2].RouteAddresses.ElementAt(0)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(20),
|
||||
CostToNextAddress = 10,
|
||||
CurrentAddressStopTime = TimeSpan.FromMinutes(10),
|
||||
RouteAddress = routes[2].RouteAddresses.ElementAt(1)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(30),
|
||||
CostToNextAddress = 11.2M,
|
||||
CurrentAddressStopTime = TimeSpan.FromMinutes(10),
|
||||
RouteAddress = routes[2].RouteAddresses.ElementAt(2)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(30),
|
||||
CostToNextAddress = 5.23M,
|
||||
CurrentAddressStopTime = TimeSpan.FromMinutes(10),
|
||||
RouteAddress = routes[2].RouteAddresses.ElementAt(3)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.FromMinutes(30),
|
||||
CostToNextAddress = 5.2M,
|
||||
CurrentAddressStopTime = TimeSpan.FromMinutes(10),
|
||||
RouteAddress = routes[2].RouteAddresses.ElementAt(4)
|
||||
},
|
||||
new RouteAddressDetail()
|
||||
{
|
||||
TimeToNextAddress = TimeSpan.Zero,
|
||||
CostToNextAddress = 0,
|
||||
CurrentAddressStopTime = TimeSpan.Zero,
|
||||
RouteAddress = routes[2].RouteAddresses.ElementAt(5)
|
||||
}
|
||||
},
|
||||
VehicleEnrollmentEmployees = new VehicleEnrollmentEmployee[]
|
||||
{
|
||||
new VehicleEnrollmentEmployee()
|
||||
{
|
||||
Employee = employees[2]
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
foreach (var enrollment in vehicleEnrollments)
|
||||
{
|
||||
_unitOfWork.VehicleEnrollmentRepository
|
||||
.AddOneAsync(enrollment, CancellationToken.None)
|
||||
.Wait();
|
||||
}
|
||||
|
||||
|
||||
_unitOfWork.Save();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_unitOfWork.Dispose();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user