Quellcode durchsuchen

Experimental support for importing previous logbook

Added experimental support for importing an existing logbook from crewlounge pilotlog. The source for the import is a CSV file exported from crewlounge. 

- Added a couple of const & in ADatabase to avoid copying entry objects unnecessarily
- Added a function to read CSV files as rows instead of columns.
- Implemented AEntry::setPosition
- Added RowIDs to Opl::Db Namespace
Felix Turo vor 3 Jahren
Ursprung
Commit
4dbb0248b0

+ 9 - 0
CMakeLists.txt

@@ -117,6 +117,15 @@ set(PROJECT_SOURCES
     assets/themes/stylesheets/breeze/breeze.qrc
     assets/themes/stylesheets/qdarkstyle/qdarkstyle.qrc
     assets/templates.qrc
+
+    src/testing/importCrewlounge/importcrewlounge.h
+    src/testing/importCrewlounge/importcrewlounge.cpp
+    src/testing/importCrewlounge/processpilots.h
+    src/testing/importCrewlounge/processpilots.cpp
+    src/testing/importCrewlounge/processaircraft.h
+    src/testing/importCrewlounge/processaircraft.cpp
+    src/testing/importCrewlounge/processflights.h
+    src/testing/importCrewlounge/processflights.cpp
 )
 
 # This is currently a bit buggy, see

+ 4 - 4
mainwindow.cpp

@@ -20,15 +20,15 @@
 #include "src/functions/alog.h"
 #include "src/database/adatabase.h"
 #include "src/classes/astyle.h"
+#include "src/gui/dialogues/firstrundialog.h"
+#include "src/classes/aentry.h"
 
 // Quick and dirty Debug area
-#include "src/gui/dialogues/firstrundialog.h"
+#include "src/testing/importCrewlounge/importcrewlounge.h"
 void MainWindow::doDebugStuff()
 {
-    auto fr = new FirstRunDialog(this);
-    fr->exec();
+    ImportCrewlounge::exec(QString());
 }
-
 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
     , ui(new Ui::MainWindow)

+ 7 - 2
src/classes/aentry.cpp

@@ -34,12 +34,17 @@ void AEntry::setData(RowData_T table_data)
     tableData = table_data;
 }
 
-const DataPosition& AEntry::getPosition()
+void AEntry::setPosition(DataPosition position_)
+{
+    position = position_;
+}
+
+const DataPosition& AEntry::getPosition() const
 {
     return position;
 }
 
-const RowData_T& AEntry::getData()
+const RowData_T& AEntry::getData() const
 {
     return tableData;
 }

+ 2 - 2
src/classes/aentry.h

@@ -53,8 +53,8 @@ public:
     void setData(RowData_T table_data);
     void setPosition(DataPosition position_);
 
-    const DataPosition& getPosition();
-    const RowData_T& getData();
+    const DataPosition& getPosition() const;
+    const RowData_T& getData() const;
 
 };
 

+ 5 - 5
src/database/adatabase.cpp

@@ -189,7 +189,7 @@ QSqlDatabase ADatabase::database()
     return QSqlDatabase::database(QStringLiteral("qt_sql_default_connection"));
 }
 
-bool ADatabase::commit(AEntry entry)
+bool ADatabase::commit(const AEntry &entry)
 {
     if (exists(entry)) {
         return update(entry);
@@ -198,7 +198,7 @@ bool ADatabase::commit(AEntry entry)
     }
 }
 
-bool ADatabase::remove(AEntry entry)
+bool ADatabase::remove(const AEntry &entry)
 {
     if (!exists(entry)) {
         DEB << "Error: Database entry not found.";
@@ -269,7 +269,7 @@ bool ADatabase::removeMany(QList<DataPosition> data_position_list)
     }
 }
 
-bool ADatabase::exists(AEntry entry)
+bool ADatabase::exists(const AEntry &entry)
 {
     if(entry.getPosition().rowId == 0)
         return false;
@@ -344,7 +344,7 @@ bool ADatabase::clear()
 }
 
 
