Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option in vehicle stats to choose what mileage metric to show #108

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8410674
Add vin field vehicle data
AlfHou Mar 8, 2022
c00c6bc
Map VIN number to db model from request model when creating vehicle
AlfHou Apr 28, 2022
ab94997
Add basic tests
djjudas21 May 17, 2022
966cac2
Add utils for converting imperial and metric
AlfHou Oct 15, 2022
2ecb113
Add mileage options to frontend
AlfHou Oct 15, 2022
c0db2c5
Calculate mileage based on mileageOption
AlfHou Oct 15, 2022
2d24c4b
Merge pull request #1 from djjudas21/ci
AlfHou Nov 26, 2022
afdfa31
Add vscode specific files to gitignore
AlfHou Nov 26, 2022
d3ce692
Merge branch 'master' into add-vin
AlfHou Nov 26, 2022
0b450dc
added translations
boerniee Jan 12, 2023
961ec30
set locale to browser locale
boerniee Jan 13, 2023
bb68c8c
translate units
boerniee Jan 13, 2023
5aabeda
update axios version fixes #104 (#4)
boerniee Jan 19, 2023
f9d24bc
Fix indentation in db migration
Jan 19, 2023
47810a8
Merge pull request #3 from AlfHou/add-vin
AlfHou Jan 19, 2023
311ac75
Update the package lock file
AlfHou Jan 22, 2023
e6e90d9
Merge pull request #9 from AlfHou/chore/update-package-lock
AlfHou Jan 22, 2023
19680b1
Remove the github action which ran npm tests
AlfHou Jan 24, 2023
0035897
Merge pull request #12 from AlfHou/bug/remove-npm-github-action
AlfHou Jan 24, 2023
6871a40
added not translated texts, changed translations
boerniee Jan 25, 2023
c588e34
translating fuelly import page
boerniee Jan 25, 2023
ee964a6
Fixed another translations
boerniee Jan 25, 2023
7d4b763
Merge branch 'master' into i18n
AlfHou Jan 25, 2023
ba27697
Merge pull request #5 from boerniee/i18n
AlfHou Jan 25, 2023
126aff7
Update workflow action for publishing to new docker hub repo
AlfHou Jan 24, 2023
08f2a35
Rename docker secret variable
AlfHou Jan 24, 2023
f96638d
Update readme with the correct url's and remove some specifics from f…
AlfHou Jan 24, 2023
a89ca5e
Update links in docker files to point to this repo
AlfHou Jan 25, 2023
9dab3d1
Point to this repo in ubuntu install docs
AlfHou Jan 25, 2023
4a55879
Update links in more info view in settings
AlfHou Jan 25, 2023
8e89484
Merge pull request #13 from AlfHou/chore/docker-push
AlfHou Jan 26, 2023
091cfdc
Merge branch 'master' into feat/state_mileage_option
AlfHou Jan 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions server/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,33 @@ func RandString(n int) string {
return string(b)
}

// A helper to convert from litres to gallon
func LitreToGallon(litres float32) float32 {
gallonConversionFactor := 0.21997
return litres * float32(gallonConversionFactor);
}

// A helper to convert from gallon to litres
func GallonToLitre(gallons float32) float32 {
litreConversionFactor := 3.785412
return gallons * float32(litreConversionFactor);
}


// A helper to convert from km to miles
func KmToMiles(km float32) float32 {
kmConversionFactor := 0.62137119
return km * float32(kmConversionFactor);
}

// A helper to convert from miles to km
func MilesToKm(miles float32) float32 {
milesConversionFactor := 1.609344
return miles * float32(milesConversionFactor);
}



