From d1202d4081b020502a5f20c0bff8131abe0fa9a5 Mon Sep 17 00:00:00 2001 From: Ondrej Oravcok Date: Wed, 6 Sep 2017 11:46:44 +0200 Subject: [PATCH] #73 inserting fillUp done (Full + NotFull) --- .../piskula/fuelup/data/DatabaseHelper.java | 4 +- .../fuelup/data/provider/VehicleProvider.java | 122 ++++++++++++++++-- .../screens/edit/AddFillUpActivity.java | 6 + 3 files changed, 118 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/sk/piskula/fuelup/data/DatabaseHelper.java b/app/src/main/java/sk/piskula/fuelup/data/DatabaseHelper.java index 548ebd2..a98b0e7 100644 --- a/app/src/main/java/sk/piskula/fuelup/data/DatabaseHelper.java +++ b/app/src/main/java/sk/piskula/fuelup/data/DatabaseHelper.java @@ -37,7 +37,7 @@ public void onCreate(SQLiteDatabase db) { String SQL_CREATE_VEHICLES_TABLE = "CREATE TABLE " + VehicleEntry.TABLE_NAME + " (" + VehicleEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + VehicleEntry.COLUMN_NAME + " TEXT NOT NULL, " + + VehicleEntry.COLUMN_NAME + " TEXT NOT NULL UNIQUE, " + VehicleEntry.COLUMN_TYPE + " INTEGER NOT NULL, " + VehicleEntry.COLUMN_VOLUME_UNIT + " TEXT NOT NULL, " + VehicleEntry.COLUMN_VEHICLE_MAKER + " TEXT, " @@ -67,7 +67,7 @@ public void onCreate(SQLiteDatabase db) { + FillUpEntry.COLUMN_FUEL_PRICE_TOTAL + " REAL NOT NULL, " + FillUpEntry.COLUMN_IS_FULL_FILLUP + " INTEGER NOT NULL, " + FillUpEntry.COLUMN_FUEL_CONSUMPTION + " INTEGER, " - + FillUpEntry.COLUMN_DATE + " INTEGER NOT NULL, " + + FillUpEntry.COLUMN_DATE + " INTEGER NOT NULL UNIQUE, " + FillUpEntry.COLUMN_INFO + " TEXT, " + "FOREIGN KEY(" + FillUpEntry.COLUMN_VEHICLE + ") REFERENCES " diff --git a/app/src/main/java/sk/piskula/fuelup/data/provider/VehicleProvider.java b/app/src/main/java/sk/piskula/fuelup/data/provider/VehicleProvider.java index b40abc3..313d85d 100644 --- a/app/src/main/java/sk/piskula/fuelup/data/provider/VehicleProvider.java +++ b/app/src/main/java/sk/piskula/fuelup/data/provider/VehicleProvider.java @@ -601,27 +601,125 @@ private Uri insertFullValidatedFillUp(Uri uri, ContentValues contentValues) { return ContentUris.withAppendedId(uri, id); } - private Uri validateFillUpAndInsert(Uri uri, ContentValues contentValues) { - - validateFillUpBasics(contentValues, false); + private Uri insertNotFullValidatedFillUp(Uri uri, ContentValues contentValues) { - boolean isFullFillUp = 1 == contentValues.getAsInteger(FillUpEntry.COLUMN_IS_FULL_FILLUP); + // first insert fillUp + long id = mDbHelper.getWritableDatabase().insert(FillUpEntry.TABLE_NAME, null, contentValues); - if (isFullFillUp) { - return insertFullValidatedFillUp(uri, contentValues); + long vehicleId = contentValues.getAsLong(FillUpEntry.COLUMN_VEHICLE); + long timestamp = contentValues.getAsLong(FillUpEntry.COLUMN_DATE); - } else { - SQLiteDatabase database = mDbHelper.getWritableDatabase(); - long id = database.insert(FillUpEntry.TABLE_NAME, null, contentValues); + // then recalculate consumption + // firstly count newer fillUps + String selectionNewer = FillUpEntry.COLUMN_VEHICLE + "=? AND " + FillUpEntry.COLUMN_DATE + ">=?"; + String[] selectionNewerArgs = new String[] { String.valueOf(vehicleId), String.valueOf(timestamp) }; - if (id == -1) { - Log.e(LOG_TAG, "Failed to insert row for " + uri); - return null; + Cursor cursorNewerFillUps = mDbHelper.getReadableDatabase().query( + FillUpEntry.TABLE_NAME, + FuelUpContract.ALL_COLUMNS_FILLUPS, + selectionNewer, + selectionNewerArgs, + null, + null, + FillUpEntry.COLUMN_DATE + " ASC"); + + // find fillups until full newer fillUp + List newerIds = new ArrayList<>(); + BigDecimal newerFuelUpsVol = BigDecimal.ZERO; + Long newerFuelUpsDistance = 0L; + boolean existsNewerFullFillUp = false; + + while (cursorNewerFillUps.moveToNext()) { + newerIds.add(cursorNewerFillUps.getLong(cursorNewerFillUps.getColumnIndexOrThrow(FillUpEntry._ID))); + newerFuelUpsDistance += cursorNewerFillUps.getLong(cursorNewerFillUps.getColumnIndexOrThrow(FillUpEntry.COLUMN_DISTANCE_FROM_LAST)); + newerFuelUpsVol = newerFuelUpsVol.add(BigDecimal.valueOf(cursorNewerFillUps.getDouble(cursorNewerFillUps.getColumnIndexOrThrow(FillUpEntry.COLUMN_FUEL_VOLUME)))); + if (1 == cursorNewerFillUps.getInt(cursorNewerFillUps.getColumnIndexOrThrow(FillUpEntry.COLUMN_IS_FULL_FILLUP))) { + existsNewerFullFillUp = true; + break; + } + } + cursorNewerFillUps.close(); + + // if there is no newer full fill up, we do not compute consumption + if (!existsNewerFullFillUp) { + getContext().getContentResolver().notifyChange(uri, null); + return ContentUris.withAppendedId(uri, id); + } + + // secondly count older fillUps until full (respecting this) + String selectionOlder = FillUpEntry.COLUMN_VEHICLE + "=? AND " + FillUpEntry.COLUMN_DATE + " olderIds = new ArrayList<>(); + BigDecimal olderFuelUpsVol = BigDecimal.ZERO; + Long olderFuelUpsDistance = 0L; + boolean existsOlderFullFillUp = false; + + while (cursorOlderFillUps.moveToNext()) { + if (1 == cursorOlderFillUps.getInt(cursorOlderFillUps.getColumnIndexOrThrow(FillUpEntry.COLUMN_IS_FULL_FILLUP))) { + existsOlderFullFillUp = true; + break; } + olderIds.add(cursorOlderFillUps.getLong(cursorOlderFillUps.getColumnIndexOrThrow(FillUpEntry._ID))); + olderFuelUpsDistance += cursorOlderFillUps.getLong(cursorOlderFillUps.getColumnIndexOrThrow(FillUpEntry.COLUMN_DISTANCE_FROM_LAST)); + olderFuelUpsVol = olderFuelUpsVol.add(BigDecimal.valueOf(cursorOlderFillUps.getDouble(cursorOlderFillUps.getColumnIndexOrThrow(FillUpEntry.COLUMN_FUEL_VOLUME)))); + } + cursorOlderFillUps.close(); + // if there is no older full fill up, we do not compute consumption + if (!existsOlderFullFillUp) { getContext().getContentResolver().notifyChange(uri, null); return ContentUris.withAppendedId(uri, id); } + + // update all neighbouring fillUps with new consumption + // compute consumption for all + VolumeUnit unit = VehicleService.getVehicleById(vehicleId, getContext()).getVolumeUnit(); + BigDecimal fuelVol = newerFuelUpsVol.add(olderFuelUpsVol); + Long distance = newerFuelUpsDistance + olderFuelUpsDistance; + BigDecimal avgConsumption = FillUpService.getConsumptionFromVolumeDistance(fuelVol, distance, unit); + + ContentValues contentValuesUpdate = new ContentValues(); + contentValuesUpdate.put(FillUpEntry.COLUMN_FUEL_CONSUMPTION, avgConsumption.doubleValue()); + + String selectionUpdate = FillUpEntry._ID + "=?"; + String[] selectionUpdateArgs; + + newerIds.addAll(olderIds); + // and update all not full until it including it + for (Long fillUpId : newerIds) { + selectionUpdateArgs = new String[] { String.valueOf(fillUpId) }; + mDbHelper.getWritableDatabase().update( + FillUpEntry.TABLE_NAME, + contentValuesUpdate, + selectionUpdate, + selectionUpdateArgs); + } + + getContext().getContentResolver().notifyChange(uri, null); + return ContentUris.withAppendedId(uri, id); + } + + private Uri validateFillUpAndInsert(Uri uri, ContentValues contentValues) { + + validateFillUpBasics(contentValues, false); + + boolean isFullFillUp = 1 == contentValues.getAsInteger(FillUpEntry.COLUMN_IS_FULL_FILLUP); + if (isFullFillUp) { + return insertFullValidatedFillUp(uri, contentValues); + } else { + return insertNotFullValidatedFillUp(uri, contentValues); + } } private Uri validateVehicleTypeAndInsert(Uri uri, ContentValues contentValues) { diff --git a/app/src/main/java/sk/piskula/fuelup/screens/edit/AddFillUpActivity.java b/app/src/main/java/sk/piskula/fuelup/screens/edit/AddFillUpActivity.java index 7120db9..dbb7248 100644 --- a/app/src/main/java/sk/piskula/fuelup/screens/edit/AddFillUpActivity.java +++ b/app/src/main/java/sk/piskula/fuelup/screens/edit/AddFillUpActivity.java @@ -23,6 +23,7 @@ import java.text.DecimalFormat; import java.text.ParseException; import java.util.Calendar; +import java.util.Date; import sk.piskula.fuelup.R; import sk.piskula.fuelup.business.FillUpService; @@ -124,7 +125,12 @@ public void onClickAdd(View view) { try { createdFuelVol = (BigDecimal) decimalFormat.parse(fuelVol.toString()); createdPrice = (BigDecimal) decimalFormat.parse(price.toString()); + Calendar timePart = Calendar.getInstance(); createdDate.setTime(dateFormatter.parse(date)); + createdDate.set(Calendar.HOUR, timePart.get(Calendar.HOUR)); + createdDate.set(Calendar.MINUTE, timePart.get(Calendar.MINUTE)); + createdDate.set(Calendar.SECOND, timePart.get(Calendar.SECOND)); + createdDate.set(Calendar.MILLISECOND, timePart.get(Calendar.MILLISECOND)); } catch (ParseException ex) { Log.d(TAG, "tried bad format", ex); throw new RuntimeException(ex);