-bool ADatabase::update(AEntry updated_entry)
+bool ADatabase::update(const AEntry &updated_entry)
 {
     auto data = updated_entry.getData();
     QString statement = QLatin1String("UPDATE ") + updated_entry.getPosition().tableName + QLatin1String(" SET ");
@@ -378,7 +378,7 @@ bool ADatabase::update(AEntry updated_entry)
     }
 }
 
-bool ADatabase::insert(AEntry new_entry)
+bool ADatabase::insert(const AEntry &new_entry)
 {
     auto data = new_entry.getData();
     QString statement = QLatin1String("INSERT INTO ") + new_entry.getPosition().tableName + QLatin1String(" (");

+ 5 - 5
src/database/adatabase.h

@@ -220,7 +220,7 @@ public:
     /*!
      * \brief Checks if an entry exists in the database, based on position data
      */
-    bool exists(AEntry entry);
+    bool exists(const AEntry &entry);
     bool exists(DataPosition data_position);
 
     /*!
@@ -233,22 +233,22 @@ public:
      * \brief commits an entry to the database, calls either insert or update,
      * based on position data
      */
-    bool commit(AEntry entry);
+    bool commit(const AEntry &entry);
 
     /*!
      * \brief Create new entry in the databse based on UserInput
      */
-    bool insert(AEntry new_entry);
+    bool insert(const AEntry &new_entry);
 
     /*!
      * \brief Updates entry in database from existing entry tweaked by the user.
      */
-    bool update(AEntry updated_entry);
+    bool update(const AEntry &updated_entry);
 
     /*!
      * \brief deletes an entry from the database.
      */
-    bool remove(AEntry entry);
+    bool remove(const AEntry &entry);
 
     /*!
      * \brief deletes a list of entries from the database. Optimised for speed when

+ 21 - 0
src/functions/areadcsv.cpp

@@ -48,3 +48,24 @@ QVector<QStringList> aReadCsv(QString filename)
     }
     return values;
 }
+
+/*!
+ * \brief aReadCsvAsRows reads from CSV
+ * \param file_name input file path
+ * \return QVector<QStringList> of the CSV data, where each QStringList is one row of the input file
+ */
+QVector<QStringList> aReadCsvAsRows(const QString &file_name)
+{
+    QFile csvfile(file_name);
+    csvfile.open(QIODevice::ReadOnly);
+    QTextStream stream(&csvfile);
+
+    QVector<QStringList> csv_rows;
+
+    // Read each line
+    while (!stream.atEnd()) {
+        const QString line = stream.readLine();
+        csv_rows.append(line.split(','));
+    }
+    return csv_rows;
+}

+ 2 - 0
src/functions/areadcsv.h

@@ -21,5 +21,7 @@
 #include<QtCore>
 
 QVector<QStringList> aReadCsv(QString filename);
+QVector<QStringList> aReadCsvAsRows(const QString &filename);
+
 
 #endif // AREADCSV_H

+ 19 - 1
src/gui/widgets/debugwidget.cpp

@@ -33,9 +33,27 @@
 #include "src/classes/ajson.h"
 #include "src/functions/adate.h"
 
+
+#include "src/testing/importCrewlounge/processflights.h"
+#include "src/testing/importCrewlounge/processpilots.h"
+#include "src/testing/importCrewlounge/processaircraft.h"
 void DebugWidget::on_debugPushButton_clicked()
 {
-    // Debug
+    auto rawCsvData = aReadCsvAsRows("/home/felix/git/importMCC/assets/data/felix.csv");
+    // Process Pilots
+    auto proc_pilots = ProcessPilots(rawCsvData);
+    proc_pilots.init();
+    const auto p_maps = proc_pilots.getProcessedPilotMaps();
+    // Process Tails
+    auto proc_tails = ProcessAircraft(rawCsvData);
+    proc_tails.init();
+    const auto t_maps = proc_tails.getProcessedTailMaps();
+    // Process Flights
+    auto proc_flights = ProcessFlights(rawCsvData,proc_pilots.getProcessedPilotsIds(), proc_tails.getProcessedTailIds());
+    proc_flights.init();
+
+    auto flights = proc_flights.getProcessedFlights();
+    DEB << "Flight:" << flights[1000];
 }
 
 DebugWidget::DebugWidget(QWidget *parent) :

+ 3 - 0
src/opl.h

@@ -170,6 +170,7 @@ static const auto TABLE_AIRPORTS         = QLatin1String("airports");
 static const auto TABLE_CURRENCIES       = QLatin1String("currencies");
 
 // Flights table columns
+static const auto FLIGHTS_ROWID          = QLatin1String("flight_id");
 static const auto FLIGHTS_DOFT           = QLatin1String("doft");
 static const auto FLIGHTS_DEPT           = QLatin1String("dept");
 static const auto FLIGHTS_DEST           = QLatin1String("dest");
@@ -203,6 +204,7 @@ static const auto FLIGHTS_REMARKS        = QLatin1String("remarks");
 
 // tails table
 
+static const auto TAILS_ROWID            = QLatin1String("tail_id");
 static const auto TAILS_REGISTRATION     = QLatin1String("registration");
 static const auto TAILS_COMPANY          = QLatin1String("company");
 static const auto TAILS_MAKE             = QLatin1String("make");
@@ -215,6 +217,7 @@ static const auto TAILS_WEIGHTCLASS      = QLatin1String("weightClass");
 
 // pilots table
 
+static const auto PILOTS_ROWID           = QLatin1String("pilot_id");
 static const auto PILOTS_LASTNAME        = QLatin1String("lastname");
 static const auto PILOTS_FIRSTNAME       = QLatin1String("firstname");
 static const auto PILOTS_ALIAS           = QLatin1String("alias");

+ 69 - 0
src/testing/importCrewlounge/importcrewlounge.cpp

@@ -0,0 +1,69 @@
+#include "importcrewlounge.h"
+#include "src/database/adatabase.h"
+#include "src/opl.h"
+#include "src/testing/importCrewlounge/processpilots.h"
+#include "src/testing/importCrewlounge/processaircraft.h"
+#include "src/testing/importCrewlounge/processflights.h"
+#include "src/functions/areadcsv.h"
+
+namespace ImportCrewlounge
+{
+
+void exec(const QString &csv_file_path)
+{
+    // Inhibit HomeWindow Updating
+    QSignalBlocker blocker(aDB);
+
+    // Prepare database and set up exclusive transaction for mass commit
+    QSqlQuery q;
+    q.prepare(QStringLiteral("BEGIN EXCLUSIVE TRANSACTION"));
+    q.exec();
+
+    // Read from CSV and remove first line (headers)
+    auto raw_csv_data = aReadCsvAsRows(csv_file_path);
+    raw_csv_data.removeFirst();
+
+    // Process Pilots
+    auto proc_pilots = ProcessPilots(raw_csv_data);
+    proc_pilots.init();
+    const auto p_maps = proc_pilots.getProcessedPilotMaps();
+
+    for (const auto & pilot : p_maps) {
+        APilotEntry pe(pilot);
+        pe.setPosition(DataPosition(Opl::Db::TABLE_PILOTS, pilot.value(Opl::Db::PILOTS_ROWID).toInt()));
+        aDB->commit(pe);
+    }
+
+    // Process Tails
+    auto proc_tails = ProcessAircraft(raw_csv_data);
+    proc_tails.init();
+    const auto t_maps = proc_tails.getProcessedTailMaps();
+
+    for (const auto& tail : t_maps) {
+        ATailEntry te(tail);
+        te.setPosition(DataPosition(Opl::Db::TABLE_TAILS, tail.value(Opl::Db::PILOTS_ROWID).toInt()));
+        aDB->commit(te);
+    }
+
+    auto proc_flights = ProcessFlights(raw_csv_data,
+                                       proc_pilots.getProcessedPilotsIds(),
+                                       proc_tails.getProcessedTailIds());
+    proc_flights.init();
+    const auto flights = proc_flights.getProcessedFlights();
+
+
+
+    for (const auto &flight : flights) {
+        AFlightEntry fe(flight);
+        aDB->commit(fe);
+    }
+
+    // Commit the exclusive transaction
+    q.prepare(QStringLiteral("COMMIT"));
+    q.exec();
+
+    // destroy blocker
+    blocker.unblock();
+    emit aDB->dataBaseUpdated();
+}
+}// namespace ImportCrewLongue

+ 10 - 0
src/testing/importCrewlounge/importcrewlounge.h

@@ -0,0 +1,10 @@
+#ifndef IMPORTCREWLOUNGE_H
+#define IMPORTCREWLOUNGE_H
+#include <QtCore>
+
+namespace ImportCrewlounge
+{
+void exec(const QString &csv_file_path);
+};
+
+#endif // IMPORTCREWLOUNGE_H

+ 69 - 0
src/testing/importCrewlounge/processaircraft.cpp

@@ -0,0 +1,69 @@
+#include "processaircraft.h"
+
+void ProcessAircraft::parseRawData()
+{
+    QStringList tail_details;
+    // relevant colums: {reg,company,make,model,variant,multipilot,multiengine,engineType,weightClass}
+    int relevant_cols[9] = {79, 36, 76, 77, 78, 83, 84, 92, 96};
+
+    for (const auto &row : qAsConst(rawData)) {
+        for (const auto &col : relevant_cols) {
+            tail_details.append(row[col]);
+        }
+        if (!(unique_tails.contains(tail_details)))
+            unique_tails.append(tail_details);
+        tail_details.clear();
+    }
+}
+
+void ProcessAircraft::processParsedData()
+{
+    // init counter
+    int unique_tail_id = 1;
+
+    QMap<QString, QVariant> new_tail_data;
+    for (const auto &list : qAsConst(unique_tails)) {
+        new_tail_data.insert(Opl::Db::TAILS_REGISTRATION, list[0]);
+        new_tail_data.insert(Opl::Db::TAILS_COMPANY, list[1]);
+        new_tail_data.insert(Opl::Db::TAILS_MAKE, list[2]);
+        new_tail_data.insert(Opl::Db::TAILS_MODEL, list[3]);
+        new_tail_data.insert(Opl::Db::TAILS_VARIANT, list[4]);
+
+        if (list[5] == "TRUE")
+            new_tail_data.insert(Opl::Db::TAILS_MULTIPILOT, 1);
+        else
+            new_tail_data.insert(Opl::Db::TAILS_MULTIPILOT, 0);
+
+        if (list[6] == "TRUE")
+            new_tail_data.insert(Opl::Db::TAILS_MULTIENGINE, 1);
+        else
+            new_tail_data.insert(Opl::Db::TAILS_MULTIENGINE, 0);
+
+        if (list[7] == "Piston") // other values need to be added as needed, do later
+            new_tail_data.insert(Opl::Db::TAILS_ENGINETYPE, 1);
+        else if (list[7] == "Turbine (jet-fan)")
+            new_tail_data.insert(Opl::Db::TAILS_ENGINETYPE, 3);
+
+        if (list[8] == "TRUE") // this is a above 7.5t switch in MCC, so default to medium for now
+            new_tail_data.insert(Opl::Db::TAILS_WEIGHTCLASS, 1);
+        else
+            new_tail_data.insert(Opl::Db::TAILS_WEIGHTCLASS, 0);
+
+        new_tail_data.insert(QStringLiteral("tail_id"), unique_tail_id);
+
+        processedTailIds.insert(list[0], unique_tail_id);
+        processedTailMaps.insert(list[0], new_tail_data);
+        unique_tail_id ++;
+        new_tail_data.clear();
+    }
+}
+
+QMap<QString, int> ProcessAircraft::getProcessedTailIds() const
+{
+    return processedTailIds;
+}
+
+QMap<QString, QMap<QString, QVariant> > ProcessAircraft::getProcessedTailMaps() const
+{
+    return processedTailMaps;
+}

+ 49 - 0
src/testing/importCrewlounge/processaircraft.h

@@ -0,0 +1,49 @@
+#ifndef PROCESSAIRCRAFT_H
+#define PROCESSAIRCRAFT_H
+#include <QtCore>
+#include "src/opl.h"
+
+class ProcessAircraft
+{
+public:
+    ProcessAircraft(const QVector<QStringList> &raw_csv_data)
+        : rawData(raw_csv_data){};
+
+    void init(){
+        parseRawData();
+        processParsedData();
+    };
+
+    QMap<QString, QMap<QString, QVariant> > getProcessedTailMaps() const;
+    QMap<QString, int> getProcessedTailIds() const;
+
+private:
+    void parseRawData();
+    void processParsedData();
+    QVector<QStringList> rawData;
+
+    /*!
+     * \brief unique_tails contains a list of all unique tails with relevant details
+     */
+    QVector<QStringList> unique_tails;
+
+    /*!
+     * \brief processedPilotMaps Holds a map of the processed pilots
+     *
+     * \details Here, the imported tails are stored after having been read from the CSV file.
+     * The key is the original string as it was originally in the AC_REG field and allows
+     * mapping the data to ID's later on. The value is a QMap<QString, QVariant> and contains
+     * the data processed as it will be represented in the OPL database later on.
+     */
+    QMap<QString, QMap<QString, QVariant>> processedTailMaps;
+
+    /*!
+     * \brief processedTailIds Holds a map of the ids that have been given to the processed pilots
+     *
+     * \details The tail data, once processed is held in processedTailMaps. With processedTailIds it
+     * is possible to map the original String to the tail_id that has been assigned during the parsing process.
+     */
+    QMap<QString, int> processedTailIds;
+};
+
+#endif // PROCESSAIRCRAFT_H

+ 89 - 0
src/testing/importCrewlounge/processflights.cpp

@@ -0,0 +1,89 @@
+#include "processflights.h"
+#include <src/functions/atime.h>
+
+void ProcessFlights::parseRawData()
+{
+    // doft, flightNumber, dept, dest, tofb, tonb, tblk, tPIC, tSIC, tDUAL, tPICUS, tFI, tNight, pic, secondPilot, thirdPilot   toDN,ldDN   pilotFlying, appType, remarks,  acftReg
+    int relevant_cols[24] = {0,3,5,7,9,11,17,19,20,21,22,23,25,38,42,46,53,54,55,56,58,60,64,79};
+    QStringList row_data;
+    for (const auto &row : qAsConst(rawData)) {
+        for (const auto &col : relevant_cols) {
+            row_data.append(row[col]);
+        }
+        rawFlightData.append(row_data);
+        row_data.clear();
+    }
+    DEB << "Flight Info #1742:" << rawFlightData[1742];
+}
+
+void ProcessFlights::processParsedData()
+{
+    QMap<QString, QVariant> new_flight_data;
+    int flight_id = 1;
+
+    for (const auto &row : qAsConst(rawFlightData)) {
+        // insert values that don't require editing
+        new_flight_data.insert(Opl::Db::FLIGHTS_FLIGHTNUMBER, row[1]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_DEPT, row[2]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_DEST, row[3]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TBLK, row[6]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TPIC, row[7]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TSIC, row[8]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TDUAL, row[9]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TPICUS, row[10]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TFI, row[11]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TNIGHT, row[12]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TODAY, row[16]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TONIGHT, row[17]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_LDGDAY, row[18]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_LDGNIGHT, row[19]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_APPROACHTYPE, row[21]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_REMARKS, row[22]);
+
+        // PF
+        if (row[20] == QLatin1String("TRUE"))
+            new_flight_data.insert(Opl::Db::FLIGHTS_PILOTFLYING, 1);
+        else
+            new_flight_data.insert(Opl::Db::FLIGHTS_PILOTFLYING, 0);
+
+        // Convert Date and Time
+        const QDate doft = QDate::fromString(row[0],QStringLiteral("dd/MM/yyyy"));
+        new_flight_data.insert(Opl::Db::FLIGHTS_DOFT, doft.toString(Qt::ISODate));
+
+        auto time_off = QTime::fromString(row[4], QStringLiteral("hh:mm"));
+        if (!time_off.isValid())
+            time_off = QTime::fromString(row[4], QStringLiteral("h:mm"));
+        int tofb = ATime::toMinutes(time_off);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TOFB, tofb);
+
+        auto time_on = QTime::fromString(row[5], QStringLiteral("hh:mm"));
+        if (!time_on.isValid())
+            time_on = QTime::fromString(row[5], QStringLiteral("h:mm"));
+
+        int tonb = ATime::toMinutes(time_on);
+        new_flight_data.insert(Opl::Db::FLIGHTS_TONB, tonb);
+
+        // map pilots
+        int pic = processedPilotsIds.value(row[13]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_PIC, pic);
+        int second_pilot = processedPilotsIds.value(row[14]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_SECONDPILOT, second_pilot);
+        int third_pilot = processedPilotsIds.value(row[15]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_THIRDPILOT, third_pilot);
+
+        // map tail
+        int acft = processedTailsIds.value(row[23]);
+        new_flight_data.insert(Opl::Db::FLIGHTS_ACFT, acft);
+
+        // set id, fix opl to include alias
+        new_flight_data.insert(QStringLiteral("flight_id"), flight_id);
+        processedFlights.append(new_flight_data);
+        new_flight_data.clear();
+        flight_id ++;
+    }
+}
+
+QVector<QMap<QString, QVariant> > ProcessFlights::getProcessedFlights() const
+{
+    return processedFlights;
+}

