From f851a2dc191cd1df51e1d1c11e5a5aabea81996a Mon Sep 17 00:00:00 2001 From: Akhil Gupta Date: Sun, 27 Jun 2021 11:04:58 +0530 Subject: [PATCH] import from Fuelly complete --- server/controllers/import.go | 6 +- server/db/dbModels.go | 2 + server/service/importService.go | 34 +++-- server/service/vehicleService.go | 2 + ui/src/components/nav-bar.vue | 8 +- ui/src/router/routes.js | 22 +++- ui/src/router/views/import-fuelly.unit.js | 7 ++ ui/src/router/views/import-fuelly.vue | 144 ++++++++++++++++++++++ ui/src/router/views/import.unit.js | 7 ++ ui/src/router/views/import.vue | 37 ++++++ 10 files changed, 247 insertions(+), 22 deletions(-) create mode 100644 ui/src/router/views/import-fuelly.unit.js create mode 100644 ui/src/router/views/import-fuelly.vue create mode 100644 ui/src/router/views/import.unit.js create mode 100644 ui/src/router/views/import.vue diff --git a/server/controllers/import.go b/server/controllers/import.go index 746c38a..38a897d 100644 --- a/server/controllers/import.go +++ b/server/controllers/import.go @@ -17,9 +17,9 @@ func fuellyImport(c *gin.Context) { c.JSON(http.StatusUnprocessableEntity, err) return } - err = service.FuellyImport(bytes, c.MustGet("userId").(string)) - if err != nil { - c.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()}) + errors := service.FuellyImport(bytes, c.MustGet("userId").(string)) + if len(errors) > 0 { + c.JSON(http.StatusUnprocessableEntity, gin.H{"errors": errors}) return } c.JSON(http.StatusOK, gin.H{}) diff --git a/server/db/dbModels.go b/server/db/dbModels.go index d0966d1..e3861d5 100644 --- a/server/db/dbModels.go +++ b/server/db/dbModels.go @@ -117,6 +117,7 @@ type Fillup struct { Date time.Time `json:"date"` Currency string `json:"currency"` DistanceUnit DistanceUnit `json:"distanceUnit"` + Source string `json:"source"` } func (v *Fillup) FuelUnitDetail() EnumDetail { @@ -145,6 +146,7 @@ type Expense struct { Date time.Time `json:"date"` Currency string `json:"currency"` DistanceUnit DistanceUnit `json:"distanceUnit"` + Source string `json:"source"` } type Setting struct { diff --git a/server/service/importService.go b/server/service/importService.go index 92ea4f3..237b0b7 100644 --- a/server/service/importService.go +++ b/server/service/importService.go @@ -5,30 +5,33 @@ import ( "encoding/csv" "fmt" "strconv" - "strings" "time" "github.com/akhilrex/hammond/db" "github.com/leekchan/accounting" ) -func FuellyImport(content []byte, userId string) error { +func FuellyImport(content []byte, userId string) []string { stream := bytes.NewReader(content) reader := csv.NewReader(stream) records, err := reader.ReadAll() + var errors []string if err != nil { - return err + errors = append(errors, err.Error()) + return errors } vehicles, err := GetUserVehicles(userId) if err != nil { - return err + errors = append(errors, err.Error()) + return errors } user, err := GetUserById(userId) if err != nil { - return err + errors = append(errors, err.Error()) + return errors } var vehicleMap map[string]db.Vehicle = make(map[string]db.Vehicle) @@ -41,8 +44,6 @@ func FuellyImport(content []byte, userId string) error { layout := "2006-01-02 15:04" altLayout := "2006-01-02 3:04 PM" - var errors []string - for index, record := range records { if index == 0 { continue @@ -111,6 +112,7 @@ func FuellyImport(content []byte, userId string) error { Date: date, Currency: user.Currency, DistanceUnit: user.DistanceUnit, + Source: "Fuelly", }) } @@ -128,12 +130,13 @@ func FuellyImport(content []byte, userId string) error { Currency: user.Currency, Date: date, DistanceUnit: user.DistanceUnit, + Source: "Fuelly", }) } } if len(errors) != 0 { - return fmt.Errorf(strings.Join(errors, "\n")) + return errors } tx := db.DB.Begin() @@ -143,15 +146,22 @@ func FuellyImport(content []byte, userId string) error { } }() if err := tx.Error; err != nil { - return err + errors = append(errors, err.Error()) + return errors } if err := tx.Create(&fillups).Error; err != nil { tx.Rollback() - return err + errors = append(errors, err.Error()) + return errors } if err := tx.Create(&expenses).Error; err != nil { tx.Rollback() - return err + errors = append(errors, err.Error()) + return errors } - return tx.Commit().Error + err = tx.Commit().Error + if err != nil { + errors = append(errors, err.Error()) + } + return errors } diff --git a/server/service/vehicleService.go b/server/service/vehicleService.go index 5866d7b..e8ee23a 100644 --- a/server/service/vehicleService.go +++ b/server/service/vehicleService.go @@ -139,6 +139,7 @@ func CreateFillup(model models.CreateFillupRequest) (*db.Fillup, error) { Date: model.Date, Currency: user.Currency, DistanceUnit: user.DistanceUnit, + Source: "API", } tx := db.DB.Create(&fillup) @@ -166,6 +167,7 @@ func CreateExpense(model models.CreateExpenseRequest) (*db.Expense, error) { Date: model.Date, Currency: user.Currency, DistanceUnit: user.DistanceUnit, + Source: "API", } tx := db.DB.Create(&expense) diff --git a/ui/src/components/nav-bar.vue b/ui/src/components/nav-bar.vue index 2792b03..fbac02b 100644 --- a/ui/src/components/nav-bar.vue +++ b/ui/src/components/nav-bar.vue @@ -19,10 +19,10 @@ export default { title: () => 'Quick Entries', badge: () => this.unprocessedQuickEntries.length, }, - // { - // name: 'profile', - // title: () => 'Logged in as ' + this.currentUser.name, - // }, + { + name: 'import', + title: () => 'Import', + }, { name: 'settings', title: 'Settings', diff --git a/ui/src/router/routes.js b/ui/src/router/routes.js index a068497..82495f7 100644 --- a/ui/src/router/routes.js +++ b/ui/src/router/routes.js @@ -392,6 +392,24 @@ export default [ }, props: (route) => ({ user: store.state.auth.currentUser || {} }), }, + { + path: '/import', + name: 'import', + component: () => lazyLoadView(import('@views/import.vue')), + meta: { + authRequired: true, + }, + props: (route) => ({ user: store.state.auth.currentUser || {} }), + }, + { + path: '/import/fuelly', + name: 'import-fuelly', + component: () => lazyLoadView(import('@views/import-fuelly.vue')), + meta: { + authRequired: true, + }, + props: (route) => ({ user: store.state.auth.currentUser || {} }), + }, { path: '/logout', name: 'logout', @@ -399,9 +417,7 @@ export default [ authRequired: true, beforeResolve(routeTo, routeFrom, next) { store.dispatch('auth/logOut').then((data) => { - const authRequiredOnPreviousRoute = routeFrom.matched.some( - (route) => route.meta.authRequired - ) + const authRequiredOnPreviousRoute = routeFrom.matched.some((route) => route.meta.authRequired) // Navigate back to previous page, or home as a fallback next(authRequiredOnPreviousRoute ? { name: 'login' } : { ...routeFrom }) }) diff --git a/ui/src/router/views/import-fuelly.unit.js b/ui/src/router/views/import-fuelly.unit.js new file mode 100644 index 0000000..d570ae0 --- /dev/null +++ b/ui/src/router/views/import-fuelly.unit.js @@ -0,0 +1,7 @@ +import ImportFuelly from './import-fuelly' + +describe('@views/import-fuelly', () => { + it('is a valid view', () => { + expect(ImportFuelly).toBeAViewComponent() + }) +}) diff --git a/ui/src/router/views/import-fuelly.vue b/ui/src/router/views/import-fuelly.vue new file mode 100644 index 0000000..5a43d5a --- /dev/null +++ b/ui/src/router/views/import-fuelly.vue @@ -0,0 +1,144 @@ + + + diff --git a/ui/src/router/views/import.unit.js b/ui/src/router/views/import.unit.js new file mode 100644 index 0000000..3897232 --- /dev/null +++ b/ui/src/router/views/import.unit.js @@ -0,0 +1,7 @@ +import Import from './import' + +describe('@views/import', () => { + it('is a valid view', () => { + expect(Import).toBeAViewComponent() + }) +}) diff --git a/ui/src/router/views/import.vue b/ui/src/router/views/import.vue new file mode 100644 index 0000000..f92b9f9 --- /dev/null +++ b/ui/src/router/views/import.vue @@ -0,0 +1,37 @@ + + +