package service import ( "bytes" "encoding/csv" "fmt" "strconv" "time" "github.com/akhilrex/hammond/db" "github.com/leekchan/accounting" ) 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 { errors = append(errors, err.Error()) return errors } vehicles, err := GetUserVehicles(userId) if err != nil { errors = append(errors, err.Error()) return errors } user, err := GetUserById(userId) if err != nil { errors = append(errors, err.Error()) return errors } var vehicleMap map[string]db.Vehicle = make(map[string]db.Vehicle) for _, vehicle := range *vehicles { vehicleMap[vehicle.Nickname] = vehicle } var fillups []db.Fillup var expenses []db.Expense layout := "2006-01-02 15:04" altLayout := "2006-01-02 3:04 PM" for index, record := range records { if index == 0 { continue } var vehicle db.Vehicle var ok bool if vehicle, ok = vehicleMap[record[4]]; !ok { errors = append(errors, "Found an unmapped vehicle entry at row "+strconv.Itoa(index+1)) } dateStr := record[2] + " " + record[3] date, err := time.Parse(layout, dateStr) if err != nil { date, err = time.Parse(altLayout, dateStr) } if err != nil { errors = append(errors, "Found an invalid date/time at row "+strconv.Itoa(index+1)) } totalCostStr := accounting.UnformatNumber(record[9], 3, user.Currency) totalCost64, err := strconv.ParseFloat(totalCostStr, 32) if err != nil { errors = append(errors, "Found an invalid total cost at row "+strconv.Itoa(index+1)) } totalCost := float32(totalCost64) odoStr := accounting.UnformatNumber(record[5], 0, user.Currency) odoreading, err := strconv.Atoi(odoStr) if err != nil { errors = append(errors, "Found an invalid odo reading at row "+strconv.Itoa(index+1)) } location := record[12] //Create Fillup if record[0] == "Gas" { rateStr := accounting.UnformatNumber(record[7], 3, user.Currency) ratet64, err := strconv.ParseFloat(rateStr, 32) if err != nil { errors = append(errors, "Found an invalid cost per gallon at row "+strconv.Itoa(index+1)) } rate := float32(ratet64) quantity64, err := strconv.ParseFloat(record[8], 32) if err != nil { errors = append(errors, "Found an invalid quantity at row "+strconv.Itoa(index+1)) } quantity := float32(quantity64) notes := fmt.Sprintf("Octane:%s\nGas Brand:%s\nLocation%s\nTags:%s\nPayment Type:%s\nTire Pressure:%s\nNotes:%s\nMPG:%s", record[10], record[11], record[12], record[13], record[14], record[15], record[16], record[1], ) isTankFull := record[6] == "Full" fillups = append(fillups, db.Fillup{ VehicleID: vehicle.ID, FuelUnit: vehicle.FuelUnit, FuelQuantity: quantity, PerUnitPrice: rate, TotalAmount: totalCost, OdoReading: odoreading, IsTankFull: &isTankFull, Comments: notes, FillingStation: location, UserID: userId, Date: date, Currency: user.Currency, DistanceUnit: user.DistanceUnit, Source: "Fuelly", }) } if record[0] == "Service" { notes := fmt.Sprintf("Tags:%s\nPayment Type:%s\nNotes:%s", record[13], record[14], record[16], ) expenses = append(expenses, db.Expense{ VehicleID: vehicle.ID, Amount: totalCost, OdoReading: odoreading, Comments: notes, ExpenseType: record[17], UserID: userId, Currency: user.Currency, Date: date, DistanceUnit: user.DistanceUnit, Source: "Fuelly", }) } } if len(errors) != 0 { return errors } tx := db.DB.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() if err := tx.Error; err != nil { errors = append(errors, err.Error()) return errors } if err := tx.Create(&fillups).Error; err != nil { tx.Rollback() errors = append(errors, err.Error()) return errors } if err := tx.Create(&expenses).Error; err != nil { tx.Rollback() errors = append(errors, err.Error()) return errors } err = tx.Commit().Error if err != nil { errors = append(errors, err.Error()) } return errors }