+ 34 - 0
src/testing/importCrewlounge/processflights.h

@@ -0,0 +1,34 @@
+#ifndef PROCESSFLIGHTS_H
+#define PROCESSFLIGHTS_H
+#include <QtCore>
+#include <src/opl.h>
+
+class ProcessFlights
+{
+public:
+    ProcessFlights(const QVector<QStringList> &raw_csv_data,
+                   const QMap<QString, int> &processed_pilots_ids,
+                   const QMap<QString, int> &processed_tails_ids)
+        : rawData(raw_csv_data),
+          processedPilotsIds(processed_pilots_ids),
+          processedTailsIds(processed_tails_ids){};
+
+    void init(){
+        parseRawData();
+        processParsedData();
+    };
+    QVector<QMap<QString, QVariant> > getProcessedFlights() const;
+
+private:
+    void parseRawData();
+    void processParsedData();
+    QVector<QStringList> rawData;
+    QVector<QStringList> rawFlightData;
+
+    QVector<QMap<QString, QVariant>> processedFlights;
+
+    QMap<QString, int> processedPilotsIds;
+    QMap<QString, int> processedTailsIds;
+};
+
+#endif // PROCESSFLIGHTS_H

+ 84 - 0
src/testing/importCrewlounge/processpilots.cpp

