<repo_name>philgung/TUI_SimulatorFlightCosts<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/ControlTower.cs
﻿using System.Collections.Generic;
using TUI.SimulatorFlights.Domain;

namespace TUI.Domain.SimulatorFlights
{
    public class ControlTower : IFlightsManager, IFlightsSimulator
    {
        private readonly IPersistenceService _persistenceService;

        public ControlTower(IPersistenceService persistenceService)
        {
            _persistenceService = persistenceService;
        }

        public double CalculateDistance(string flightName)
        {
            var flight = GetFlight(flightName);
            var distanceTraveled = flight.CalculateDistance();
            _persistenceService.SaveReport(flightName, CalculType.CalculateDistance, distanceTraveled);
            return distanceTraveled;
        }

        public double CalculateFuelConsumption(string flightName)
        {
            var flight = GetFlight(flightName);

            var fuelConsumption = flight.CalculateFuelConsumption();
            _persistenceService.SaveReport(flightName, CalculType.CalculateFuelConsumption, fuelConsumption);
            return fuelConsumption;
        }

        public IFlight GetFlight(string flightName)
        {
            return _persistenceService.GetFlight(flightName);
        }

        public void RegisterFlight(IFlight flight)
        {
            _persistenceService.SaveFlight(flight);            
        }

        public ICollection<Report> GetReports()
        {
            return _persistenceService.GetReports();
        }