// A Util function to generate jwt_token which can be used in the request header
func GenToken(id string, role db.Role) (string, string) {
jwt_token := jwt.New(jwt.GetSigningMethod("HS256"))
Expand Down
2 changes: 1 addition & 1 deletion server/controllers/reports.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func getMileageForVehicle(c *gin.Context) {
return
}

fillups, err := service.GetMileageByVehicleId(searchByIdQuery.Id, model.Since)
fillups, err := service.GetMileageByVehicleId(searchByIdQuery.Id, model.Since, model.MileageOption)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("getMileageForVehicle", err))
return
Expand Down
3 changes: 2 additions & 1 deletion server/models/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type MileageModel struct {
FuelQuantity float32 `form:"fuelQuantity" json:"fuelQuantity" binding:"required"`
PerUnitPrice float32 `form:"perUnitPrice" json:"perUnitPrice" binding:"required"`
Currency string `json:"currency"`

DistanceUnit db.DistanceUnit `form:"distanceUnit" json:"distanceUnit"`
Mileage float32 `form:"mileage" json:"mileage" binding:"mileage"`
CostPerMile float32 `form:"costPerMile" json:"costPerMile" binding:"costPerMile"`
OdoReading int `form:"odoReading" json:"odoReading" binding:"odoReading"`
Expand All @@ -35,4 +35,5 @@ func (b *MileageModel) MarshalJSON() ([]byte, error) {

type MileageQueryModel struct {
Since time.Time `json:"since" query:"since" form:"since"`
MileageOption string `json:"mileageOption" query:"mileageOption" form:"mileageOption"`
}
43 changes: 39 additions & 4 deletions server/service/reportService.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import (
"sort"
"time"

"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
)

func GetMileageByVehicleId(vehicleId string, since time.Time) (mileage []models.MileageModel, err error) {
func GetMileageByVehicleId(vehicleId string, since time.Time, mileageOption string) (mileage []models.MileageModel, err error) {
data, err := db.GetFillupsByVehicleIdSince(vehicleId, since)
if err != nil {
return nil, err
Expand Down Expand Up @@ -36,14 +37,48 @@ func GetMileageByVehicleId(vehicleId string, since time.Time) (mileage []models.
PerUnitPrice: currentFillup.PerUnitPrice,
OdoReading: currentFillup.OdoReading,
Currency: currentFillup.Currency,
DistanceUnit: currentFillup.DistanceUnit,
Mileage: 0,
CostPerMile: 0,
}

if currentFillup.IsTankFull != nil && *currentFillup.IsTankFull && (currentFillup.HasMissedFillup == nil || !(*currentFillup.HasMissedFillup)) {
distance := float32(currentFillup.OdoReading - lastFillup.OdoReading)
mileage.Mileage = distance / currentFillup.FuelQuantity
mileage.CostPerMile = distance / currentFillup.TotalAmount
currentOdoReading := float32(currentFillup.OdoReading);
lastFillupOdoReading := float32(lastFillup.OdoReading);
currentFuelQuantity := float32(currentFillup.FuelQuantity);
// If miles per gallon option and distanceUnit is km, convert from km to miles
// then check if fuel unit is litres. If it is, convert to gallons
if (mileageOption == "mpg" && mileage.DistanceUnit == db.KILOMETERS) {
currentOdoReading = common.KmToMiles(currentOdoReading);
lastFillupOdoReading = common.KmToMiles(lastFillupOdoReading);
if (mileage.FuelUnit == db.LITRE) {
currentFuelQuantity = common.LitreToGallon(currentFuelQuantity);
}
}

// If km_litre option or litre per 100km and distanceUnit is miles, convert from miles to km
// then check if fuel unit is not litres. If it isn't, convert to litres

if ((mileageOption == "km_litre" || mileageOption == "litre_100km") && mileage.DistanceUnit == db.MILES) {
currentOdoReading = common.MilesToKm(currentOdoReading);
lastFillupOdoReading = common.MilesToKm(lastFillupOdoReading);

if (mileage.FuelUnit == db.US_GALLON) {
currentFuelQuantity = common.GallonToLitre(currentFuelQuantity);
}
}




distance := float32(currentOdoReading - lastFillupOdoReading);
if (mileageOption == "litre_100km") {
mileage.Mileage = currentFuelQuantity / distance * 100;
} else {
mileage.Mileage = distance / currentFuelQuantity;
}

mileage.CostPerMile = distance / currentFillup.TotalAmount;

}

Expand Down
34 changes: 27 additions & 7 deletions ui/src/components/mileageChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@ import { Line } from 'vue-chartjs'

import axios from 'axios'
import { mapState } from 'vuex'
import { string } from 'yargs'
export default {
extends: Line,
props: { vehicle: { type: Object, required: true }, since: { type: Date, default: '' }, user: { type: Object, required: true } },
props: {
vehicle: { type: Object, required: true },
since: { type: Date, default: '' },
user: { type: Object, required: true },
mileageOption: { type: string, default: 'litre_100km' },
},
data: function() {
return {
chartData: [],
}
},
computed: {
...mapState('utils', ['isMobile']),
},
Expand All @@ -17,20 +28,28 @@ export default {
this.fetchMileage()
},
},
data: function() {
return {
chartData: [],
}
},
mounted() {
this.fetchMileage()
},
methods: {
showChart() {
let mileageLabel = ''
switch (this.mileageOption) {
case 'litre_100km':
mileageLabel = 'L/100km'
break
case 'km_litre':
mileageLabel = 'km/L'
break
case 'mpg':
mileageLabel = 'mpg'
break
}

var labels = this.chartData.map((x) => x.date.substr(0, 10))
var dataset = {
steppedLine: true,
label: `Mileage (${this.user.distanceUnitDetail.short}/${this.vehicle.fuelUnitDetail.short})`,
label: `Mileage (${mileageLabel})`,
fill: true,
data: this.chartData.map((x) => x.mileage),
}
Expand All @@ -41,6 +60,7 @@ export default {
.get(`/api/vehicles/${this.vehicle.id}/mileage`, {
params: {
since: this.since,
mileageOption: this.mileageOption,
},
})
.then((response) => {
Expand Down
31 changes: 24 additions & 7 deletions ui/src/router/views/vehicle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ export default {
{ label: 'All Time', value: 'all_time' },
],
dateRangeOption: 'past_30_days',
mileageOptions: [
{ label: 'L/100km', value: 'litre_100km' },
{ label: 'km/L', value: 'km_litre' },
{ label: 'mpg', value: 'mpg' },
],
mileageOption: 'litre_100km',
}
},
computed: {
Expand Down Expand Up @@ -529,14 +535,25 @@ export default {
<div class="columns">
<div class="column" :class="isMobile ? 'has-text-centered' : ''"> <h1 class="title">Stats</h1></div>
<div class="column">
<b-select v-model="dateRangeOption" class="is-pulled-right is-medium">
<option v-for="option in dateRangeOptions" :key="option.value" :value="option.value">
{{ option.label }}
</option>
</b-select></div
>
<div class="columns is-pulled-right is-medium">
<div class="column">
<b-select v-model="mileageOption">
<option v-for="option in mileageOptions" :key="option.value" :value="option.value">
{{ option.label }}
</option>
</b-select>
</div>
<div class="column">
<b-select v-model="dateRangeOption">
<option v-for="option in dateRangeOptions" :key="option.value" :value="option.value">
{{ option.label }}
</option>
</b-select>
</div>
</div>
</div>
</div>
<MileageChart :vehicle="vehicle" :since="getStartDate()" :user="me" :height="300" />
<MileageChart :vehicle="vehicle" :since="getStartDate()" :user="me" :height="300" :mileage-option="mileageOption" />
</div>
</Layout>
</template>