@@ -0,0 +1,84 @@
+#include "processpilots.h"
+
+void ProcessPilots::parseRawData()
+{
+    const QVector<int> cols_pilot1 = {37, 38, 39, 40}; //empId, name, phone, email
+    const QVector<int> cols_pilot2 = {41, 42, 43, 44};
+    const QVector<int> cols_pilot3 = {45, 46, 47, 48};
+    const QVector<QVector<int>> pilot_cols = {
+        cols_pilot1,
+        cols_pilot2,
+        cols_pilot3
+    };
+
+    QVector<QStringList> unique_pilots;
+    QStringList pilot_data = {
+        QString(),
+        QStringLiteral("SELF"),
+        QString(),
+        QString()
+    };
+    unique_pilots.append(pilot_data);
+    int unique_pilot_id = 1;
+    processedPilotsIds.insert(pilot_data[1], unique_pilot_id);
+    rawPilotsAndIds.append({pilot_data, unique_pilot_id});
+    pilot_data.clear();
+    unique_pilot_id ++;
+
+
+    for (const auto &row : qAsConst(rawData)) {
+        for (const auto &col_array : pilot_cols) {
+            for (const auto &col : col_array) {
+                pilot_data.append(row[col]);
+            }
+            if (!unique_pilots.contains(pilot_data) && !pilot_data.contains(QLatin1String("SELF"))) {
+                unique_pilots.append(pilot_data);
+                processedPilotsIds.insert(pilot_data[1], unique_pilot_id);
+                rawPilotsAndIds.append({pilot_data, unique_pilot_id});
+                unique_pilot_id ++;
+            }
+            pilot_data.clear();
+        }
+    }
+}
+
+void ProcessPilots::processParsedData()
+{
+    for (const auto &pair : qAsConst(rawPilotsAndIds)) {
+        //DEB << "ID:" << pair.second << "Details:" << pair.first;
+        QMap<QString, QVariant> new_pilot_data;
+
+        // process name [1]
+        auto temp_list = pair.first[1].split(QLatin1Char(' '));
+        if (!temp_list.isEmpty()) {
+            new_pilot_data.insert(Opl::Db::PILOTS_LASTNAME, temp_list.first());
+            temp_list.pop_front();
+
+            if (!temp_list.isEmpty())
+                new_pilot_data.insert(Opl::Db::PILOTS_FIRSTNAME, temp_list.join(QLatin1Char(' ')));
+        } else {
+            new_pilot_data.insert(Opl::Db::PILOTS_LASTNAME, QStringLiteral("UNKNOWN"));
+        }
+
+        // add additional data
+        new_pilot_data.insert(Opl::Db::PILOTS_EMPLOYEEID, pair.first[0]);
+        new_pilot_data.insert(Opl::Db::PILOTS_PHONE, pair.first[2]);
+        new_pilot_data.insert(Opl::Db::PILOTS_EMAIL, pair.first[3]);
+
+        // add pilot_id (workaround with literal until Opl::Db is updated)
+        new_pilot_data.insert(QStringLiteral("pilot_id"), pair.second);
+
+        processedPilotMaps.insert(pair.first[1], new_pilot_data);
+        processedPilotsIds.insert(pair.first[1], pair.second);
+    }
+}
+
+QMap<QString, QMap<QString, QVariant>> ProcessPilots::getProcessedPilotMaps() const
+{
+    return processedPilotMaps;
+}
+
+QMap<QString, int> ProcessPilots::getProcessedPilotsIds() const
+{
+    return processedPilotsIds;
+}

