We have following endpoint on our api that should grab some events from db, aggregate them and output as a json. But I am having hard time reading this function and hope you could help me out with some ideas how to refactor this to something more reasonable. Or maybe its fine and I just need to read harder?
[HttpGet]
public AmazonDTO GetCRSTimeStatuses(string countryId, string regionId, string storeId, string dateFrom, string dateTo)
{
List<CRSTimeStatus> res = new List<CRSTimeStatus>();
try
{
DateTime _dateFrom;
DateTime.TryParse(dateFrom, out _dateFrom);
_dateFrom = _dateFrom.Date;
DateTime _dateTo;
DateTime.TryParse(dateTo, out _dateTo);
int _countryId;
int.TryParse(countryId, out _countryId);
int _regionId;
int.TryParse(regionId, out _regionId);
int _storeId;
int.TryParse(storeId, out _storeId);
PageDetailType _pageDetailType = ModelHelper.GetActualPageType(_countryId, _regionId, _storeId, tillId: 0);
var eventValue = _cache.Get<List<Event>>("eventsChache");
var events = new List<Event>();
var countries = new List<Country>();
// Read base relation data from DB.
countries = _countryRepository.GetAll().ToList();
_regionRepository.GetAll().ToList();
_storeRepository.GetAll().ToList();
_askoTillRepository.GetAll().ToList();
if (_hostingEnvironment.IsDevelopment())
{
EventCache evc = new EventCache(_eventRepository, _cache);
evc.SetEventsCache(_dateFrom, _dateTo);
}
events = _cache.Get<List<Event>>("eventsChache");
Dictionary<int, List<Event>> eventsForPos = new Dictionary<int, List<Event>>();
events = events == null ? new List<Event>() : events;
var forEvets = events.FindAll(x => x.DateFrom >= _dateFrom && (x.DateTo <= _dateTo || !x.DateTo.HasValue));
foreach (Event e in forEvets)
{
if (eventsForPos.ContainsKey(e.PosTillId))
{
eventsForPos[e.PosTillId].Add(e);
}
else
{
eventsForPos[e.PosTillId] = new List<Event>() { e };
}
}
foreach (var item in countries)
{
var tills = item.Regions.SelectMany(t => t.Stores.Where(e => e.PosTills != null).SelectMany(r => r.PosTills));
foreach (var till in tills)
{
till.Events = eventsForPos.ContainsKey(till.Id) ? eventsForPos[till.Id] : null;
}
}
switch ((PageDetailType)_pageDetailType)
{
case PageDetailType.CountriesDetail:
break;
case PageDetailType.CountryDetail:
res = ModelHelper.GetGraphStatusesCountry(countries, _countryId);
break;
case PageDetailType.RegionDetail:
res = ModelHelper.GetGraphStatusesRegion(countries, _regionId);
break;
case PageDetailType.StoreDetail:
res = ModelHelper.GetGraphStatusesStore(countries, _storeId);
break;
case PageDetailType.TillDetail:
break;
default:
break;
}
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
return AmazonDTO.Error(((int)HttpException.InternetServerError).ToString(), ex.ToString());
}
return AmazonDTO.Data(res);
}
My initial suggestion is to remove data parsing at the start and move it elsewhere. The code also looks like it is trying to do three things at once based on incoming parameters, maybe split it into three endpoints or use some form of inheritance would help here.
Any ideas are welcomed!