        public ICollection<IFlight> GetFlights()
        {
            return _persistenceService.GetFlights();
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/Tests/TUI_GeoCoordinateTests/GeoCoordinateTests.cs
using FluentAssertions;
using GeoCoordinatePortable;
using Xunit;

namespace TUI_GeoCoordinateTests
{
    public class GeoCoordinateTests
    {
        [Fact]
        public void CalculateDistanceBetweenParisAirportAndLondonAirport()
        {
            // Arrange
            var latitudeAirportRoissy = 49.007;
            var longitudeAirportRoissy = 2.559790000000021;

            var roissyAirportGPSPosition = new GeoCoordinate(latitudeAirportRoissy, longitudeAirportRoissy);

            var latitudeAirportLondon = 51.5048;
            var longitudeAirportLondon = 0.052745500000014545;

            var londonAirportGPSPosition = new GeoCoordinate(latitudeAirportLondon, longitudeAirportLondon);
            var expectedDistance = 330.25267832631079;
            // Act
            var distanceKmCalculated = londonAirportGPSPosition.GetDistanceTo(roissyAirportGPSPosition) / 1000;
            // Assert
            distanceKmCalculated.Should().Be(expectedDistance);

        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Infrastructure/TUI.SimulatorFlights.Infrastructure/FlightAdapter.cs
﻿using TUI.Domain.SimulatorFlights;
using TUI.SimulatorFlights.Infrastructure.DTO;

namespace TUI.SimulatorFlights.Infrastructure
{
    public static class FlightAdapter
    {
        public static IFlight ToFlight(this FlightDTO flightDTO)
        {
            var flight = new Flight(flightDTO.flight_name);
            flight.SetFuelConsumptionPerDistance(flightDTO.fuel_consumption_per_distance);
            flight.SetFuelConsumptionTakeoffEffort(flightDTO.fuel_consumption_takeoff_effort);
            flight.RegisterDepartureAirport(flightDTO.departure_airport_name, flightDTO.departure_airport_latitude, flightDTO.departure_airport_longitude);
            flight.RegisterDestinationAirport(flightDTO.destination_airport_name, flightDTO.destination_airport_latitude, flightDTO.destination_airport_longitude);
            return flight;
            
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Infrastructure/TUI.SimulatorFlights.Infrastructure/DTO/ReportDTO.cs
﻿namespace TUI.SimulatorFlights.Infrastructure.DTO
{
    public class ReportDTO
    {
        public string Flight_name { get; set; }
        public string CalculType { get; set; }
        public double Result { get; set; }
        public string CalculDate { get; set; }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/GPSPosition.cs
﻿namespace TUI.Domain.SimulatorFlights
{
    public struct GPSPosition
    {
        public double Latitude { get; }
        public double Longitude { get; }

        public GPSPosition(double latitude, double longitude)
        {
            this.Latitude = latitude;
            this.Longitude = longitude;
        }
    }
}<file_sep>/TUI_SimulatorFlightCosts/Presentation/TUI_SimulatorFlightCosts.Web/Adapters/ReportModelAdapter.cs
﻿using TUI.SimulatorFlights.Domain;
using TUI_SimulatorFlightCosts.Web.Models;

namespace TUI_SimulatorFlightCosts.Web.Adapters
{
    public static class ReportModelAdapter
    {
        public static ReportModel ToReportModel(this Report report)
        {
            return new ReportModel
            {
                FlightName = report.FlightName,
                CalculType = report.CalculType == CalculType.CalculateDistance ? "Distance Traveled" : "Consumption Fuel",
                CalculDate = report.CalculDate.ToShortDateString(),
                Result = report.CalculType == CalculType.CalculateDistance ? $"{report.Result.ToString("0.00000")} km" : $"{report.Result.ToString("0.00000")} L"
            };
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/Flight.cs
﻿using TUI.SimulatorFlights.Domain.Extensions;

namespace TUI.Domain.SimulatorFlights
{
    public class Flight : IFlight
    {
        public Airport DepartureAirport { get; private set; }
        public Airport DestinationAirport { get; private set; }

        public string Name { get; private set; }
        public int FuelConsumptionPerDistance { get; private set; }
        public int FuelConsumptionTakeoffEffort { get; private set; }

        public Flight(string flightName)
        {
            this.Name = flightName;
        }

        public double CalculateDistance()
        {
            return DepartureAirport.GetDistanceTo(DestinationAirport);
        }

        public double CalculateFuelConsumption()
        {
            return (CalculateDistance() * FuelConsumptionPerDistance) + FuelConsumptionTakeoffEffort;
        }

        public void RegisterDepartureAirport(string airportName, double latitude, double longitude)
        {
            DepartureAirport = new Airport(airportName, new GPSPosition(latitude, longitude));
        }

        public void RegisterDestinationAirport(string airportName, double latitude, double longitude)
        {
            DestinationAirport = new Airport(airportName, new GPSPosition(latitude, longitude));
        }

        public void SetFuelConsumptionPerDistance(int fuelConsumptionPerDistance)
        {
            FuelConsumptionPerDistance = fuelConsumptionPerDistance;
        }

        public void SetFuelConsumptionTakeoffEffort(int fuelConsumptionTakeoffEffort)
        {
            FuelConsumptionTakeoffEffort = fuelConsumptionTakeoffEffort;
        }

        public void Rename(string flightName)
        {
            Name = flightName;
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Infrastructure/TUI.SimulatorFlights.Infrastructure/ReportAdapter.cs
﻿using System;
using TUI.SimulatorFlights.Domain;
using TUI.SimulatorFlights.Infrastructure.DTO;

namespace TUI.SimulatorFlights.Infrastructure
{
    public static class ReportAdapter
    {
        public static Report ToReport(this ReportDTO reportDTO)
        {
            return new Report
            {
                FlightName = reportDTO.Flight_name,
                CalculType = Enum.Parse<CalculType>(reportDTO.CalculType),
                Result = reportDTO.Result,
                CalculDate = DateTime.Parse(reportDTO.CalculDate)
            };
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Presentation/TUI_SimulatorFlightCosts.Web/Models/ReportModel.cs
﻿namespace TUI_SimulatorFlightCosts.Web.Models
{
    public class ReportModel
    {
        public string FlightName { get; set; }
        public string CalculType { get; set; }
        public string Result { get; set; }
        public string CalculDate { get; set; }

    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/Report.cs
﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TUI.SimulatorFlights.Domain
{
    public enum CalculType
    {
        CalculateDistance,
        CalculateFuelConsumption
    }
    public class Report
    {
        public string FlightName { get; set; }
        public CalculType CalculType { get; set; }
        public double Result { get; set; }
        public DateTime CalculDate { get; set; }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Presentation/TUI_SimulatorFlightCosts.Web/Controllers/HomeController.cs
﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.Diagnostics;
using System.Linq;
using TUI.SimulatorFlights.Domain;
using TUI_SimulatorFlightCosts.Application;
using TUI_SimulatorFlightCosts.Web.Adapters;
using TUI_SimulatorFlightCosts.Web.Models;
using UI_SimulatorFlightCosts.Web.Models;

namespace TUI_SimulatorFlightCosts.Web.Controllers
{
    public class HomeController : Controller
    {
        private FlightSimulatorService _flightSimulatorService;

        public HomeController(IPersistenceService persistenceService, IConfiguration configuration)
        {
            persistenceService.InitializeService(ConfigurationExtensions.GetConnectionString(configuration, "DefaultConnection"));
            _flightSimulatorService = new FlightSimulatorService(persistenceService);
        }
        public IActionResult Index()
        {
            var flights = _flightSimulatorService.GetFlights();            
            return View(new HomeModel()
            {
                Flights = flights
            });
        }

        public IActionResult Edit(string flightName)
        {
            if (!string.IsNullOrEmpty(flightName))
            {
                var flight = _flightSimulatorService.GetFlight(flightName);
                if (flight != null)
                    return View(flight.ToFlightModel());
            }
           
            return View();
        }

        [HttpPost]
        public IActionResult Edit(FlightModel flightModel)
        {
            _flightSimulatorService.Save(flightModel.ToFlight());
            return View();
        }

        public JsonResult CalculDistance(string flightName)
        {
            var distance = _flightSimulatorService.CalculateDistance(flightName);
            return Json(distance);
        }

        public JsonResult CalculConsumptionFuel(string flightName)
        {
            var consumptionFuel = _flightSimulatorService.CalculateFuelConsumption(flightName);
            return Json(consumptionFuel);
        }

        public IActionResult Report()
        {
            var reports = _flightSimulatorService.GetReports()?.Select(x => x.ToReportModel());
            return View(reports);
        }

       
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/IFlightsSimulator.cs
﻿using System.Collections.Generic;
using TUI.Domain.SimulatorFlights;

namespace TUI.SimulatorFlights.Domain
{
    public interface IFlightsSimulator
    {
        double CalculateDistance(string flightName);
        double CalculateFuelConsumption(string flightName);
        ICollection<Report> GetReports();
    }
}
<file_sep>/TUI_SimulatorFlightCosts/TUI_SimulatorFlightCosts_AcceptanceTests/Calculate_Flight_Distance_And_Fuel_Needed_Steps.cs
﻿using FluentAssertions;
using TechTalk.SpecFlow;
using TUI.Domain.SimulatorFlights;
using TUI.SimulatorFlights.Infrastructure;

namespace TUI_SimulatorFlightCosts_AcceptanceTests
{
    [Binding]
    public class Calculate_Flight_Distance_And_Fuel_NeededSteps
    {
        private Flight _currentFlight;
        private ControlTower _currentControlTower;
        private double _distanceKm, _fuelConsumption;

        public Calculate_Flight_Distance_And_Fuel_NeededSteps()
        {
            var persistenceService = new SQLLitePersistenceService();
            persistenceService.InitializeService(@"Data Source=..\..\..\..\Sqlite\TUI.SimulatorFlights.sqlite;Version=3;");
            _currentControlTower = new ControlTower(persistenceService);
            _currentFlight = new Flight("currentFlight");
        }


        [Given(@"A flight which has a departure airport with GPS Position \((.*) - (.*), (.*)\)")]
        public void GivenAFlightWhichHasADepartureAirportWithGPSPositionLondon_(string airportName, double latitude, double longitude)
        {
            _currentFlight.RegisterDepartureAirport(airportName, latitude, longitude);
        }        
        
        [Given(@"has a destination airport with GPS Position \((.*) - (.*), (.*)\)")]
        public void GivenHasADestinationAirportWithGPSPosition(string airportName, double latitude, double longitude)
        {
            _currentFlight.RegisterDestinationAirport(airportName, latitude, longitude);
        }
        
        [Given(@"the aircraft fuel consumption per distance/flight time \((.*) L/km\) \+ takeoff effort \((.*) L\)")]
        public void GivenTheAircraftFuelConsumptionPerDistanceFlightTimeLKmHTakeoffEffortLKmH(int fuelConsumptionPerDistancePerFlightTime, int fuelConsumptionTakeoffEffort)
        {
            _currentFlight.SetFuelConsumptionPerDistance(fuelConsumptionPerDistancePerFlightTime);
            _currentFlight.SetFuelConsumptionTakeoffEffort(fuelConsumptionTakeoffEffort);
        }       

        [Given(@"is registered in control tower like '(.*)'")]
        public void GivenIsRegisteredInControlTowerLike(string flightName)
        {
            _currentFlight.Rename(flightName);
            _currentControlTower.RegisterFlight(_currentFlight);
        }


        [When(@"the simulator calculate travel distance for the flight '(.*)'")]
        public void WhenTheFlightTakesPlace(string flightName)
        {
            _distanceKm = _currentControlTower.CalculateDistance(flightName);
        }

        [When(@"the simulator calculate the fuel consumption for the flight '(.*)'")]
        public void WhenTheFuelConsumptionSimulatorCalculate(string flightName)
        {
            _fuelConsumption = _currentControlTower.CalculateFuelConsumption(flightName);
        }


        [Then(@"the travel distance was (.*) km")]
        public void ThenTheTravelDistanceWasKm(double distanceExpected)
        {
            _distanceKm.Should().Be(distanceExpected);
        }
        
        [Then(@"the total fuel consumption was (.*) L")]
        public void ThenTheTotalFuelConsumptionWasL(double fuelConsumptionExpected)
        {
            _fuelConsumption.Should().Be(fuelConsumptionExpected);
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Presentation/TUI.SimulatorFlights.InitDBSqlite/Program.cs
﻿using System;
using TUI.SimulatorFlights.Infrastructure;

namespace TUI.SimulatorFlights.InitDBSqlite
{
    class Program
    {
        static void Main(string[] args)
        {
            var service = new SQLLitePersistenceService();
            Console.WriteLine("SQLite : Initialize table");
            service.InitializeTables();
            Console.WriteLine("SQLite : Tables were created.");
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Application/TUI_SimulatorFlightCosts.Application/FlightSimulatorService.cs
﻿using System.Collections.Generic;
using TUI.Domain.SimulatorFlights;
using TUI.SimulatorFlights.Domain;

namespace TUI_SimulatorFlightCosts.Application
{
    public class FlightSimulatorService
    {
        private readonly ControlTower _controlTower;

        public FlightSimulatorService(IPersistenceService persistenceService)
        {
            _controlTower = new ControlTower(persistenceService);
        }

        public ICollection<IFlight> GetFlights()
        {
            return _controlTower.GetFlights();
        }

        public IFlight GetFlight(string flightName)
        {
            return _controlTower.GetFlight(flightName);
        }

        public void Save(IFlight flight)
        {
            _controlTower.RegisterFlight(flight);
        }

        public ICollection<Report> GetReports()
        {
            return _controlTower.GetReports();
        }

        public double CalculateDistance(string flightName)
        {
            return _controlTower.CalculateDistance(flightName);
        }

        public double CalculateFuelConsumption(string flightName)
        {
            return _controlTower.CalculateFuelConsumption(flightName);
        }
    }
}<file_sep>/TUI_SimulatorFlightCosts/Infrastructure/TUI.SimulatorFlights.Infrastructure/DTO/FlightDTO.cs
﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TUI.SimulatorFlights.Infrastructure.DTO
{
    public class FlightDTO
    {
        public string flight_name { get; set; }
        public int fuel_consumption_per_distance { get; set; }
        public int fuel_consumption_takeoff_effort { get; set; }
        public string departure_airport_name { get; set; }
        public double departure_airport_latitude { get; set; }
        public double departure_airport_longitude { get; set; }
        public string destination_airport_name { get; set; }
        public double destination_airport_latitude { get; set; }
        public double destination_airport_longitude { get; set; }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Presentation/TUI_SimulatorFlightCosts.Web/Models/FlightModel.cs
﻿using System.ComponentModel.DataAnnotations;

namespace TUI_SimulatorFlightCosts.Web.Models
{
    public class FlightModel
    {
        [Display(Name="Flight Name")]
        [Required]
        public string Name { get; set; }
        [Display(Name = "Fuel consumption per distance")]
        public int FuelConsumptionPerDistance { get; set; }
        [Display(Name = "Fuel consumption at takeoff effort")]
        public int FuelConsumptionTakeoffEffort { get; set; }
        [Display(Name = "Departure airport name")]
        public string DepartureAirportName { get; set; }
        [Display(Name = "Departure airport latitude")]
        public double DepartureAiportLatitude { get; set; }
        [Display(Name = "Departure airport longitude")]
        public double DepartureAirportLongitude { get; set; }
        [Display(Name = "Destination airport name")]
        public string DestinationAirportName { get; set; }
        [Display(Name = "Destination airport latitude")]
        public double DestinationAirportLatitude { get; set; }
        [Display(Name = "Destination airport longitude")]
        public double DestinationAirportLongitude { get; set; }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Application/Tests/TUI_SimulatorFlightCosts.App.Tests/FlightSimulatorServiceTests.cs
using FluentAssertions;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using TUI.Domain.SimulatorFlights;
using TUI.SimulatorFlights.Domain;
using TUI_SimulatorFlightCosts.Application;
using Xunit;

namespace TUI_SimulatorFlightCosts.App.Tests
{
    public class FlightSimulatorServiceTests
    {
        Mock<IPersistenceService> _persistenceServiceMock;
        const string _flightName = "FlightTest";
        FlightSimulatorService _flightSimulatorService;

        public FlightSimulatorServiceTests()
        {
            _persistenceServiceMock = new Mock<IPersistenceService>();
            _flightSimulatorService = new FlightSimulatorService(_persistenceServiceMock.Object);
        }
        
        [Fact]
        public void GetFlights()
        {
            // Arrange
            _persistenceServiceMock.Setup(x => x.GetFlights()).Returns(new List<IFlight> { new Flight(_flightName) });
            // Act
            var flights = _flightSimulatorService.GetFlights();
            // Assert
            flights.Should().NotBeEmpty();
            flights.Should().HaveCount(1);
            flights.First().Name.Should().Be(_flightName);
        }

        [Fact]
        public void GetFlightByName()
        {
            // Arrange
            _persistenceServiceMock.Setup(x => x.GetFlight(_flightName)).Returns(new Flight(_flightName));
            // Act
            var flight = _flightSimulatorService.GetFlight(_flightName);
            // Assert
            flight.Name.Should().Be(_flightName);
        }

        [Fact]
        public void SaveFlight()
        {
            // Arrange
            // Act
            _flightSimulatorService.Save(new Flight(_flightName));
            // Assert
            _persistenceServiceMock.Verify(x => x.SaveFlight(It.IsAny<IFlight>()), Times.Once);
        }

        [Fact]
        public void GetReports()
        {
            // Arrange
            _persistenceServiceMock.Setup(x => x.GetReports()).Returns(new List<Report> {
                new Report { FlightName = "test", CalculType = CalculType.CalculateDistance, Result = 633.445, CalculDate = new DateTime(2019, 04, 08) },
                new Report { FlightName = "test2", CalculType = CalculType.CalculateFuelConsumption, Result = 699.001, CalculDate = new DateTime(2019, 04, 08) }});
            // Act
            var reports = _flightSimulatorService.GetReports();
            // Assert
            reports.Should().NotBeEmpty();
            reports.Should().HaveCount(2);
            reports.First().CalculType.Should().Be(CalculType.CalculateDistance);
            reports.Last().CalculType.Should().Be(CalculType.CalculateFuelConsumption);
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/IPersistenceService.cs
﻿using System.Collections.Generic;
using TUI.Domain.SimulatorFlights;

namespace TUI.SimulatorFlights.Domain
{
    public interface IPersistenceService
    {
        void InitializeService(string connectionString);
        void SaveFlight(IFlight flight);
        IFlight GetFlight(string flightName);

        ICollection<IFlight> GetFlights();

        void SaveReport(string flightName, CalculType calculType, double result);
        ICollection<Report> GetReports();
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/Tests/TUI_SimulatorFlightsDomainTests/FlightTests.cs
﻿using FluentAssertions;
using TUI.Domain.SimulatorFlights;
using Xunit;

namespace TUI_SimulatorFlightCostsTests
{
    public class FlightTests
    {
        const string _flightName = "Roissy <NAME> - London";

        [Fact]
        public void CalculateDistance()
        {
            // Arrange
            var flight = new Flight(_flightName);
            flight.RegisterDepartureAirport("Roissy Charles de Gaulle", 49.007, 2.559790000000021);
            flight.RegisterDestinationAirport("London", 51.5048, 0.052745500000014545);
            // Act
            var distance = flight.CalculateDistance();
            // Assert
            distance.Should().Be(330.25267832631079);
        }

        [Fact]
        public void CalculateFuelConsumption()
        {
            // Arrange
            var flight = new Flight(_flightName);
            flight.RegisterDepartureAirport("Roissy Charles de Gaulle", 49.007, 2.559790000000021);
            flight.RegisterDestinationAirport("London", 51.5048, 0.052745500000014545);            
            flight.SetFuelConsumptionPerDistance(1000);
            flight.SetFuelConsumptionTakeoffEffort(2000);

            // Act
            var fuelConsumption = flight.CalculateFuelConsumption();
            // Assert
            fuelConsumption.Should().Be(332252.67832631076);
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/Extensions/GeoCoordinateExtensions.cs
﻿using GeoCoordinatePortable;
using TUI.Domain.SimulatorFlights;

namespace TUI.SimulatorFlights.Domain.Extensions
{
    public static class GeoCoordinateExtensions
    {
        public static double GetDistanceTo(this Airport departureAirport, Airport destinationAirport)
        {
            var departurePosition = new GeoCoordinate(departureAirport.GetLatitude(), departureAirport.GetLongitude());
            var destinationPosition = new GeoCoordinate(destinationAirport.GetLatitude(), destinationAirport.GetLongitude());
            return departurePosition.GetDistanceTo(destinationPosition) / 1000;
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Infrastructure/TUI.SimulatorFlights.Infrastructure/SQLLitePersistenceService.cs
﻿using Dapper;
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using TUI.Domain.SimulatorFlights;
using TUI.SimulatorFlights.Domain;
using TUI.SimulatorFlights.Infrastructure.DTO;

namespace TUI.SimulatorFlights.Infrastructure
{
    public class SQLLitePersistenceService : IPersistenceService
    {
        private string _connectionString;
        
        public IFlight GetFlight(string flightName)
        {
            
            using (var connection = new SQLiteConnection(_connectionString))
            using (var command = connection.CreateCommand())
            {
                connection.Open();
                var flightDTO = connection.Query<FlightDTO>($"select * from flight where flight_name='{flightName}'").FirstOrDefault();
                return flightDTO.ToFlight();
            }
        }

        public void SaveFlight(IFlight flight)
        {
            using (var connection = new SQLiteConnection(_connectionString))
            using (var command = connection.CreateCommand())
            {
                connection.Open();
                command.CommandText = "INSERT INTO flight (flight_name,fuel_consumption_per_distance,fuel_consumption_takeoff_effort," +
                    "departure_airport_name, departure_airport_latitude, departure_airport_longitude," +
                    "destination_airport_name, destination_airport_latitude, destination_airport_longitude" +
                   $") VALUES ('{flight.Name}', {flight.FuelConsumptionPerDistance}, {flight.FuelConsumptionTakeoffEffort},'{flight.DepartureAirport.AirportName}',{flight.DepartureAirport.GetLatitude()}, {flight.DepartureAirport.GetLongitude()}, '{flight.DestinationAirport.AirportName}', {flight.DestinationAirport.GetLatitude()}, {flight.DestinationAirport.GetLongitude()})" +
                   $"ON CONFLICT(flight_name) DO UPDATE SET fuel_consumption_per_distance = {flight.FuelConsumptionPerDistance},fuel_consumption_takeoff_effort={flight.FuelConsumptionTakeoffEffort}," +
                    $"departure_airport_name='{flight.DepartureAirport.AirportName}',departure_airport_latitude={flight.DepartureAirport.GetLatitude()}, departure_airport_longitude={flight.DepartureAirport.GetLongitude()}," +
                    $"destination_airport_name='{flight.DestinationAirport.AirportName}',destination_airport_latitude={flight.DepartureAirport.GetLatitude()}, destination_airport_longitude={flight.DestinationAirport.GetLongitude()};";
                command.ExecuteNonQuery();
            }
        }

        public void InitializeTables()
        {
            SQLiteConnection.CreateFile("TUI.SimulatorFlights.sqlite");
            using (var connection = new SQLiteConnection(@"Data Source=TUI.SimulatorFlights.sqlite;Version=3;"))
            using (var command = connection.CreateCommand())
            {
                connection.Open();
                command.CommandText = 
                    "CREATE TABLE flight (flight_name VARCHAR(255) PRIMARY KEY, " +
                    "fuel_consumption_per_distance INT," +
                    "fuel_consumption_takeoff_effort INT," +
                    "departure_airport_name VARCHAR(255)," +
                    "departure_airport_latitude double," +
                    "departure_airport_longitude double," +
                    "destination_airport_name VARCHAR(255)," +
                    "destination_airport_latitude double," +
                    "destination_airport_longitude double)"
                    ;
                command.ExecuteNonQuery();

                command.CommandText = "CREATE TABLE report (flight_name VARCHAR(255), calculType VARCHAR(255), calculDate VARCHAR(255), result double)" ;
                command.ExecuteNonQuery();
            }
        }

        public ICollection<IFlight> GetFlights()
        {
            using (var connection = new SQLiteConnection(_connectionString))
            using (var command = connection.CreateCommand())
            {
                connection.Open();
                var flightDTOs = connection.Query<FlightDTO>("select * from flight");
                return flightDTOs.Select(x => x.ToFlight()).ToList();
            }
        }

        public void InitializeService(string connectionString)
        {
            _connectionString = connectionString;
        }

        public void SaveReport(string flightName, CalculType calculType, double result)
        {
            using (var connection = new SQLiteConnection(_connectionString))
            using (var command = connection.CreateCommand())
            {
                connection.Open();
                command.CommandText = "INSERT INTO report (flight_name, calculType, calculDate, result)" +
                   $" VALUES ('{flightName}', '{calculType.ToString()}', '{DateTime.Now.ToShortDateString()}', {result})";
                command.ExecuteNonQuery();
            }
        }

        public ICollection<Report> GetReports()
        {
            using (var connection = new SQLiteConnection(_connectionString))
            using (var command = connection.CreateCommand())
            {
                connection.Open();
                var reportDTOs = connection.Query<ReportDTO>("select * from report");
                return reportDTOs.Select(x => x.ToReport()).ToList();
            }
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/Tests/TUI_SimulatorFlightsDomainTests/ControlTowerTests.cs
using FluentAssertions;
using Moq;
using System.Collections.Generic;
using System.Linq;
using TUI.Domain.SimulatorFlights;
using TUI.SimulatorFlights.Domain;
using Xunit;

namespace TUI_SimulatorFlightCostsTests
{
    public class ControlTowerTests
    {
        const string flightName = "<NAME> - London";
        ControlTower _controlTower;
        List<IFlight> _flights = new List<IFlight>();
        Mock<IPersistenceService> _persistenceServiceMock;

        public ControlTowerTests()
        {
            _persistenceServiceMock = new Mock<IPersistenceService>();
            _persistenceServiceMock.Setup(x => x.SaveFlight(It.IsAny<IFlight>()))
                .Callback((IFlight flight) => _flights.Add(flight));
            _persistenceServiceMock.Setup(x => x.GetFlight(It.IsAny<string>()))
                .Returns((string flightName) => _flights.SingleOrDefault(x => x.Name == flightName));
            _controlTower = new ControlTower(_persistenceServiceMock.Object);
        }

        [Fact]
        public void RegisterFlightAndRetriveIt()
        {
            // Arrange            
            var firstFlight = new Flight(flightName);
            // Act
            _controlTower.RegisterFlight(firstFlight);
            var flightLoaded = _controlTower.GetFlight(flightName);
            // Assert
            flightLoaded.Should().Be(firstFlight);
        }

        [Fact]
        public void CalculateDistanceForAFlight()
        {
            // Arrange
            var flightMock = new Mock<IFlight>();
            flightMock.SetupGet(x => x.Name).Returns(flightName);
            _controlTower.RegisterFlight(flightMock.Object);

            // Act
            _controlTower.CalculateDistance(flightName);
            // Assert
            flightMock.Verify(x => x.CalculateDistance(), Times.Once);
        }

        [Fact]
        public void CalculateFuelConsumption()
        {
            // Arrange
            var flightMock = new Mock<IFlight>();            
            flightMock.SetupGet(x => x.Name).Returns(flightName);
            _controlTower.RegisterFlight(flightMock.Object);

            // Act
            _controlTower.CalculateFuelConsumption(flightName);
            // Assert
            flightMock.Verify(x => x.CalculateFuelConsumption(), Times.Once);
        }

        [Fact]
        public void GetReports()
        {
            // Arrange

            // Act
            var reports = _controlTower.GetReports();
            // Assert
            _persistenceServiceMock.Verify(x => x.GetReports(), Times.Once);
        }

        [Fact]
        public void GetFlights()
        {
            // Arrange

            // Act
            var flights = _controlTower.GetFlights();
            // Assert
            _persistenceServiceMock.Verify(x => x.GetFlights(), Times.Once);
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/Airport.cs
﻿namespace TUI.Domain.SimulatorFlights
{
    public class Airport
    {
        private GPSPosition _GPSPosition;
        public string AirportName { get; }

        public Airport(string airportName, GPSPosition gPSPosition)
        {
            this.AirportName = airportName;
            this._GPSPosition = gPSPosition;
        }

        public double GetLatitude()
        {
            return _GPSPosition.Latitude;
        }

        public double GetLongitude()
        {
            return _GPSPosition.Longitude;
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Presentation/TUI_SimulatorFlightCosts.Web/Adapters/FlightModelAdapter.cs
﻿using TUI.Domain.SimulatorFlights;
using TUI_SimulatorFlightCosts.Web.Models;

namespace TUI_SimulatorFlightCosts.Web.Adapters
{
    public static class FlightModelAdapter
    {
        public static IFlight ToFlight(this FlightModel flightModel)
        {
            var flight = new Flight(flightModel.Name);
            flight.SetFuelConsumptionPerDistance(flightModel.FuelConsumptionPerDistance);
            flight.SetFuelConsumptionTakeoffEffort(flightModel.FuelConsumptionTakeoffEffort);
            flight.RegisterDepartureAirport(flightModel.DepartureAirportName, flightModel.DepartureAiportLatitude, flightModel.DepartureAirportLongitude);
            flight.RegisterDestinationAirport(flightModel.DestinationAirportName, flightModel.DestinationAirportLatitude, flightModel.DestinationAirportLongitude);
            return flight;
        }

        public static FlightModel ToFlightModel(this IFlight flight)
        {
            return new FlightModel
            {
                Name = flight.Name,
                FuelConsumptionPerDistance = flight.FuelConsumptionPerDistance,
                FuelConsumptionTakeoffEffort = flight.FuelConsumptionTakeoffEffort,
                DepartureAirportName = flight.DepartureAirport.AirportName,
                DepartureAiportLatitude = flight.DepartureAirport.GetLatitude(),
                DepartureAirportLongitude = flight.DepartureAirport.GetLongitude(),
                DestinationAirportName = flight.DestinationAirport.AirportName,
                DestinationAirportLatitude = flight.DestinationAirport.GetLatitude(),
                DestinationAirportLongitude = flight.DestinationAirport.GetLongitude()
            };
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/TUI_SimulatorFlightCosts_AcceptanceTests/Register_A_New_Flight_Steps.cs
﻿using FluentAssertions;
using TechTalk.SpecFlow;
using TUI.Domain.SimulatorFlights;
using TUI.SimulatorFlights.Infrastructure;

namespace TUI_SimulatorFlightCosts_AcceptanceTests
{
    [Binding]
    public class Register_A_New_FlightSteps
    {
        private ControlTower _currentControlTower;
        public Register_A_New_FlightSteps()
        {
            var persistenceService = new SQLLitePersistenceService();
            persistenceService.InitializeService(@"Data Source=..\..\..\..\Sqlite\TUI.SimulatorFlights.sqlite;Version=3;");
            _currentControlTower = new ControlTower(persistenceService);
        }

        [When(@"A user enters a new flight called '(.*)' on system")]
        public void WhenAUserEntersANewFlightCalledOnSystem(string flightName)
        {
            var flight = new Flight(flightName);
            flight.RegisterDepartureAirport("departure_airport", 0.0, 0.0);
            flight.RegisterDestinationAirport("destination_airport", 0.0, 0.0);
            _currentControlTower.RegisterFlight(flight);
        }

        [Then(@"The flight called '(.*)' can be retrived on system")]
        public void ThenTheFlightCalledCanBeRetrivedOnSystem(string flightName)
        {
            var flightFound = _currentControlTower.GetFlight(flightName);
            flightFound.Should().NotBeNull();
        }
    }
}
<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/IFlight.cs
﻿namespace TUI.Domain.SimulatorFlights
{
    public interface IFlight
    {
        string Name { get;}

        int FuelConsumptionPerDistance { get; }
        int FuelConsumptionTakeoffEffort { get; }
        Airport DepartureAirport { get; }
        Airport DestinationAirport { get; }

        void RegisterDepartureAirport(string airportName, double latitude, double longitude);
        void RegisterDestinationAirport(string airportName, double latitude, double longitude);
        void Rename(string flightName);
        double CalculateDistance();
        double CalculateFuelConsumption();
        void SetFuelConsumptionPerDistance(int fuelConsumptionPerDistance);
        void SetFuelConsumptionTakeoffEffort(int fuelConsumptionTakeoffEffort);
    }
}<file_sep>/TUI_SimulatorFlightCosts/Presentation/TUI_SimulatorFlightCosts.Web/Models/HomeModel.cs
﻿using System.Collections.Generic;
using TUI.Domain.SimulatorFlights;

namespace UI_SimulatorFlightCosts.Web.Models
{
    public class HomeModel
    {
        public HomeModel()
        {
        }

        public ICollection<IFlight> Flights { get; set; }
    }
}<file_sep>/TUI_SimulatorFlightCosts/Domain/TUI.SimulatorFlights.Domain/IFlightsManager.cs
﻿using System.Collections.Generic;
using TUI.Domain.SimulatorFlights;

namespace TUI.SimulatorFlights.Domain
{
    public interface IFlightsManager
    {
        void RegisterFlight(IFlight flight);

        IFlight GetFlight(string flightName);
        ICollection<IFlight> GetFlights();
    }
}
