using APP.Domain;
using APP.Models;
using CORE.APP.Models;
using CORE.APP.Services;
using CORE.APP.Services.Files.MVC;
using Microsoft.EntityFrameworkCore;
namespace APP.Services
{
public class CityService : Service<City>, IService<CityRequest, CityResponse>
{
private readonly FileServiceBase _fileService;
public CityService(DbContext db, FileServiceBase fileService) : base(db)
{
_fileService = fileService;
}
protected override IQueryable<City> Query(bool isNoTracking = true)
{
return base.Query(isNoTracking).Include(c => c.Country).OrderBy(c => c.Country.CountryName).ThenBy(c => c.CityName);
}
public CommandResponse Create(CityRequest request)
{
if (Query().Any(c => c.CityName == request.CityName.Trim()))
return Error("City with the same name exists!");
// save city's image file to wwwroot/files folder if an image file is chosen by the user
var filePath = _fileService.GetFilePath(request.FormFile);
var fileResponse = _fileService.SaveFile(request.FormFile, filePath);
if (!fileResponse.IsSuccessful)
return Error(fileResponse.Message);
var city = new City
{
CityName = request.CityName?.Trim(),
CountryId = request.CountryId ?? 0,
FilePath = filePath // set the saved city's image file path if an image file is chosen by the user, otherwise null is set
};
Create(city);
return Success("City created successfully.", city.Id);
}
public CommandResponse Delete(int id)
{
var city = Query(false).SingleOrDefault(c => c.Id == id); // isNoTracking is false for being tracked by EF Core to delete the entity
if (city is null)
return Error("City not found!");
// delete the city's image file from wwwroot/files folder if an image file exists
_fileService.DeleteFile(city.FilePath);
Delete(city);
return Success("City deleted successfully.", city.Id);
}
public CityRequest Edit(int id)
{
var city = Query().SingleOrDefault(c => c.Id == id);
if (city is null)
return null;
return new CityRequest
{
Id = city.Id,
CityName = city.CityName,
CountryId = city.CountryId
};
}
public CityResponse Item(int id)
{
var city = Query().SingleOrDefault(c => c.Id == id);
if (city is null)
return null;
return new CityResponse
{
Id = city.Id,
Guid = city.Guid,
CityName = city.CityName,
Country = new CountryResponse
{
Id = city.Country.Id,
Guid = city.Country.Guid,
CountryName = city.Country.CountryName
},
FilePath = city.FilePath // city image file's path in wwwroot/files folder
};
}
public List<CityResponse> List()
{
return Query().Select(city => new CityResponse
{
Id = city.Id,
Guid = city.Guid,
CityName = city.CityName,
Country = new CountryResponse
{
Id = city.Country.Id,
Guid = city.Country.Guid,
CountryName = city.Country.CountryName
},
FilePath = city.FilePath // city image file's path in wwwroot/files folder
}).ToList();
}
public CommandResponse Update(CityRequest request)
{
if (Query().Any(c => c.Id != request.Id && c.CityName == request.CityName.Trim()))
return Error("City with the same name exists!");
var city = Query(false).SingleOrDefault(c => c.Id == request.Id); // isNoTracking is false for being tracked by EF Core to update the entity
if (city is null)
return Error("City not found!");
// save city's new image file to wwwroot/files folder and delete the old image file, then update the City entity's file path
// with the new image file's path if a new image file is chosen by the user
var filePath = _fileService.GetFilePath(request.FormFile);
if (!string.IsNullOrWhiteSpace(filePath))
{
var fileResponse = _fileService.SaveFile(request.FormFile, filePath);
if (!fileResponse.IsSuccessful)
return Error(fileResponse.Message);
_fileService.DeleteFile(city.FilePath);
city.FilePath = filePath;
}
city.CityName = request.CityName?.Trim();
city.CountryId = request.CountryId ?? 0;
Update(city);
return Success("City updated successfully.", city.Id);
}
// get a filtered list of City response items filtered by country ID,
// if countryId is null, return an empty City response list
public List<CityResponse> List(int? countryId)
{
// if countryId is null, return an empty City response list
if (!countryId.HasValue) // if (countryId == null) or if (countryId is null) may also be written
return new List<CityResponse>();
// filter the City entity query by countryId value and project the City entity query to City response query then return the list
return Query().Where(c => c.CountryId == countryId.Value).Select(c => new CityResponse
{
Id = c.Id,
Guid = c.Guid,
CityName = c.CityName
}).ToList();
}
// delete a city's image file by city ID and image file path, set the city entity's FilePath property to null and update the Cities table
public void DeleteFile(int id, string filePath)
{
_fileService.DeleteFile(filePath); // delete the image file from wwwroot/files folder
// set the city entity's FilePath property to null
var city = Query(false).SingleOrDefault(c => c.Id == id); // isNoTracking is false for being tracked by EF Core to update the entity
if (city is not null)
city.FilePath = null;
Update(city); // update the Cities table with no image file
}
}
}