+ 49 - 0
src/testing/importCrewlounge/processpilots.h

@@ -0,0 +1,49 @@
+#ifndef PROCESSPILOTS_H
+#define PROCESSPILOTS_H
+#include <QtCore>
+#include <src/opl.h>
+#include <QMap>
+#include <QVector>
+
+class ProcessPilots
+{
+public:
+    ProcessPilots(const QVector<QStringList> &raw_csv_data)
+        : rawData(raw_csv_data){};
+
+    void init(){
+        parseRawData();
+        processParsedData();
+    };
+
+    QMap<QString, QMap<QString, QVariant> > getProcessedPilotMaps() const;
+    QMap<QString, int> getProcessedPilotsIds() const;
+
+private:
+
+    void parseRawData();
+    void processParsedData();
+
+    QVector<QPair<QStringList, int>> rawPilotsAndIds;
+    QVector<QStringList> rawData;
+
+    /*!
+     * \brief processedPilotMaps Holds a map of the processed pilots
+     *
+     * \details Here, the imported pilots are stored after having been read from the CSV file.
+     * The key is the original string as it was originally in the PILOT_NAME field and allows
+     * mapping the data to ID's later on. The value is a QMap<QString, QVariant> and contains
+     * the data processed as it will be represented in the OPL database later on.
+     */
+    QMap<QString, QMap<QString, QVariant>> processedPilotMaps;
+
+    /*!
+     * \brief processedPilotsIds Holds a map of the ids that have been given to the processed pilots
+     *
+     * \details The pilot data, once processed is held in processedPilotMaps. With processePilotsIds it
+     * is possible to map the original String to the PilotID that has been assigned during the parsing process.
+     */
+    QMap<QString, int> processedPilotsIds;
+};
+
+#endif // PROCESSPILOTS_H