From 1ac3a8b31b4498b2094ca63145b6c0a489eb9e64 Mon Sep 17 00:00:00 2001 From: Alex H Date: Thu, 13 Apr 2023 07:13:17 +0000 Subject: [PATCH 01/22] import-generic view and route added --- ui/src/locales/de.json | 2 +- ui/src/locales/en.json | 6 +++++- ui/src/router/routes.js | 9 +++++++++ ui/src/router/views/import-generic.unit.js | 7 +++++++ ui/src/router/views/import-generic.vue | 18 ++++++++++++++++++ ui/src/router/views/import.vue | 21 ++++++++++++++++----- 6 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 ui/src/router/views/import-generic.unit.js create mode 100644 ui/src/router/views/import-generic.vue diff --git a/ui/src/locales/de.json b/ui/src/locales/de.json index c2e2ac7..fa62964 100644 --- a/ui/src/locales/de.json +++ b/ui/src/locales/de.json @@ -137,7 +137,7 @@ "dontimportagain": "Achte darauf, dass du die Datei nicht erneut importierst, da dies zu mehrfachen Einträgen führen würde.", "checkpointsimportcsv": "Wenn du alle diese Punkte überprüft hast kannst du unten die CSV importieren.", "importhintunits": "Vergewissere dich ebenfalls, dass die Kraftstoffeinheit und der Kraftstofftyp im Fahrzeug richtig eingestellt sind.", - "importhintcurrdist": "Stelle sicher, dass die Währung und die Entfernungseinheit in Hammond korrekt eingestellt sind. Der Import erkennt die Währung nicht automatisch aus der CSV-Datei, sondern verwendet die für den Benutzer eingestellte Währung.", + "importhintcurrdist": "Stelle sicher, dass die Währung und die Entfernungseinheit in Hammond korrekt eingestellt sind. Der Import erkennt die Währung nicht automatisch aus der datei, sondern verwendet die für den Benutzer eingestellte Währung.", "importhintnickname": "Vergewissere dich, dass der Fahrzeugname in Hammond genau mit dem Namen in der Fuelly-CSV-Datei übereinstimmt, sonst funktioniert der Import nicht.", "importhintvehiclecreated": "Vergewissere dich, dass du die Fahrzeuge bereits in Hammond erstellt hast.", "importhintcreatecsv": "Exportiere deine Daten aus {name} im CSV-Format. Die Schritte dazu findest du", diff --git a/ui/src/locales/en.json b/ui/src/locales/en.json index 0bb7fc0..f5d4b0a 100644 --- a/ui/src/locales/en.json +++ b/ui/src/locales/en.json @@ -130,6 +130,8 @@ "importdatadesc": "Choose from the following options to import data into Hammond", "import": "Import", "importcsv": "If you have been using {name} to store your vehicle data, export the CSV file from {name} and click here to import.", + "importgeneric": "Generic Import", + "importgenericdesc": "Generic csv and json import.", "choosecsv": "Choose CSV", "choosephoto": "Choose Photo", "importsuccessfull": "Data Imported Successfully", @@ -137,13 +139,15 @@ "importfrom": "Import from {0}", "stepstoimport": "Steps to import data from {name}", "choosecsvimport": "Choose the {name} CSV and press the import button.", + "choosedatafile": "Choose the CSV or JSON file and then press the import button.", "dontimportagain": "Make sure that you do not import the file again because that will create repeat entries.", "checkpointsimportcsv": "Once you have checked all these points, just import the CSV below.", "importhintunits": "Similiarly, make sure that the Fuel Unit and Fuel Type are correctly set in the Vehicle.", - "importhintcurrdist": "Make sure that the Currency and Distance Unit are set correctly in Hammond. Import will not autodetect Currency from the CSV but use the one set for the user.", + "importhintcurrdist": "Make sure that the Currency and Distance Unit are set correctly in Hammond. Import will not autodetect Currency from the file but use the one set for the user.", "importhintnickname": "Make sure that the Vehicle nickname in Hammond is exactly the same as the name on Fuelly CSV or the import will not work.", "importhintvehiclecreated": "Make sure that you have already created the vehicles in Hammond platform.", "importhintcreatecsv": "Export your data from {name} in the CSV format. Steps to do that can be found", + "importgenerichintdata": "Data must be in either CSV or JSON format.", "here": "here", "unprocessedquickentries": "You have one quick entry to be processed. | You have {0} quick entries pending to be processed.", "show": "Show", diff --git a/ui/src/router/routes.js b/ui/src/router/routes.js index 011de78..c5d01c4 100644 --- a/ui/src/router/routes.js +++ b/ui/src/router/routes.js @@ -419,6 +419,15 @@ export default [ }, props: (route) => ({ user: store.state.auth.currentUser || {} }), }, + { + path: '/import/generic', + name: 'import-generic', + component: () => lazyLoadView(import('@views/import-generic.vue')), + meta: { + authRequired: true, + }, + props: (route) => ({ user: store.state.auth.currentUser || {} }), + }, { path: '/logout', name: 'logout', diff --git a/ui/src/router/views/import-generic.unit.js b/ui/src/router/views/import-generic.unit.js new file mode 100644 index 0000000..51d032e --- /dev/null +++ b/ui/src/router/views/import-generic.unit.js @@ -0,0 +1,7 @@ +import ImportGeneric from './import-generic' + +describe('@views/import-generic', () => { + it('is a valid view', () => { + expect(ImportGeneric).toBeAViewComponent() + }) +}) diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue new file mode 100644 index 0000000..6d6b5a9 --- /dev/null +++ b/ui/src/router/views/import-generic.vue @@ -0,0 +1,18 @@ + + + + diff --git a/ui/src/router/views/import.vue b/ui/src/router/views/import.vue index 40597e6..6a31b92 100644 --- a/ui/src/router/views/import.vue +++ b/ui/src/router/views/import.vue @@ -18,18 +18,19 @@ export default { From cd2e9ebc61de75db163ac10406ff4d04d37963b4 Mon Sep 17 00:00:00 2001 From: Alex H Date: Thu, 13 Apr 2023 07:32:24 +0000 Subject: [PATCH 02/22] first interation of a generic csv importer --- ui/src/router/views/import-generic.vue | 248 ++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 4 deletions(-) diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue index 6d6b5a9..2aec1d1 100644 --- a/ui/src/router/views/import-generic.vue +++ b/ui/src/router/views/import-generic.vue @@ -1,18 +1,258 @@ From 2a8325c6ce39e0910780dec66f2c3b3738e298f9 Mon Sep 17 00:00:00 2001 From: Alex H Date: Thu, 13 Apr 2023 17:52:13 +0000 Subject: [PATCH 03/22] initial server side processing --- ui/src/router/views/import-generic.vue | 29 +++++++++----------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue index 2aec1d1..3b01d36 100644 --- a/ui/src/router/views/import-generic.vue +++ b/ui/src/router/views/import-generic.vue @@ -76,26 +76,17 @@ export default { Papa.parse(this.file, this.papaConfig) }, importData() { - const fillups = [] - for (let i = 1; i < this.fileData.length; i++) { - const fillup = { - date: this.fillupModel.date !== null ? this.fileData[i][this.fillupModel.date] : null, - fuelSubType: this.fillupModel.fuelsubtype !== null ? this.fileData[i][this.fillupModel.fuelSubType] : null, - fuelQuantity: this.fillupModel.fuelQuantity !== null ? this.fileData[i][this.fillupModel.fuelQuantity] : null, - perUnitPrice: this.fillupModel.perUnitPrice !== null ? this.fileData[i][this.fillupModel.perUnitPrice] : null, - totalAmount: this.fillupModel.totalAmount > -1 ? this.fileData[i][this.fillupModel.totalAmount] : (this.fileData[i][this.fillupModel.fuelQuantity] * this.fileData[i][this.fillupModel.perUnitPrice]).toFixed(2), - odoReading: this.fillupModel.odoReading !== null ? this.fileData[i][this.fillupModel.odoReading] : null, - isTankFull: this.fillupModel.isTankFull !== null ? this.fileData[i][this.fillupModel.isTankFull] : null, - hasMissedFillup: this.fillupModel.hasMissedFillup !== null ? this.fileData[i][this.fillupModel.hasMissedFillup] : null, - comments: this.fillupModel.comments.length === 1 ? this.fileData[i][this.fillupModel.comments] : '', - fillingStation: this.fillupModel.fillingStation !== null ? this.fileData[i][this.fillupModel.fillingStation] : null, - } - if (this.inverted) { - fillup.isTankFull = !fillup.isTankFull - } - fillups.push(fillup) + if (typeof this.fileData[1][this.fillupModel.isTankFull] !== "boolean") { + this.errors.push('The value of Tank Full needs to be a boolean (true,false).') + return } - alert(JSON.stringify(fillups[1])) + const content = { + headings: this.fillupModel, + data: this.fileData.splice(1, this.fileData.length), + fullTankInverted: this.inverted, + vehicleId: this.selectedVehicle.id + } + alert(JSON.stringify(content)) }, } } From e2e41697870f8ee71f7c07192450e1a8b486515e Mon Sep 17 00:00:00 2001 From: Alex H Date: Thu, 13 Apr 2023 22:55:09 -0400 Subject: [PATCH 04/22] user selects if they track full tank or partial fillup --- ui/src/locales/en.json | 111 +++++++++++++------------ ui/src/router/views/import-generic.vue | 31 +++---- 2 files changed, 74 insertions(+), 68 deletions(-) diff --git a/ui/src/locales/en.json b/ui/src/locales/en.json index f5d4b0a..9e84f4d 100644 --- a/ui/src/locales/en.json +++ b/ui/src/locales/en.json @@ -5,7 +5,7 @@ "thismonth": "This month", "pastxdays": "Past one day | Past {count} days", "pastxmonths": "Past one month | Past {count} months", - "thisyear": "This year", + "thisyear": "This year", "alltime": "All Time", "noattachments": "No Attachments so far", "attachments": "Attachments", @@ -43,15 +43,15 @@ "createnow": "Create Now", "yourvehicles": "Your Vehicles", "menu": { - "quickentries": "Quick Entries", - "logout": "Log out", - "import": "Import", - "home": "Home", - "settings": "Settings", - "admin": "Admin", - "sitesettings": "Site Settings", - "users": "Users", - "login": "Log in" + "quickentries": "Quick Entries", + "logout": "Log out", + "import": "Import", + "home": "Home", + "settings": "Settings", + "admin": "Admin", + "sitesettings": "Site Settings", + "users": "Users", + "login": "Log in" }, "enterusername": "Enter your username", "enterpassword": "Enter your password", @@ -81,34 +81,34 @@ "quantity": "Quantity", "gasstation": "Gas Station", "fuel": { - "petrol": "Petrol", - "diesel": "Diesel", - "cng": "CNG", - "lpg": "LPG", - "electric": "Electric", - "ethanol": "Ethanol" + "petrol": "Petrol", + "diesel": "Diesel", + "cng": "CNG", + "lpg": "LPG", + "electric": "Electric", + "ethanol": "Ethanol" }, "unit": { - "long": { - "litre": "Litre", - "gallon": "Gallon", - "kilowatthour": "Kilowatt Hour", - "kilogram": "Kilogram", - "usgallon": "US Gallon", - "minutes": "Minutes", - "kilometers": "Kilometers", - "miles": "Miles" - }, - "short": { - "litre": "Lt", - "gallon": "Gal", - "kilowatthour": "KwH", - "kilogram": "Kg", - "usgallon": "US Gal", - "minutes": "Mins", - "kilometers": "Km", - "miles": "Mi" - } + "long": { + "litre": "Litre", + "gallon": "Gallon", + "kilowatthour": "Kilowatt Hour", + "kilogram": "Kilogram", + "usgallon": "US Gallon", + "minutes": "Minutes", + "kilometers": "Kilometers", + "miles": "Miles" + }, + "short": { + "litre": "Lt", + "gallon": "Gal", + "kilowatthour": "KwH", + "kilogram": "Kg", + "usgallon": "US Gal", + "minutes": "Mins", + "kilometers": "Km", + "miles": "Mi" + } }, "avgfillupqty": "Avg Fillup Qty", "avgfillupexpense": "Avg Fillup Expense", @@ -117,7 +117,9 @@ "price": "Price", "total": "Total", "fulltank": "Tank Full", + "partialfillup": "Partial Fillup", "getafulltank": "Did you get a full tank?", + "tankpartialfull": "Which do you track?", "by": "By", "expenses": "Expenses", "expensetype": "Expense Type", @@ -182,6 +184,7 @@ "fillingstation": "Filling Station Name", "comments": "Comments", "missfillupbefore": "Did you miss the fillup entry before this one?", + "missedfillup": "Missed Fillup", "fillupdate": "Fillup Date", "fillupsavedsuccessfully": "Fillup Saved Successfully", "expensesavedsuccessfully": "Expense Saved Successfully", @@ -199,25 +202,25 @@ "testconn": "Test Connection", "migrate": "Migrate", "init": { - "migrateclarkson": "Migrate from Clarkson", - "migrateclarksondesc": "If you have an existing Clarkson deployment and you want to migrate your data from that, press the following button.", - "freshinstall": "Fresh Install", - "freshinstalldesc": "If you want a fresh install of Hammond, press the following button.", - "clarkson": { - "desc": "

You need to make sure that this deployment of Hammond can access the MySQL database used by Clarkson.

If that is not directly possible, you can make a copy of that database somewhere accessible from this instance.

Once that is done, enter the connection string to the MySQL instance in the following format.

All the users imported from Clarkson will have their username as their email in Clarkson database and pasword set tohammond

user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local

", - "success": "We have successfully migrated the data from Clarkson. You will be redirected to the login screen shortly where you can login using your existing email and password : hammond" - }, - "fresh": { - "setupadminuser": "Setup Admin Users", - "yourpassword": "Your Password", - "youremail": "Your Email", - "yourname": "Your Name", - "success": "You have been registered successfully. You will be redirected to the login screen shortly where you can login and start using the system." - } + "migrateclarkson": "Migrate from Clarkson", + "migrateclarksondesc": "If you have an existing Clarkson deployment and you want to migrate your data from that, press the following button.", + "freshinstall": "Fresh Install", + "freshinstalldesc": "If you want a fresh install of Hammond, press the following button.", + "clarkson": { + "desc": "

You need to make sure that this deployment of Hammond can access the MySQL database used by Clarkson.

If that is not directly possible, you can make a copy of that database somewhere accessible from this instance.

Once that is done, enter the connection string to the MySQL instance in the following format.

All the users imported from Clarkson will have their username as their email in Clarkson database and pasword set tohammond

user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local

", + "success": "We have successfully migrated the data from Clarkson. You will be redirected to the login screen shortly where you can login using your existing email and password : hammond" + }, + "fresh": { + "setupadminuser": "Setup Admin Users", + "yourpassword": "Your Password", + "youremail": "Your Email", + "yourname": "Your Name", + "success": "You have been registered successfully. You will be redirected to the login screen shortly where you can login and start using the system." + } }, "roles": { - "ADMIN": "ADMIN", - "USER": "USER" + "ADMIN": "ADMIN", + "USER": "USER" }, "profile": "Profile", "processedon": "Processed on", @@ -225,4 +228,4 @@ "disable": "Disable", "confirm": "Go Ahead", "labelforfile": "Label for this file" - } \ No newline at end of file +} \ No newline at end of file diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue index 3b01d36..8c156cd 100644 --- a/ui/src/router/views/import-generic.vue +++ b/ui/src/router/views/import-generic.vue @@ -14,7 +14,7 @@ export default { user: { type: Object, required: true, - } + }, }, data: function () { return { @@ -38,7 +38,7 @@ export default { fillingStation: null, date: null, fuelSubType: null, - } + }, } }, computed: { @@ -58,7 +58,7 @@ export default { return '' } } - } + }, }, mounted() { this.myVehicles = this.vehicles @@ -76,7 +76,7 @@ export default { Papa.parse(this.file, this.papaConfig) }, importData() { - if (typeof this.fileData[1][this.fillupModel.isTankFull] !== "boolean") { + if (typeof this.fileData[1][this.fillupModel.isTankFull] !== 'boolean') { this.errors.push('The value of Tank Full needs to be a boolean (true,false).') return } @@ -84,11 +84,11 @@ export default { headings: this.fillupModel, data: this.fileData.splice(1, this.fileData.length), fullTankInverted: this.inverted, - vehicleId: this.selectedVehicle.id + vehicleId: this.selectedVehicle.id, } alert(JSON.stringify(content)) }, - } + }, } @@ -109,7 +109,9 @@ export default {
  • {{ $t('importhintvehiclecreated') }}
  • -
  • {{ $t('dontimportagain') }}
  • +
  • {{ $t('dontimportagain') }}
  • @@ -177,8 +179,7 @@ export default { - + - + + {{ $t('fulltank') }} + {{ $t('partialfillup') }} + + - Invert Value - +
    - +

    There was an error logging in to your account.

    From e389a9ac2aadb33dd308e86c99228a839f0a494a Mon Sep 17 00:00:00 2001 From: Alex H Date: Thu, 13 Apr 2023 22:57:01 -0400 Subject: [PATCH 05/22] forgot to commit package.json after I added papaparse --- ui/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/package.json b/ui/package.json index c166776..2d53a0b 100644 --- a/ui/package.json +++ b/ui/package.json @@ -36,6 +36,7 @@ "node-gyp": "^9.3.1", "normalize.css": "^8.0.1", "nprogress": "^0.2.0", + "papaparse": "^5.4.1", "vue": "^2.6.11", "vue-chartjs": "^3.5.1", "vue-i18n": "^8.28.2", From df165dae6eb284abd46ffa0cd41caf625111cc8e Mon Sep 17 00:00:00 2001 From: Alex H Date: Fri, 14 Apr 2023 01:54:03 -0400 Subject: [PATCH 06/22] added full tank string value inputs --- ui/src/router/views/import-generic.vue | 41 +++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue index 8c156cd..eda5fd8 100644 --- a/ui/src/router/views/import-generic.vue +++ b/ui/src/router/views/import-generic.vue @@ -27,6 +27,9 @@ export default { myVehicles: [], selectedVehicle: null, invert: false, + filledValue: null, + notFilledValue: null, + isFullTankString: false, fillupModel: { fuelQuantity: null, perUnitPrice: null, @@ -76,17 +79,27 @@ export default { Papa.parse(this.file, this.papaConfig) }, importData() { - if (typeof this.fileData[1][this.fillupModel.isTankFull] !== 'boolean') { - this.errors.push('The value of Tank Full needs to be a boolean (true,false).') - return + if (this.errors.length !== 0) { + const content = { + headings: this.fillupModel, + data: this.fileData.splice(1, this.fileData.length), + fullTankInverted: this.inverted, + vehicleId: this.selectedVehicle.id, + } + alert(JSON.stringify(content)) + } else { + this.errors.push('fix errors') } - const content = { - headings: this.fillupModel, - data: this.fileData.splice(1, this.fileData.length), - fullTankInverted: this.inverted, - vehicleId: this.selectedVehicle.id, + }, + checkFieldString() { + const tankFull = this.fileData[1][this.fillupModel.isTankFull] + if (typeof tankFull !== 'boolean') { + if (typeof tankFull === 'string' && tankFull.length > 0) { + this.isFullTankString = true + } else { + this.errors.push('The value of Tank Full needs to be a boolean (true,false) or consistent string.') + } } - alert(JSON.stringify(content)) }, }, } @@ -206,12 +219,20 @@ export default { {{ $t('partialfillup') }}
    - + + + + + + + + + - + - + - + - + - + - + - {{ $t('fulltank') }} - {{ $t('partialfillup') }} + {{ $t('fulltank') }} + {{ $t('partialfillup') }} - + @@ -227,28 +227,28 @@ export default { - + - + - + - + - + From 051e3476a78fd6cf2b5855dfbc8fd2cd492cbabd Mon Sep 17 00:00:00 2001 From: Alex H Date: Fri, 14 Apr 2023 20:45:12 -0400 Subject: [PATCH 08/22] csvToJson is mostly complete --- ui/src/router/views/import-generic.vue | 44 ++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue index abcad73..63fe7a7 100644 --- a/ui/src/router/views/import-generic.vue +++ b/ui/src/router/views/import-generic.vue @@ -78,15 +78,47 @@ export default { this.errorMessage = '' Papa.parse(this.file, this.papaConfig) }, + csvToJson() { + const data = [] + const headings = Object.keys(this.fileHeadingMap) + .filter((k) => this.fileHeadingMap[k] != null) // filter non-null properties + .reduce((a, k) => ({ ...a, [k]: this.fileHeadingMap[k] }), {}) // create new object from filter + const comments = (row) => { + return this.fileHeadingMap.comments.reduce((a, fi) => { + // TODO: sanitize to prevent XSS + return `${a}${this.fileHeadings[fi]}: ${row[fi]}\n` + }, '') + } + const calculateTotal = (row) => { + return this.fileHeadingMap.totalAmount === -1 + ? (row[this.fileHeadings.fuelQuantity] * row[this.fileHeadings.perUnitPrice]).toFixed(2) + : row[this.fileHeadingMap.totalAmount] + } + + for (let r = 1; r < this.fileData.length; r++) { + const row = this.fileData[r] + const item = {} + Object.keys(headings).forEach((k) => { + if (k === 'comments') { + item[k] = comments(row) + } else if (k === 'totalAmount') { + item[k] = calculateTotal(row) + } else { + item[k] = row[headings[k]] + } + }) + data.push(item) + } + return data + }, importData() { if (this.errors.length === 0) { - const content = { - headings: this.fileHeadingMap, - data: this.fileData.splice(1, this.fileData.length), - fullTankInverted: this.inverted, - vehicleId: this.selectedVehicle.id, + try { + const content = this.csvToJson() + alert(JSON.stringify(content)) + } catch (e) { + alert(e) } - alert(JSON.stringify(content)) } else { this.errors.push('fix errors') } From 9f9f90fd1da828c586940a4cf3579f1f7bc1f3f0 Mon Sep 17 00:00:00 2001 From: Alex H Date: Fri, 14 Apr 2023 23:20:44 -0400 Subject: [PATCH 09/22] handling isFullTankString and making post request to api --- ui/src/router/views/import-generic.vue | 54 ++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue index 63fe7a7..5ea9182 100644 --- a/ui/src/router/views/import-generic.vue +++ b/ui/src/router/views/import-generic.vue @@ -1,7 +1,7 @@ @@ -200,9 +202,7 @@ export default {
  • {{ $t('importhintvehiclecreated') }}
  • -
  • {{ $t('dontimportagain') }}
  • +
  • {{ $t('dontimportagain') }}
  • @@ -270,7 +270,8 @@ export default {
    - +
    - +

    There was an error logging in to your account.

    From 785ff9a089050ccf5c0c043afafbee82592e6ad5 Mon Sep 17 00:00:00 2001 From: Alex H Date: Mon, 17 Apr 2023 21:08:20 -0400 Subject: [PATCH 15/22] improper totalAmount comparison, wrong case on object prop --- ui/src/router/views/import-generic.vue | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue index 0cd4a07..35bbb11 100644 --- a/ui/src/router/views/import-generic.vue +++ b/ui/src/router/views/import-generic.vue @@ -94,8 +94,8 @@ export default { }, '') } const calculateTotal = (row) => { - return this.fileHeadingMap.totalAmount === "-1" - ? (row[this.fileHeadings.fuelQuantity] * row[this.fileHeadings.perUnitPrice]).toFixed(2) + return this.fileHeadingMap.totalAmount === -1 + ? row[this.fileHeadingMap.fuelQuantity] * row[this.fileHeadingMap.perUnitPrice] : row[this.fileHeadingMap.totalAmount] } @@ -142,7 +142,7 @@ export default { try { const content = { data: this.csvToJson(), - vehicleId: this.selectedVehicle.Id, + vehicleId: this.selectedVehicle.id, timezone: this.getTimezone(), } axios @@ -180,7 +180,7 @@ export default { if (typeof tankFull !== 'boolean' && typeof tankFull === 'string') { this.isFullTankString = true } - } + }, }, } @@ -202,7 +202,9 @@ export default {
  • {{ $t('importhintvehiclecreated') }}
  • -
  • {{ $t('dontimportagain') }}
  • +
  • + {{ $t('dontimportagain') }} +
  • @@ -270,8 +272,7 @@ export default {
    - +
    - +

    There was an error logging in to your account.

    From e9812e7e270d6e30cc60d7058f8e2e172aefccc9 Mon Sep 17 00:00:00 2001 From: Alex H Date: Mon, 17 Apr 2023 21:10:31 -0400 Subject: [PATCH 16/22] fixed dateLayout, fixed variable order in call to ParseInLocation, code formatting --- server/service/genericImportService.go | 42 ++++++++++++++------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/server/service/genericImportService.go b/server/service/genericImportService.go index df2bc75..463094e 100644 --- a/server/service/genericImportService.go +++ b/server/service/genericImportService.go @@ -1,6 +1,7 @@ package service import ( + "fmt" "hammond/db" "hammond/models" "time" @@ -9,11 +10,12 @@ import ( func GenericParseRefuelings(content []models.ImportFillup, user *db.User, vehicle *db.Vehicle, timezone string) ([]db.Fillup, []string) { var errors []string var fillups []db.Fillup - dateLayout := "2023-04-16T04:41:25.682Z" + dateLayout := "2006-01-02T15:04:05.000Z" loc, _ := time.LoadLocation(timezone) for _, record := range content { - date, err := time.ParseInLocation(record.Date, dateLayout, loc) + date, err := time.ParseInLocation(dateLayout, record.Date, loc) if err != nil { + fmt.Println(err) date = time.Date(2000, time.December, 0, 0, 0, 0, 0, loc) } @@ -24,24 +26,24 @@ func GenericParseRefuelings(content []models.ImportFillup, user *db.User, vehicl missedFillup = *record.HasMissedFillup } - fillups = append(fillups, db.Fillup{ - VehicleID: vehicle.ID, - UserID: user.ID, - Date: date, - IsTankFull: record.IsTankFull, - HasMissedFillup: &missedFillup, - FuelQuantity: float32(record.FuelQuantity), - PerUnitPrice: float32(record.PerUnitPrice), - FillingStation: record.FillingStation, - OdoReading: record.OdoReading, - TotalAmount: float32(record.TotalAmount), - FuelUnit: vehicle.FuelUnit, - Currency: user.Currency, - DistanceUnit: user.DistanceUnit, - Comments: record.Comments, - Source: "Generic Import", - }) + fillups = append(fillups, db.Fillup{ + VehicleID: vehicle.ID, + UserID: user.ID, + Date: date, + IsTankFull: record.IsTankFull, + HasMissedFillup: &missedFillup, + FuelQuantity: float32(record.FuelQuantity), + PerUnitPrice: float32(record.PerUnitPrice), + FillingStation: record.FillingStation, + OdoReading: record.OdoReading, + TotalAmount: float32(record.TotalAmount), + FuelUnit: vehicle.FuelUnit, + Currency: user.Currency, + DistanceUnit: user.DistanceUnit, + Comments: record.Comments, + Source: "Generic Import", + }) } return fillups, errors -} \ No newline at end of file +} From 24f295c632e15c6f060238c471397fe63e9548ed Mon Sep 17 00:00:00 2001 From: Alex H Date: Mon, 17 Apr 2023 21:17:32 -0400 Subject: [PATCH 17/22] forgot to remove a print statement --- server/service/genericImportService.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/service/genericImportService.go b/server/service/genericImportService.go index 463094e..7f9e2c9 100644 --- a/server/service/genericImportService.go +++ b/server/service/genericImportService.go @@ -1,7 +1,6 @@ package service import ( - "fmt" "hammond/db" "hammond/models" "time" @@ -15,7 +14,6 @@ func GenericParseRefuelings(content []models.ImportFillup, user *db.User, vehicl for _, record := range content { date, err := time.ParseInLocation(dateLayout, record.Date, loc) if err != nil { - fmt.Println(err) date = time.Date(2000, time.December, 0, 0, 0, 0, 0, loc) } From 094cf0d7c9a30c3cce493efcf7879642d8ad733a Mon Sep 17 00:00:00 2001 From: Alex H Date: Mon, 17 Apr 2023 22:19:01 -0400 Subject: [PATCH 18/22] added the ability to clear non-required fields, added a new icon --- ui/src/main.js | 2 + ui/src/router/views/import-generic.vue | 63 ++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/ui/src/main.js b/ui/src/main.js index cb336b0..e21c08b 100644 --- a/ui/src/main.js +++ b/ui/src/main.js @@ -7,6 +7,7 @@ import { faCheck, faTimes, faArrowUp, + faArrowRotateLeft, faAngleLeft, faAngleRight, faCalendar, @@ -38,6 +39,7 @@ library.add( faCheck, faTimes, faArrowUp, + faArrowRotateLeft, faAngleLeft, faAngleRight, faCalendar, diff --git a/ui/src/router/views/import-generic.vue b/ui/src/router/views/import-generic.vue index 35bbb11..5a3db76 100644 --- a/ui/src/router/views/import-generic.vue +++ b/ui/src/router/views/import-generic.vue @@ -181,6 +181,13 @@ export default { this.isFullTankString = true } }, + clearHeadingProperty(property) { + if (property === 'comments') { + this.fileHeadingMap[property] = [] + } else { + this.fileHeadingMap[property] = null + } + }, }, } @@ -258,7 +265,19 @@ export default {
    - + + - + + - + + - + +