- gradle version upgrade

- migrated to AndroidX
 - migrated to Kotlin
 - Content resolver unit test added
 - Upgraded android version to 31
This commit is contained in:
2023-08-22 17:10:11 +01:00
parent 8352735b17
commit 6a90d0bd17
45 changed files with 2414 additions and 2545 deletions

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidTestResultsUserPreferences">
<option name="androidTestResultsTableState">
<map>
<entry key="1283002349">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_6_Pro_API_31" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
</map>
</option>
</component>
</project>

6
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

4
.idea/gradle.xml generated
View File

@@ -5,16 +5,16 @@
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="delegatedBuild" value="false" /> <option name="delegatedBuild" value="false" />
<option name="testRunner" value="PLATFORM" /> <option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
</set> </set>
</option> </option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>

6
.idea/kotlinc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.0" />
</component>
</project>

3
.idea/misc.xml generated
View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="NullableNotNullManager"> <component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" /> <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
@@ -39,7 +38,7 @@
</value> </value>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

7
.idea/modules.xml generated
View File

@@ -2,8 +2,11 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/Shift_tracker.iml" filepath="$PROJECT_DIR$/Shift_tracker.iml" group="Shift_tracker" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/Farmr.iml" filepath="$PROJECT_DIR$/.idea/modules/Farmr.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" group="Shift_tracker/app" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/app/Farmr.app.iml" filepath="$PROJECT_DIR$/.idea/modules/app/Farmr.app.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/app/Farmr.app.androidTest.iml" filepath="$PROJECT_DIR$/.idea/modules/app/Farmr.app.androidTest.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/app/Farmr.app.main.iml" filepath="$PROJECT_DIR$/.idea/modules/app/Farmr.app.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/app/Farmr.app.unitTest.iml" filepath="$PROJECT_DIR$/.idea/modules/app/Farmr.app.unitTest.iml" />
</modules> </modules>
</component> </component>
</project> </project>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@@ -1,15 +1,15 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'
android { android {
compileSdkVersion 29 compileSdkVersion 31
buildToolsVersion '26.0.2'
defaultConfig { defaultConfig {
applicationId "com.appttude.h_mal.farmr" applicationId "com.appttude.h_mal.farmr"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 31
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
} }
buildTypes { buildTypes {
@@ -21,15 +21,16 @@ android {
} }
dependencies { dependencies {
implementation 'com.android.support:support-v4:26.1.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.android.support:support-vector-drawable:26.1.0' implementation 'androidx.vectordrawable:vectordrawable:1.0.0'
compile fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.core:core-ktx:1.1.0'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { testImplementation 'junit:junit:4.12'
exclude group: 'com.android.support', module: 'support-annotations' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
}) implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.google.android.material:material:1.0.0'
implementation 'com.android.support:design:26.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.ajts.androidmads.SQLite2Excel:library:1.0.2' implementation 'com.ajts.androidmads.SQLite2Excel:library:1.0.2'
testCompile 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:core-ktx:1.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
} }

View File

@@ -1,26 +0,0 @@
package com.appttude.h_mal.farmr;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.example.h_mal.shift_tracker", appContext.getPackageName());
}
}

View File

@@ -0,0 +1,36 @@
package com.appttude.h_mal.farmr.data
import android.icu.util.Calendar
import com.appttude.h_mal.farmr.model.ShiftType
import java.text.SimpleDateFormat
import java.util.UUID
import kotlin.random.Random
fun getShift() = ShiftType.values().toList().shuffled().first()
fun generateDescription() = UUID.randomUUID().toString()
fun generatePayRate() = Random.nextDouble(0.00, 50.00)
fun getRandomDate(): String {
val calendar = generateCalendar()
val format = SimpleDateFormat("yyyy-MM-dd")
return format.format(calendar) ?: "2010-12-28"
}
fun getRandomTime(): String {
val calendar = generateCalendar()
val format = SimpleDateFormat("hh:mm")
return format.format(calendar) ?: "11:00"
}
fun generateCalendar() = Calendar.getInstance().set(
Random.nextInt(2000, 2023),
Random.nextInt(12),
Random.nextInt(28),
Random.nextInt(0, 23),
Random.nextInt(0, 59)
)
fun getDurationInHours(timeOne: String, timeTwo: String) {
}

View File

@@ -0,0 +1,259 @@
package com.appttude.h_mal.farmr.data
import android.content.ContentResolver
import android.content.ContentValues
import androidx.test.rule.provider.ProviderTestRule
import com.appttude.h_mal.farmr.data.ShiftsContract.CONTENT_AUTHORITY
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_BREAK
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DATE
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DESCRIPTION
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DURATION
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_PAYRATE
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_IN
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_OUT
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TOTALPAY
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TYPE
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.COLUMN_SHIFT_UNIT
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry.CONTENT_URI
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry._ID
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNull
import org.junit.Rule
import org.junit.Test
class ShiftProviderTest {
@get:Rule
val providerRule: ProviderTestRule = ProviderTestRule
.Builder(ShiftProvider::class.java, CONTENT_AUTHORITY)
.build()
private val contentResolver: ContentResolver
get() = providerRule.resolver
@Test
fun insertEntry_queryEntry_assertEntry() {
// Arrange
val typeColumn = "Hourly"
val descriptionColumn = "Description string"
val dateColumn = "01/01/2010"
val timeInColumn = "09:00"
val timeOutColumn = "14:00"
val durationColumn = 4.50f
val breakOutColumn = 30
val unitColumn = 0f
val payrateColumn = 10.00f
val totalpayColumn = 45.00f
val values = ContentValues().apply {
put(COLUMN_SHIFT_TYPE, typeColumn)
put(COLUMN_SHIFT_DESCRIPTION, descriptionColumn)
put(COLUMN_SHIFT_DATE, dateColumn)
put(COLUMN_SHIFT_TIME_IN, timeInColumn)
put(COLUMN_SHIFT_TIME_OUT, timeOutColumn)
put(COLUMN_SHIFT_DURATION, durationColumn)
put(COLUMN_SHIFT_BREAK, breakOutColumn)
put(COLUMN_SHIFT_UNIT, unitColumn)
put(COLUMN_SHIFT_PAYRATE, payrateColumn)
put(COLUMN_SHIFT_TOTALPAY, totalpayColumn)
}
val projection = arrayOf(
_ID,
COLUMN_SHIFT_DESCRIPTION,
COLUMN_SHIFT_DATE,
COLUMN_SHIFT_TIME_IN,
COLUMN_SHIFT_TIME_OUT,
COLUMN_SHIFT_BREAK,
COLUMN_SHIFT_DURATION,
COLUMN_SHIFT_TYPE,
COLUMN_SHIFT_UNIT,
COLUMN_SHIFT_PAYRATE,
COLUMN_SHIFT_TOTALPAY)
// Act
contentResolver.insert(CONTENT_URI, values)
// Assert
val item = contentResolver.query(CONTENT_URI, projection, null, null, null)
item?.takeIf { it.moveToNext() }?.run {
val descriptionColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_DESCRIPTION))
val dateColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_DATE))
val timeInColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TIME_IN))
val timeOutColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TIME_OUT))
val durationColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_DURATION))
val breakOutColumnIndex = getInt(getColumnIndexOrThrow(COLUMN_SHIFT_BREAK))
val typeColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TYPE))
val unitColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_UNIT))
val payrateColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_PAYRATE))
val totalpayColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_TOTALPAY))
assertEquals(descriptionColumnIndex, descriptionColumn)
assertEquals(dateColumnIndex, dateColumn)
assertEquals(timeInColumnIndex, timeInColumn)
assertEquals(timeOutColumnIndex, timeOutColumn)
assertEquals(durationColumnIndex, durationColumn)
assertEquals(breakOutColumnIndex, breakOutColumn)
assertEquals(typeColumnIndex, typeColumn)
assertEquals(unitColumnIndex, unitColumn)
assertEquals(payrateColumnIndex, payrateColumn)
assertEquals(totalpayColumnIndex, totalpayColumn)
}
}
@Test
fun insertAndDeleteAllEntry_queryEntry_assertEntry() {
// Arrange
val typeColumn = "Hourly"
val descriptionColumn = "Description string"
val dateColumn = "01/01/2010"
val timeInColumn = "09:00"
val timeOutColumn = "14:00"
val durationColumn = 4.50f
val breakOutColumn = 30
val unitColumn = 0f
val payrateColumn = 10.00f
val totalpayColumn = 45.00f
val values = ContentValues().apply {
put(COLUMN_SHIFT_TYPE, typeColumn)
put(COLUMN_SHIFT_DESCRIPTION, descriptionColumn)
put(COLUMN_SHIFT_DATE, dateColumn)
put(COLUMN_SHIFT_TIME_IN, timeInColumn)
put(COLUMN_SHIFT_TIME_OUT, timeOutColumn)
put(COLUMN_SHIFT_DURATION, durationColumn)
put(COLUMN_SHIFT_BREAK, breakOutColumn)
put(COLUMN_SHIFT_UNIT, unitColumn)
put(COLUMN_SHIFT_PAYRATE, payrateColumn)
put(COLUMN_SHIFT_TOTALPAY, totalpayColumn)
}
val projection = arrayOf(
_ID,
COLUMN_SHIFT_DESCRIPTION,
COLUMN_SHIFT_DATE,
COLUMN_SHIFT_TIME_IN,
COLUMN_SHIFT_TIME_OUT,
COLUMN_SHIFT_BREAK,
COLUMN_SHIFT_DURATION,
COLUMN_SHIFT_TYPE,
COLUMN_SHIFT_UNIT,
COLUMN_SHIFT_PAYRATE,
COLUMN_SHIFT_TOTALPAY)
// Act
contentResolver.insert(CONTENT_URI, values)
val itemFirst = contentResolver.query(CONTENT_URI, projection, null, null, null)
contentResolver.delete(CONTENT_URI, null, null)
// Assert
itemFirst?.takeIf { it.moveToNext() }?.run {
val descriptionColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_DESCRIPTION))
val dateColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_DATE))
val timeInColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TIME_IN))
val timeOutColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TIME_OUT))
val durationColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_DURATION))
val breakOutColumnIndex = getInt(getColumnIndexOrThrow(COLUMN_SHIFT_BREAK))
val typeColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TYPE))
val unitColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_UNIT))
val payrateColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_PAYRATE))
val totalpayColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_TOTALPAY))
assertEquals(descriptionColumnIndex, descriptionColumn)
assertEquals(dateColumnIndex, dateColumn)
assertEquals(timeInColumnIndex, timeInColumn)
assertEquals(timeOutColumnIndex, timeOutColumn)
assertEquals(durationColumnIndex, durationColumn)
assertEquals(breakOutColumnIndex, breakOutColumn)
assertEquals(typeColumnIndex, typeColumn)
assertEquals(unitColumnIndex, unitColumn)
assertEquals(payrateColumnIndex, payrateColumn)
assertEquals(totalpayColumnIndex, totalpayColumn)
}
assertNull(contentResolver.query(CONTENT_URI, projection, null, null, null)?.takeIf { it.moveToNext() }?.run { getLong(getColumnIndexOrThrow(_ID)) })
}
@Test
fun insertAndDeleteSingleEntry_queryEntry_assertEntry() {
// Arrange
val typeColumn = "Hourly"
val descriptionColumn = "Description string"
val dateColumn = "01/01/2010"
val timeInColumn = "09:00"
val timeOutColumn = "14:00"
val durationColumn = 4.50f
val breakOutColumn = 30
val unitColumn = 0f
val payrateColumn = 10.00f
val totalpayColumn = 45.00f
val values = ContentValues().apply {
put(COLUMN_SHIFT_TYPE, typeColumn)
put(COLUMN_SHIFT_DESCRIPTION, descriptionColumn)
put(COLUMN_SHIFT_DATE, dateColumn)
put(COLUMN_SHIFT_TIME_IN, timeInColumn)
put(COLUMN_SHIFT_TIME_OUT, timeOutColumn)
put(COLUMN_SHIFT_DURATION, durationColumn)
put(COLUMN_SHIFT_BREAK, breakOutColumn)
put(COLUMN_SHIFT_UNIT, unitColumn)
put(COLUMN_SHIFT_PAYRATE, payrateColumn)
put(COLUMN_SHIFT_TOTALPAY, totalpayColumn)
}
val projection = arrayOf(
_ID,
COLUMN_SHIFT_DESCRIPTION,
COLUMN_SHIFT_DATE,
COLUMN_SHIFT_TIME_IN,
COLUMN_SHIFT_TIME_OUT,
COLUMN_SHIFT_BREAK,
COLUMN_SHIFT_DURATION,
COLUMN_SHIFT_TYPE,
COLUMN_SHIFT_UNIT,
COLUMN_SHIFT_PAYRATE,
COLUMN_SHIFT_TOTALPAY)
// Act
contentResolver.insert(CONTENT_URI, values)
val itemFirst = contentResolver.query(CONTENT_URI, projection, null, null, null)
val id = itemFirst?.takeIf { it.moveToNext() }?.run { getLong(getColumnIndexOrThrow(_ID)) }
contentResolver.delete(CONTENT_URI, "$_ID=?", arrayOf(id.toString()))
// Assert
itemFirst?.takeIf { it.moveToNext() }?.run {
val descriptionColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_DESCRIPTION))
val dateColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_DATE))
val timeInColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TIME_IN))
val timeOutColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TIME_OUT))
val durationColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_DURATION))
val breakOutColumnIndex = getInt(getColumnIndexOrThrow(COLUMN_SHIFT_BREAK))
val typeColumnIndex = getString(getColumnIndexOrThrow(COLUMN_SHIFT_TYPE))
val unitColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_UNIT))
val payrateColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_PAYRATE))
val totalpayColumnIndex = getFloat(getColumnIndexOrThrow(COLUMN_SHIFT_TOTALPAY))
assertEquals(descriptionColumnIndex, descriptionColumn)
assertEquals(dateColumnIndex, dateColumn)
assertEquals(timeInColumnIndex, timeInColumn)
assertEquals(timeOutColumnIndex, timeOutColumn)
assertEquals(durationColumnIndex, durationColumn)
assertEquals(breakOutColumnIndex, breakOutColumn)
assertEquals(typeColumnIndex, typeColumn)
assertEquals(unitColumnIndex, unitColumn)
assertEquals(payrateColumnIndex, payrateColumn)
assertEquals(totalpayColumnIndex, totalpayColumn)
}
assertNull(contentResolver.query(CONTENT_URI, projection, null, null, null)?.takeIf { it.moveToNext() }?.run { getLong(getColumnIndexOrThrow(_ID))})
}
private fun createContentValue() = ContentValues().apply {
put(COLUMN_SHIFT_TYPE, getShift().type)
put(COLUMN_SHIFT_DESCRIPTION, generateDescription())
put(COLUMN_SHIFT_DATE, getRandomDate())
put(COLUMN_SHIFT_TIME_IN, getRandomTime())
put(COLUMN_SHIFT_TIME_OUT, getRandomTime())
put(COLUMN_SHIFT_DURATION, 6)
put(COLUMN_SHIFT_BREAK, 0)
put(COLUMN_SHIFT_UNIT, 6)
put(COLUMN_SHIFT_PAYRATE, 11)
put(COLUMN_SHIFT_TOTALPAY, 6 * 11)
}
}

View File

@@ -17,10 +17,10 @@
<!-- Splash screen --> <!-- Splash screen -->
<activity <activity
android:name="com.appttude.h_mal.farmr.SplashScreen" android:name="com.appttude.h_mal.farmr.SplashScreen"
android:label="@string/app_name"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
tools:ignore="LockedOrientationActivity"> tools:ignore="LockedOrientationActivity"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
@@ -28,12 +28,12 @@
</activity> </activity>
<activity <activity
android:name="com.appttude.h_mal.farmr.MainActivity" android:name="com.appttude.h_mal.farmr.MainActivity"
android:label="@string/app_name"
android:parentActivityName="com.appttude.h_mal.farmr.SplashScreen" android:parentActivityName="com.appttude.h_mal.farmr.SplashScreen"
android:theme="@style/AppTheme.NoActionBar"/> android:theme="@style/AppTheme.NoActionBar"
android:exported="true"/>
<provider <provider
android:name="com.appttude.h_mal.farmr.Data.ShiftProvider" android:name="com.appttude.h_mal.farmr.data.ShiftProvider"
android:authorities="com.appttude.h_mal.farmr" android:authorities="com.appttude.h_mal.farmr"
android:exported="false" /> android:exported="false" />
</application> </application>

View File

@@ -1,263 +0,0 @@
package com.appttude.h_mal.farmr.Data;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
import com.appttude.h_mal.farmr.Data.ShiftsContract.ShiftsEntry;
/**
* Created by h_mal on 26/12/2017.
*/
public class ShiftProvider extends ContentProvider {
public static final String LOG_TAG = ShiftProvider.class.getSimpleName();
private static final int SHIFTS = 100;
private static final int SHIFT_ID = 101;
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sUriMatcher.addURI(ShiftsContract.CONTENT_AUTHORITY, ShiftsContract.PATH_SHIFTS, SHIFTS);
sUriMatcher.addURI(ShiftsContract.CONTENT_AUTHORITY, ShiftsContract.PATH_SHIFTS + "/#", SHIFT_ID);
}
ShiftsDbHelper mDbHelper;
public ShiftProvider() {
}
@Override
public boolean onCreate() {
mDbHelper = new ShiftsDbHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteDatabase database = mDbHelper.getReadableDatabase();
Cursor cursor;
int match = sUriMatcher.match(uri);
switch (match) {
case SHIFTS:
cursor = database.query(ShiftsEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
case SHIFT_ID:
selection = ShiftsEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
cursor = database.query(ShiftsEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Cannot query " + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
final int match = sUriMatcher.match(uri);
switch (match) {
case SHIFTS:
return insertShift(uri, contentValues);
default:
throw new IllegalArgumentException("Insertion is not supported for " + uri);
}
}
private Uri insertShift(Uri uri, ContentValues values) {
String description = values.getAsString(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION);
if (description == null) {
throw new IllegalArgumentException("Description required");
}
String date = values.getAsString(ShiftsEntry.COLUMN_SHIFT_DATE);
if (date == null) {
throw new IllegalArgumentException("Date required");
}
String timeIn = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TIME_IN);
if (timeIn == null) {
throw new IllegalArgumentException("Time In required");
}
String timeOut = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TIME_OUT);
if (timeOut == null) {
throw new IllegalArgumentException("Time Out required");
}
Float duration = values.getAsFloat(ShiftsEntry.COLUMN_SHIFT_DURATION);
if (duration < 0) {
throw new IllegalArgumentException("Duration cannot be negative");
}
String shiftType = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TYPE);
if (shiftType == null) {
throw new IllegalArgumentException("Shift type required");
}
Float shiftUnits = values.getAsFloat(ShiftsEntry.COLUMN_SHIFT_UNIT);
if (shiftUnits < 0) {
throw new IllegalArgumentException("Units cannot be negative");
}
Float payRate = values.getAsFloat(ShiftsEntry.COLUMN_SHIFT_PAYRATE);
if (payRate < 0) {
throw new IllegalArgumentException("Pay rate cannot be negative");
}
Float totalPay = values.getAsFloat(ShiftsEntry.COLUMN_SHIFT_TOTALPAY);
if (totalPay < 0) {
throw new IllegalArgumentException("Total Pay cannot be negative");
}
Integer breakMins = values.getAsInteger(ShiftsEntry.COLUMN_SHIFT_BREAK);
if (breakMins < 0) {
throw new IllegalArgumentException("Break cannot be negative");
}
SQLiteDatabase database = mDbHelper.getWritableDatabase();
long id = database.insert(ShiftsEntry.TABLE_NAME, null, values);
if (id == -1) {
Log.e(LOG_TAG, "row failed " + uri);
return null;
}
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(uri, id);
}
@Override
public int update(Uri uri, ContentValues contentValues, String selection,
String[] selectionArgs) {
final int match = sUriMatcher.match(uri);
switch (match) {
case SHIFTS:
return updateShift(uri, contentValues, selection, selectionArgs);
case SHIFT_ID:
selection = ShiftsEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
return updateShift(uri, contentValues, selection, selectionArgs);
default:
throw new IllegalArgumentException("Update is not supported for " + uri);
}
}
private int updateShift(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION)) {
String description = values.getAsString(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION);
if (description == null) {
throw new IllegalArgumentException("description required");
}
}
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_DATE)) {
String date = values.getAsString(ShiftsEntry.COLUMN_SHIFT_DATE);
if (date == null) {
throw new IllegalArgumentException("date required");
}
}
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_TIME_IN)) {
String timeIn = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TIME_IN);
if (timeIn == null) {
throw new IllegalArgumentException("time in required");
}
}
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_TIME_OUT)) {
String timeOut = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TIME_OUT);
if (timeOut == null) {
throw new IllegalArgumentException("time out required");
}
}
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_BREAK)) {
String breaks = values.getAsString(ShiftsEntry.COLUMN_SHIFT_BREAK);
if (breaks == null) {
throw new IllegalArgumentException("break required");
}
}
if (values.size() == 0) {
return 0;
}
SQLiteDatabase database = mDbHelper.getWritableDatabase();
int rowsUpdated = database.update(ShiftsEntry.TABLE_NAME, values, selection, selectionArgs);
if (rowsUpdated != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return rowsUpdated;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase database = mDbHelper.getWritableDatabase();
int rowsDeleted;
final int match = sUriMatcher.match(uri);
switch (match) {
case SHIFTS:
rowsDeleted = database.delete(ShiftsEntry.TABLE_NAME, selection, selectionArgs);
break;
case SHIFT_ID:
selection = ShiftsEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
rowsDeleted = database.delete(ShiftsEntry.TABLE_NAME, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Deletion is not supported for " + uri);
}
if (rowsDeleted != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return rowsDeleted;
}
@Override
public String getType(Uri uri) {
final int match = sUriMatcher.match(uri);
switch (match) {
case SHIFTS:
return ShiftsEntry.CONTENT_LIST_TYPE;
case SHIFT_ID:
return ShiftsEntry.CONTENT_ITEM_TYPE;
default:
throw new IllegalStateException("Unknown URI " + uri + " with match " + match);
}
}
}

View File

@@ -1,60 +0,0 @@
package com.appttude.h_mal.farmr.Data;
import android.content.ContentResolver;
import android.net.Uri;
import android.provider.BaseColumns;
/**
* Created by h_mal on 26/12/2017.
*/
public class ShiftsContract {
private ShiftsContract() {}
public static final String CONTENT_AUTHORITY = "com.appttude.h_mal.farmr";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final String PATH_SHIFTS = "shifts";
public static final class ShiftsEntry implements BaseColumns {
public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, PATH_SHIFTS);
public static final String CONTENT_LIST_TYPE =
ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_SHIFTS;
public static final String CONTENT_ITEM_TYPE =
ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_SHIFTS;
public final static String TABLE_NAME = "shifts";
public final static String TABLE_NAME_EXPORT = "shiftsexport";
public final static String _ID = BaseColumns._ID;
public final static String COLUMN_SHIFT_TYPE = "shifttype";
public final static String COLUMN_SHIFT_DESCRIPTION = "description";
public final static String COLUMN_SHIFT_DATE = "date";
public final static String COLUMN_SHIFT_TIME_IN = "timein";
public final static String COLUMN_SHIFT_TIME_OUT = "timeout";
public final static String COLUMN_SHIFT_BREAK = "break";
public final static String COLUMN_SHIFT_DURATION = "duration";
public final static String COLUMN_SHIFT_UNIT = "unit";
public final static String COLUMN_SHIFT_PAYRATE = "payrate";
public final static String COLUMN_SHIFT_TOTALPAY = "totalpay";
}
}

View File

@@ -1,67 +0,0 @@
package com.appttude.h_mal.farmr.Data;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.appttude.h_mal.farmr.Data.ShiftsContract.ShiftsEntry;
/**
* Created by h_mal on 26/12/2017.
*/
public class ShiftsDbHelper extends SQLiteOpenHelper {
public static final String LOG_TAG = ShiftsDbHelper.class.getSimpleName();
private static final String DATABASE_NAME = "shifts.db";
private static final int DATABASE_VERSION = 4;
private static String DEFAULT_TEXT = "Hourly";
public ShiftsDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String SQL_CREATE_PRODUCTS_TABLE = "CREATE TABLE " + ShiftsEntry.TABLE_NAME + " ("
+ ShiftsEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ ShiftsEntry.COLUMN_SHIFT_DESCRIPTION + " TEXT NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_DATE + " DATE NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_TIME_IN + " TIME NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_TIME_OUT + " TIME NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_BREAK + " INTEGER NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_DURATION + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_TYPE + " TEXT NOT NULL DEFAULT " + DEFAULT_TEXT + ", "
+ ShiftsEntry.COLUMN_SHIFT_UNIT + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_PAYRATE + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_TOTALPAY + " FLOAT NOT NULL DEFAULT 0)";
db.execSQL(SQL_CREATE_PRODUCTS_TABLE);
db.execSQL(SQL_CREATE_PRODUCTS_TABLE_2);
}
private static final String SQL_CREATE_PRODUCTS_TABLE_2 = "CREATE TABLE " + ShiftsEntry.TABLE_NAME_EXPORT + " ("
+ ShiftsEntry.COLUMN_SHIFT_DESCRIPTION + " TEXT NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_DATE + " DATE NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_TIME_IN + " TIME NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_TIME_OUT + " TIME NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_BREAK + " INTEGER NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_DURATION + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_TYPE + " TEXT NOT NULL DEFAULT " + DEFAULT_TEXT + ", "
+ ShiftsEntry.COLUMN_SHIFT_UNIT + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_PAYRATE + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_TOTALPAY + " FLOAT NOT NULL DEFAULT 0)";
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < newVersion) {
db.execSQL(SQL_CREATE_PRODUCTS_TABLE_2);
}
}
}

View File

@@ -1,198 +0,0 @@
package com.appttude.h_mal.farmr;
import android.app.DatePickerDialog;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import com.appttude.h_mal.farmr.Data.ShiftsContract;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import static com.appttude.h_mal.farmr.MainActivity.args;
import static com.appttude.h_mal.farmr.MainActivity.selection;
public class FilterDataFragment extends Fragment {
private String[] spinnerList = new String[]{"","Hourly","Piece Rate"};
private List<String> listArgs = new ArrayList<String>();
private EditText LocationET;
private EditText dateFromET;
private EditText dateToET;
private Spinner typeSpinner;
Calendar mcurrentDate;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_filter_data, container, false);
MainActivity.setActionBarTitle(getString(R.string.title_activity_filter_data));
mcurrentDate = Calendar.getInstance();
LocationET = (EditText) rootView.findViewById(R.id.filterLocationEditText);
dateFromET = (EditText) rootView.findViewById(R.id.fromdateInEditText);
dateToET = (EditText) rootView.findViewById(R.id.filterDateOutEditText);
typeSpinner = (Spinner) rootView.findViewById(R.id.TypeFilterEditText);
if(selection != null && selection.contains(" AND " + ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DESCRIPTION + " LIKE ?")){
String str = args[2];
str = str.replace("%", "");
LocationET.setText(str);
}
if(selection != null && !args[0].equals("2000-01-01")){
dateFromET.setText(args[0]);
}
if(selection != null && args != null && !args[1].equals(String.valueOf(mcurrentDate.get(Calendar.YEAR) + "-"
+ String.format("%02d", (mcurrentDate.get(Calendar.MONTH) + 1)) + "-"
+ String.format("%02d", mcurrentDate.get(Calendar.DAY_OF_MONTH))))){
dateToET.setText(args[1]);
}
dateFromET.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//To show current date in the datepicker
int mYear = mcurrentDate.get(Calendar.YEAR);
int mMonth = mcurrentDate.get(Calendar.MONTH);
int mDay = mcurrentDate.get(Calendar.DAY_OF_MONTH);
if(!dateFromET.getText().toString().equals("")) {
String dateString = dateFromET.getText().toString().trim();
mYear = Integer.parseInt(dateString.substring(0, 4));
mMonth = Integer.parseInt(dateString.substring(5, 7));
if (mMonth == 1){
mMonth = 0;
}else{
mMonth = mMonth -1;
}
mDay = Integer.parseInt(dateString.substring(8));
}
DatePickerDialog mDatePicker=new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker datepicker, int selectedyear, int selectedmonth, int selectedday) {
dateFromET.setText(
selectedyear + "-"
+ String.format("%02d", (selectedmonth + 1)) + "-"
+ String.format("%02d", selectedday)
);
}
},mYear, mMonth, mDay);
mDatePicker.setTitle("Select date");
mDatePicker.show(); }
});
dateToET.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//To show current date in the datepicker
Calendar mcurrentDate = Calendar.getInstance();
int mYear = mcurrentDate.get(Calendar.YEAR);
int mMonth = mcurrentDate.get(Calendar.MONTH);
int mDay = mcurrentDate.get(Calendar.DAY_OF_MONTH);
if(!dateToET.getText().toString().equals("")) {
String dateString = dateToET.getText().toString().trim();
mYear = Integer.parseInt(dateString.substring(0, 4));
mMonth = Integer.parseInt(dateString.substring(5, 7));
if (mMonth == 1){
mMonth = 0;
}else{
mMonth = mMonth -1;
}
mDay = Integer.parseInt(dateString.substring(8));
}
DatePickerDialog mDatePicker=new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker datepicker, int selectedyear, int selectedmonth, int selectedday) {
dateToET.setText(
selectedyear + "-"
+ String.format("%02d", (selectedmonth + 1)) + "-"
+ String.format("%02d", selectedday)
);
}
},mYear, mMonth, mDay);
mDatePicker.setTitle("Select date");
mDatePicker.show(); }
});
ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, spinnerList);
typeSpinner.setAdapter(adapter);
if(selection != null && selection.contains(" AND " + ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TYPE + " IS ?")) {
int spinnerPosition = adapter.getPosition(args[args.length-1]);
typeSpinner.setSelection(spinnerPosition);
}
Button submit = (Button) rootView.findViewById(R.id.submitFiltered);
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
BuildQuery();
args = listArgs.toArray(new String[0]);
FragmentMain.NEW_LOADER = 1;
MainActivity.fragmentManager.popBackStack();
}
});
return rootView;
}
private void BuildQuery() {
String dateQuery = ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DATE + " BETWEEN ? AND ?";
String descQuery = " AND " + ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DESCRIPTION + " LIKE ?";
String typeQuery = " AND " + ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TYPE + " IS ?";
String dateFrom = "2000-01-01";
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String dateTo = df.format(c);
if(!TextUtils.isEmpty(dateFromET.getText().toString().trim())){
dateFrom = dateFromET.getText().toString().trim();
}
if(!TextUtils.isEmpty(dateToET.getText().toString().trim())){
dateTo = dateToET.getText().toString().trim();
}
selection = dateQuery;
listArgs.add(dateFrom);
listArgs.add(dateTo);
if (!TextUtils.isEmpty(LocationET.getText().toString().trim())){
selection = selection + descQuery;
listArgs.add("%" + LocationET.getText().toString().trim() + "%");
}
if (!typeSpinner.getSelectedItem().toString().equals("")){
selection = selection + typeQuery;
listArgs.add(typeSpinner.getSelectedItem().toString());
}
}
}

View File

@@ -0,0 +1,144 @@
package com.appttude.h_mal.farmr
import android.app.DatePickerDialog
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.EditText
import android.widget.Spinner
import androidx.fragment.app.Fragment
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry
import java.text.MessageFormat
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
class FilterDataFragment : Fragment() {
private val spinnerList: Array<String> = arrayOf("", "Hourly", "Piece Rate")
private val listArgs: MutableList<String> = ArrayList()
private var LocationET: EditText? = null
private var dateFromET: EditText? = null
private var dateToET: EditText? = null
private var typeSpinner: Spinner? = null
lateinit var mcurrentDate: Calendar
private lateinit var activity: MainActivity
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
val activity = (activity)
// Inflate the layout for this fragment
val rootView: View = inflater.inflate(R.layout.fragment_filter_data, container, false)
activity.setActionBarTitle(getString(R.string.title_activity_filter_data))
mcurrentDate = Calendar.getInstance()
LocationET = rootView.findViewById<View>(R.id.filterLocationEditText) as EditText?
dateFromET = rootView.findViewById<View>(R.id.fromdateInEditText) as EditText?
dateToET = rootView.findViewById<View>(R.id.filterDateOutEditText) as EditText?
typeSpinner = rootView.findViewById<View>(R.id.TypeFilterEditText) as Spinner?
if (activity.selection != null && activity.selection!!.contains(" AND " + ShiftsEntry.COLUMN_SHIFT_DESCRIPTION + " LIKE ?")) {
var str: String = activity.args!!.get(2)
str = str.replace("%", "")
LocationET!!.setText(str)
}
if (activity.selection != null && !(activity.args!!.get(0) == "2000-01-01")) {
dateFromET!!.setText(activity.args!!.get(0))
}
if ((activity.selection != null) && (activity.args != null) && !(activity.args!![1] == (mcurrentDate.get(Calendar.YEAR).toString() + "-"
+ String.format("%02d", (mcurrentDate.get(Calendar.MONTH) + 1)) + "-"
+ String.format("%02d", mcurrentDate.get(Calendar.DAY_OF_MONTH))).toString())) {
dateToET!!.setText(activity.args!![1])
}
dateFromET!!.setOnClickListener { //To show current date in the datepicker
var mYear: Int = mcurrentDate.get(Calendar.YEAR)
var mMonth: Int = mcurrentDate.get(Calendar.MONTH)
var mDay: Int = mcurrentDate.get(Calendar.DAY_OF_MONTH)
if (!(dateFromET!!.text.toString() == "")) {
val dateString: String = dateFromET!!.text.toString().trim()
mYear = dateString.substring(0, 4).toInt()
mMonth = dateString.substring(5, 7).toInt()
if (mMonth == 1) {
mMonth = 0
} else {
mMonth = mMonth - 1
}
mDay = dateString.substring(8).toInt()
}
val mDatePicker = DatePickerDialog((context)!!, { datepicker, selectedyear, selectedmonth, selectedday ->
val input = MessageFormat.format("{0}-{1}-{2}", selectedyear, String.format("%02d", (selectedmonth + 1)), String.format("%02d", selectedday))
dateFromET!!.setText(input)
}, mYear, mMonth, mDay)
mDatePicker.setTitle("Select date")
mDatePicker.show()
}
dateToET!!.setOnClickListener { //To show current date in the datepicker
val mcurrentDate: Calendar = Calendar.getInstance()
var mYear: Int = mcurrentDate.get(Calendar.YEAR)
var mMonth: Int = mcurrentDate.get(Calendar.MONTH)
var mDay: Int = mcurrentDate.get(Calendar.DAY_OF_MONTH)
if (!(dateToET!!.text.toString() == "")) {
val dateString: String = dateToET!!.text.toString().trim({ it <= ' ' })
mYear = dateString.substring(0, 4).toInt()
mMonth = dateString.substring(5, 7).toInt()
if (mMonth == 1) {
mMonth = 0
} else {
mMonth -= 1
}
mDay = dateString.substring(8).toInt()
}
val mDatePicker = DatePickerDialog((context)!!, { datepicker, selectedyear, selectedmonth, selectedday ->
val input = MessageFormat.format("{0}-{1}-{2}", selectedyear, String.format("%02d", (selectedmonth + 1)), String.format("%02d", selectedday))
dateToET!!.setText(input)
}, mYear, mMonth, mDay)
mDatePicker.setTitle("Select date")
mDatePicker.show()
}
val adapter: ArrayAdapter<String> = ArrayAdapter((context)!!, android.R.layout.simple_spinner_dropdown_item, spinnerList)
typeSpinner!!.adapter = adapter
if (activity.selection != null && activity.selection!!.contains(" AND " + ShiftsEntry.COLUMN_SHIFT_TYPE + " IS ?")) {
val spinnerPosition: Int = adapter.getPosition(activity.args!!.get(activity.args!!.size - 1))
typeSpinner!!.setSelection(spinnerPosition)
}
val submit: Button = rootView.findViewById<View>(R.id.submitFiltered) as Button
submit.setOnClickListener {
BuildQuery()
activity.args = listArgs.toTypedArray<String>()
FragmentMain.NEW_LOADER = 1
activity.fragmentManager!!.popBackStack()
}
return rootView
}
private fun BuildQuery() {
val dateQuery: String = ShiftsEntry.COLUMN_SHIFT_DATE + " BETWEEN ? AND ?"
val descQuery: String = " AND " + ShiftsEntry.COLUMN_SHIFT_DESCRIPTION + " LIKE ?"
val typeQuery: String = " AND " + ShiftsEntry.COLUMN_SHIFT_TYPE + " IS ?"
var dateFrom = "2000-01-01"
val c: Date = Calendar.getInstance().time
val df = SimpleDateFormat("yyyy-MM-dd")
var dateTo: String = df.format(c)
if (!TextUtils.isEmpty(dateFromET!!.text.toString().trim())) {
dateFrom = dateFromET!!.text.toString().trim()
}
if (!TextUtils.isEmpty(dateToET!!.text.toString().trim())) {
dateTo = dateToET!!.text.toString().trim()
}
activity.selection = dateQuery
listArgs.add(dateFrom)
listArgs.add(dateTo)
if (!TextUtils.isEmpty(LocationET!!.text.toString().trim())) {
activity.selection = activity.selection + descQuery
listArgs.add("%" + LocationET!!.text.toString().trim() + "%")
}
if (!(typeSpinner!!.selectedItem.toString() == "")) {
activity.selection = activity.selection + typeQuery
listArgs.add(typeSpinner!!.selectedItem.toString())
}
}
}

View File

@@ -1,622 +0,0 @@
package com.appttude.h_mal.farmr;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import com.appttude.h_mal.farmr.Data.ShiftsContract;
import java.util.Calendar;
public class FragmentAddItem extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor> {
private static final int EXISTING_PRODUCT_LOADER = 0;
private Uri mCurrentProductUri;
public static RadioGroup mRadioGroup;
private RadioButton mRadioButtonOne;
private RadioButton mRadioButtonTwo;
private EditText mLocationEditText;
private EditText mDateEditText;
private TextView mDurationTextView;
private EditText mTimeInEditText;
private EditText mTimeOutEditText;
private EditText mBreakEditText;
private EditText mUnitEditText;
private EditText mPayRateEditText;
private TextView mTotalPayTextView;
private LinearLayout hourlyDataView;
private LinearLayout unitsHolder;
private LinearLayout durationHolder;
private LinearLayout wholeView;
private ScrollView scrollView;
private ProgressBar progressBarAI;
private int mBreaks;
private int mDay;
private int mMonth;
private int mYear;
private int mHoursIn;
private int mMinutesIn;
private int mHoursOut;
private int mMinutesOut;
private float mUnits;
private float mPayRate;
private String mType;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_add_item, container, false);
setHasOptionsMenu(true);
progressBarAI = (ProgressBar) rootView.findViewById(R.id.pd_ai);
scrollView = (ScrollView) rootView.findViewById(R.id.total_view);
mRadioGroup = (RadioGroup) rootView.findViewById(R.id.rg);
mRadioButtonOne = (RadioButton) rootView.findViewById(R.id.hourly);
mRadioButtonTwo = (RadioButton) rootView.findViewById(R.id.piecerate);
mLocationEditText = (EditText) rootView.findViewById(R.id.locationEditText);
mDateEditText = (EditText) rootView.findViewById(R.id.dateEditText);
mTimeInEditText = (EditText) rootView.findViewById(R.id.timeInEditText);
mBreakEditText = (EditText) rootView.findViewById(R.id.breakEditText);
mTimeOutEditText = (EditText) rootView.findViewById(R.id.timeOutEditText);
mDurationTextView = (TextView) rootView.findViewById(R.id.ShiftDuration);
mUnitEditText = (EditText) rootView.findViewById(R.id.unitET);
mPayRateEditText = (EditText) rootView.findViewById(R.id.payrateET);
mTotalPayTextView = (TextView) rootView.findViewById(R.id.totalpayval);
hourlyDataView = (LinearLayout) rootView.findViewById(R.id.hourly_data_holder);
unitsHolder = (LinearLayout) rootView.findViewById(R.id.units_holder);
durationHolder = (LinearLayout) rootView.findViewById(R.id.duration_holder);
wholeView = (LinearLayout) rootView.findViewById(R.id.whole_view);
mPayRate = 0.0f;
mUnits = 0.0f;
final Bundle b = getArguments();
if(b != null) {
mCurrentProductUri = Uri.parse(b.getString("uri"));
}
if (mCurrentProductUri == null) {
MainActivity.setActionBarTitle(getString(R.string.add_item_title));
wholeView.setVisibility(View.GONE);
} else {
MainActivity.setActionBarTitle(getString(R.string.edit_item_title));
getLoaderManager().initLoader(EXISTING_PRODUCT_LOADER, null, this);
}
mBreakEditText.setHint("insert break in minutes");
mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
if (mRadioButtonOne.isChecked()){
mType = mRadioButtonOne.getText().toString();
wholeView.setVisibility(View.VISIBLE);
unitsHolder.setVisibility(View.GONE);
hourlyDataView.setVisibility(View.VISIBLE);
durationHolder.setVisibility(View.VISIBLE);
}else if(mRadioButtonTwo.isChecked()){
mType = mRadioButtonTwo.getText().toString();
wholeView.setVisibility(View.VISIBLE);
unitsHolder.setVisibility(View.VISIBLE);
hourlyDataView.setVisibility(View.GONE);
durationHolder.setVisibility(View.GONE);
}
}
});
mDateEditText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//To show current date in the datepicker
if(TextUtils.isEmpty(mDateEditText.getText().toString().trim())) {
Calendar mcurrentDate = Calendar.getInstance();
mYear = mcurrentDate.get(Calendar.YEAR);
mMonth = mcurrentDate.get(Calendar.MONTH);
mDay = mcurrentDate.get(Calendar.DAY_OF_MONTH);
}else{
String dateString = mDateEditText.getText().toString().trim();
mYear = Integer.parseInt(dateString.substring(0, 4));
mMonth = Integer.parseInt(dateString.substring(5, 7));
if (mMonth == 1){
mMonth = 0;
}else{
mMonth = mMonth -1;
}
mDay = Integer.parseInt(dateString.substring(8));
}
DatePickerDialog mDatePicker=new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker datepicker, int selectedyear, int selectedmonth, int selectedday) {
mDateEditText.setText(
selectedyear + "-"
+ String.format("%02d", (selectedmonth = selectedmonth + 1)) +"-"
+ String.format("%02d", selectedday)
);
setDate(selectedyear, selectedmonth, selectedday);
}
},mYear, mMonth, mDay);
mDatePicker.setTitle("Select date");
mDatePicker.show(); }
});
mTimeInEditText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mTimeInEditText.getText().toString().equals("")) {
Calendar mcurrentTime = Calendar.getInstance();
mHoursIn = mcurrentTime.get(Calendar.HOUR_OF_DAY);
mMinutesIn = mcurrentTime.get(Calendar.MINUTE);
} else {
mHoursIn = Integer.parseInt((mTimeInEditText.getText().toString().subSequence(0,2)).toString());
mMinutesIn = Integer.parseInt((mTimeInEditText.getText().toString().subSequence(3,5)).toString());
}
TimePickerDialog mTimePicker;
mTimePicker = new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
String ddTime = String.format("%02d", selectedHour) + ":" + String.format("%02d", selectedMinute);
setTime(selectedMinute, selectedHour);
mTimeInEditText.setText(ddTime);
}
}, mHoursIn, mMinutesIn, true);//Yes 24 hour time
mTimePicker.setTitle("Select Time");
mTimePicker.show();
}
});
mTimeOutEditText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mTimeOutEditText.getText().toString().equals("")) {
Calendar mcurrentTime = Calendar.getInstance();
mHoursOut = mcurrentTime.get(Calendar.HOUR_OF_DAY);
mMinutesOut = mcurrentTime.get(Calendar.MINUTE);
}else {
mHoursOut = Integer.parseInt((mTimeOutEditText.getText().toString().subSequence(0,2)).toString());
mMinutesOut = Integer.parseInt((mTimeOutEditText.getText().toString().subSequence(3,5)).toString());
}
TimePickerDialog mTimePicker;
mTimePicker = new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
String ddTime = String.format("%02d", selectedHour) + ":" + String.format("%02d", selectedMinute);
setTime2(selectedMinute,selectedHour);
mTimeOutEditText.setText(ddTime);
}
}, mHoursOut, mMinutesOut, true);//Yes 24 hour time
mTimePicker.setTitle("Select Time");
mTimePicker.show();
}
});
mTimeInEditText.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int aft )
{
}
@Override
public void afterTextChanged(Editable s)
{
setDuration();
calculateTotalPay();
}
});
mTimeOutEditText.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int aft )
{
}
@Override
public void afterTextChanged(Editable s)
{
setDuration();
calculateTotalPay();
}
});
mBreakEditText.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int aft )
{
}
@Override
public void afterTextChanged(Editable s)
{
setDuration();
calculateTotalPay();
}
});
mUnitEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
// if(mRadioButtonTwo.isChecked()) {
// mUnits = 0.0f;
// if (!mUnitEditText.getText().toString().equals("")){
// mUnits = Float.parseFloat(mUnitEditText.getText().toString());
// }
// mPayRate = 0.0f;
// if (!mPayRateEditText.getText().toString().equals("")){
// mPayRate = Float.parseFloat(mPayRateEditText.getText().toString());
// }
// Float total = mPayRate * mUnits;
// mTotalPayTextView.setText(String.valueOf(total));
// }
calculateTotalPay();
}
});
mPayRateEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
calculateTotalPay();
}
});
Button SubmitProduct = (Button) rootView.findViewById(R.id.submit);
SubmitProduct.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
saveProduct();
}
});
return rootView;
}
private void calculateTotalPay(){
Float total = 0.0f;
mPayRate = 0.0f;
if(mRadioButtonTwo.isChecked()) {
mUnits = 0.0f;
if (!mUnitEditText.getText().toString().equals("")) {
mUnits = Float.parseFloat(mUnitEditText.getText().toString());
}
if (!mPayRateEditText.getText().toString().equals("")) {
mPayRate = Float.parseFloat(mPayRateEditText.getText().toString());
}
total = mPayRate * mUnits;
mTotalPayTextView.setText(String.valueOf(total));
} else if(mRadioButtonOne.isChecked()){
if (!mPayRateEditText.getText().toString().equals("")){
mPayRate = Float.parseFloat(mPayRateEditText.getText().toString());
total = mPayRate * calculateDuration(mHoursIn,mMinutesIn,mHoursOut,mMinutesOut,mBreaks);
}
}
mTotalPayTextView.setText(String.format("%.2f",total));
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
}
private void saveProduct() {
String typeString = mType;
String descriptionString = mLocationEditText.getText().toString().trim();
if (TextUtils.isEmpty(descriptionString)) {
Toast.makeText(getContext(), "please insert Location", Toast.LENGTH_SHORT).show();
return;
}
String dateString = mDateEditText.getText().toString().trim();
if (TextUtils.isEmpty(dateString)) {
Toast.makeText(getContext(), "please insert Date", Toast.LENGTH_SHORT).show();
return;
}
String timeInString = "";
String timeOutString = "";
int breaks = 0;
float units = 0;
float duration = 0;
float payRate = 0;
String payRateString = mPayRateEditText.getText().toString().trim();
if (!TextUtils.isEmpty(payRateString)) {
payRate = Float.parseFloat(payRateString);
}
float totalPay = 0;
if (typeString.equals("Hourly")) {
timeInString = mTimeInEditText.getText().toString().trim();
if (TextUtils.isEmpty(timeInString)) {
Toast.makeText(getContext(), "please insert Time in", Toast.LENGTH_SHORT).show();
return;
}
timeOutString = mTimeOutEditText.getText().toString().trim();
if (TextUtils.isEmpty(timeOutString)) {
Toast.makeText(getContext(), "please insert Time out", Toast.LENGTH_SHORT).show();
return;
}
String breakMins = mBreakEditText.getText().toString().trim();
if (!TextUtils.isEmpty(breakMins)) {
breaks = Integer.parseInt(breakMins);
if(((float)breaks / 60) > calculateDurationWithoutBreak(mHoursIn, mMinutesIn, mHoursOut, mMinutesOut)){
Toast.makeText(getContext(), "Break larger than duration", Toast.LENGTH_SHORT).show();
return;
}
}
duration = calculateDuration(mHoursIn, mMinutesIn, mHoursOut, mMinutesOut, breaks);
totalPay = duration * payRate;
}else if(typeString.equals("Piece Rate")){
String unitsString = mUnitEditText.getText().toString().trim();
if (TextUtils.isEmpty(unitsString) || Float.parseFloat(unitsString) <= 0) {
Toast.makeText(getContext(), "Insert Units", Toast.LENGTH_SHORT).show();
return;
}else{
units = Float.parseFloat(unitsString);
}
duration = 0;
totalPay = units * payRate;
}
ContentValues values = new ContentValues();
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TYPE, typeString);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DESCRIPTION, descriptionString);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DATE, dateString);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_IN, timeInString);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_OUT, timeOutString);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DURATION, duration);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_BREAK, breaks);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_UNIT, units);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_PAYRATE, payRate);
values.put(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TOTALPAY, totalPay);
if (mCurrentProductUri == null) {
Uri newUri = getActivity().getContentResolver().insert(ShiftsContract.ShiftsEntry.CONTENT_URI, values);
if (newUri == null) {
Toast.makeText(getContext(), getString(R.string.insert_item_failed),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), getString(R.string.insert_item_successful),
Toast.LENGTH_SHORT).show();
}
} else {
int rowsAffected = getActivity().getContentResolver().update(mCurrentProductUri, values, null, null);
if (rowsAffected == 0) {
Toast.makeText(getContext(), getString(R.string.update_item_failed),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), getString(R.string.update_item_successful),
Toast.LENGTH_SHORT).show();
}
}
(MainActivity.fragmentManager).popBackStack("main",0);
}
private void setDuration (){
Calendar mcurrentTime = Calendar.getInstance();
mBreaks = 0;
if (!mBreakEditText.getText().toString().equals("")){
mBreaks = Integer.parseInt(mBreakEditText.getText().toString());
}
if (mTimeOutEditText.getText().toString().equals("")) {
mHoursOut = mcurrentTime.get(Calendar.HOUR_OF_DAY);
mMinutesOut = mcurrentTime.get(Calendar.MINUTE);
}else {
mHoursOut = Integer.parseInt((mTimeOutEditText.getText().toString().subSequence(0,2)).toString());
mMinutesOut = Integer.parseInt((mTimeOutEditText.getText().toString().subSequence(3,5)).toString());
}
if (mTimeInEditText.getText().toString().equals("")) {
mHoursIn = mcurrentTime.get(Calendar.HOUR_OF_DAY);
mMinutesIn = mcurrentTime.get(Calendar.MINUTE);
} else {
mHoursIn = Integer.parseInt((mTimeInEditText.getText().toString().subSequence(0,2)).toString());
mMinutesIn = Integer.parseInt((mTimeInEditText.getText().toString().subSequence(3,5)).toString());
}
mDurationTextView.setText(calculateDuration(mHoursIn,mMinutesIn,mHoursOut,mMinutesOut,mBreaks) + " hours");
}
private void setDate (int year, int month, int day){
mYear = year;
mMonth = month;
mDay = day;
}
private void setTime (int minutes, int hours){
mMinutesIn = minutes;
mHoursIn = hours;
}
private void setTime2 (int minutes, int hours){
mMinutesOut = minutes;
mHoursOut = hours;
}
private float calculateDuration (int hoursIn, int minutesIn, int hoursOut, int minutesOut, int breaks){
float duration;
if (hoursOut > hoursIn){
duration = (((float)hoursOut + ((float)minutesOut/60)) - ((float) hoursIn + ((float)minutesIn/60))) - ((float)breaks / 60);
}else{
duration = ((((float)hoursOut + ((float)minutesOut/60)) - ((float)hoursIn + ((float)minutesIn/60))) - ((float)breaks / 60) + 24);
}
String s = String.format("%.2f",duration);
return Float.parseFloat(s);
}
private float calculateDurationWithoutBreak (int hoursIn, int minutesIn, int hoursOut, int minutesOut){
float duration;
if (hoursOut > hoursIn){
duration = (((float)hoursOut + ((float)minutesOut/60)) - ((float) hoursIn + ((float)minutesIn/60)));
}else{
duration = ((((float)hoursOut + ((float)minutesOut/60)) - ((float)hoursIn + ((float)minutesIn/60))) + 24);
}
String s = String.format("%.2f",duration);
return Float.parseFloat(s);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
progressBarAI.setVisibility(View.VISIBLE);
scrollView.setVisibility(View.GONE);
String[] projection = {
ShiftsContract.ShiftsEntry._ID,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TOTALPAY,};
return new android.support.v4.content.CursorLoader(getContext(),mCurrentProductUri,
projection,null,null,null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
progressBarAI.setVisibility(View.GONE);
scrollView.setVisibility(View.VISIBLE);
if (cursor == null || cursor.getCount() < 1) {
return;
}
if (cursor.moveToFirst()) {
int descriptionColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DESCRIPTION);
int dateColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DATE);
int timeInColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_IN);
int timeOutColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_OUT);
int breakColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_BREAK);
int durationColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DURATION);
int typeColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TYPE);
int unitColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_UNIT);
int payrateColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_PAYRATE);
int totalPayColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TOTALPAY);
String type = cursor.getString(typeColumnIndex);
String description = cursor.getString(descriptionColumnIndex);
String date = cursor.getString(dateColumnIndex);
String timeIn = cursor.getString(timeInColumnIndex);
String timeOut = cursor.getString(timeOutColumnIndex);
int breaks = cursor.getInt(breakColumnIndex);
float duration = cursor.getFloat(durationColumnIndex);
float unit = cursor.getFloat(unitColumnIndex);
float payrate = cursor.getFloat(payrateColumnIndex);
float totalPay = cursor.getFloat(totalPayColumnIndex);
mLocationEditText.setText(description);
mDateEditText.setText(date);
if (type.equals("Hourly") || type.equals("hourly")) {
mRadioButtonOne.setChecked(true);
mRadioButtonTwo.setChecked(false);
mTimeInEditText.setText(timeIn);
mTimeOutEditText.setText(timeOut);
mBreakEditText.setText(Integer.toString(breaks));
mDurationTextView.setText(String.format("%.2f", duration) + " Hours");
} else if (type.equals("Piece Rate")) {
mRadioButtonOne.setChecked(false);
mRadioButtonTwo.setChecked(true);
mUnitEditText.setText(Float.toString(unit));
}
mPayRateEditText.setText(String.format("%.2f", payrate));
mTotalPayTextView.setText(String.format("%.2f", totalPay));
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
}

View File

@@ -0,0 +1,507 @@
package com.appttude.h_mal.farmr
import android.app.DatePickerDialog
import android.app.DatePickerDialog.OnDateSetListener
import android.app.TimePickerDialog
import android.app.TimePickerDialog.OnTimeSetListener
import android.content.ContentValues
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.DatePicker
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.ScrollView
import android.widget.TextView
import android.widget.TimePicker
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.loader.app.LoaderManager
import androidx.loader.content.CursorLoader
import androidx.loader.content.Loader
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry
import java.util.Calendar
class FragmentAddItem : Fragment(), LoaderManager.LoaderCallbacks<Cursor?> {
lateinit var activity: MainActivity
private var mCurrentProductUri: Uri? = null
private var mRadioButtonOne: RadioButton? = null
private var mRadioButtonTwo: RadioButton? = null
private var mLocationEditText: EditText? = null
private var mDateEditText: EditText? = null
private var mDurationTextView: TextView? = null
private var mTimeInEditText: EditText? = null
private var mTimeOutEditText: EditText? = null
private var mBreakEditText: EditText? = null
private var mUnitEditText: EditText? = null
private var mPayRateEditText: EditText? = null
private var mTotalPayTextView: TextView? = null
private var hourlyDataView: LinearLayout? = null
private var unitsHolder: LinearLayout? = null
private var durationHolder: LinearLayout? = null
private var wholeView: LinearLayout? = null
private var scrollView: ScrollView? = null
private var progressBarAI: ProgressBar? = null
private var mBreaks = 0
private var mDay = 0
private var mMonth = 0
private var mYear = 0
private var mHoursIn = 0
private var mMinutesIn = 0
private var mHoursOut = 0
private var mMinutesOut = 0
private var mUnits = 0f
private var mPayRate = 0f
private var mType: String? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val rootView = inflater.inflate(R.layout.fragment_add_item, container, false)
setHasOptionsMenu(true)
activity = (requireActivity() as MainActivity)
progressBarAI = rootView.findViewById<View>(R.id.pd_ai) as ProgressBar
scrollView = rootView.findViewById<View>(R.id.total_view) as ScrollView
mRadioGroup = rootView.findViewById<View>(R.id.rg) as RadioGroup
mRadioButtonOne = rootView.findViewById<View>(R.id.hourly) as RadioButton
mRadioButtonTwo = rootView.findViewById<View>(R.id.piecerate) as RadioButton
mLocationEditText = rootView.findViewById<View>(R.id.locationEditText) as EditText
mDateEditText = rootView.findViewById<View>(R.id.dateEditText) as EditText
mTimeInEditText = rootView.findViewById<View>(R.id.timeInEditText) as EditText
mBreakEditText = rootView.findViewById<View>(R.id.breakEditText) as EditText
mTimeOutEditText = rootView.findViewById<View>(R.id.timeOutEditText) as EditText
mDurationTextView = rootView.findViewById<View>(R.id.ShiftDuration) as TextView
mUnitEditText = rootView.findViewById<View>(R.id.unitET) as EditText
mPayRateEditText = rootView.findViewById<View>(R.id.payrateET) as EditText
mTotalPayTextView = rootView.findViewById<View>(R.id.totalpayval) as TextView
hourlyDataView = rootView.findViewById<View>(R.id.hourly_data_holder) as LinearLayout
unitsHolder = rootView.findViewById<View>(R.id.units_holder) as LinearLayout
durationHolder = rootView.findViewById<View>(R.id.duration_holder) as LinearLayout
wholeView = rootView.findViewById<View>(R.id.whole_view) as LinearLayout
mPayRate = 0.0f
mUnits = 0.0f
val b = arguments
if (b != null) {
mCurrentProductUri = Uri.parse(b.getString("uri"))
}
if (mCurrentProductUri == null) {
activity.setActionBarTitle(getString(R.string.add_item_title))
wholeView!!.visibility = View.GONE
} else {
activity.setActionBarTitle(getString(R.string.edit_item_title))
loaderManager.initLoader(EXISTING_PRODUCT_LOADER, null, this)
}
mBreakEditText!!.hint = "insert break in minutes"
mRadioGroup!!.setOnCheckedChangeListener(RadioGroup.OnCheckedChangeListener { radioGroup, i ->
if (mRadioButtonOne!!.isChecked) {
mType = mRadioButtonOne!!.text.toString()
wholeView!!.visibility = View.VISIBLE
unitsHolder!!.visibility = View.GONE
hourlyDataView!!.visibility = View.VISIBLE
durationHolder!!.visibility = View.VISIBLE
} else if (mRadioButtonTwo!!.isChecked) {
mType = mRadioButtonTwo!!.text.toString()
wholeView!!.visibility = View.VISIBLE
unitsHolder!!.visibility = View.VISIBLE
hourlyDataView!!.visibility = View.GONE
durationHolder!!.visibility = View.GONE
}
})
mDateEditText!!.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
//To show current date in the datepicker
if (TextUtils.isEmpty(mDateEditText!!.text.toString().trim { it <= ' ' })) {
val mcurrentDate = Calendar.getInstance()
mYear = mcurrentDate[Calendar.YEAR]
mMonth = mcurrentDate[Calendar.MONTH]
mDay = mcurrentDate[Calendar.DAY_OF_MONTH]
} else {
val dateString = mDateEditText!!.text.toString().trim { it <= ' ' }
mYear = dateString.substring(0, 4).toInt()
mMonth = dateString.substring(5, 7).toInt()
if (mMonth == 1) {
mMonth = 0
} else {
mMonth = mMonth - 1
}
mDay = dateString.substring(8).toInt()
}
val mDatePicker = DatePickerDialog((context)!!, object : OnDateSetListener {
override fun onDateSet(datepicker: DatePicker, selectedyear: Int, selectedmonth: Int, selectedday: Int) {
var selectedmonth = selectedmonth
mDateEditText!!.setText(
(selectedyear.toString() + "-"
+ String.format("%02d", (selectedmonth + 1.also { selectedmonth = it })) + "-"
+ String.format("%02d", selectedday))
)
setDate(selectedyear, selectedmonth, selectedday)
}
}, mYear, mMonth, mDay)
mDatePicker.setTitle("Select date")
mDatePicker.show()
}
})
mTimeInEditText!!.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
if ((mTimeInEditText!!.text.toString() == "")) {
val mcurrentTime = Calendar.getInstance()
mHoursIn = mcurrentTime[Calendar.HOUR_OF_DAY]
mMinutesIn = mcurrentTime[Calendar.MINUTE]
} else {
mHoursIn = (mTimeInEditText!!.text.toString().subSequence(0, 2)).toString().toInt()
mMinutesIn = (mTimeInEditText!!.text.toString().subSequence(3, 5)).toString().toInt()
}
val mTimePicker: TimePickerDialog
mTimePicker = TimePickerDialog(context, object : OnTimeSetListener {
override fun onTimeSet(timePicker: TimePicker, selectedHour: Int, selectedMinute: Int) {
val ddTime = String.format("%02d", selectedHour) + ":" + String.format("%02d", selectedMinute)
setTime(selectedMinute, selectedHour)
mTimeInEditText!!.setText(ddTime)
}
}, mHoursIn, mMinutesIn, true) //Yes 24 hour time
mTimePicker.setTitle("Select Time")
mTimePicker.show()
}
})
mTimeOutEditText!!.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
if ((mTimeOutEditText!!.text.toString() == "")) {
val mcurrentTime = Calendar.getInstance()
mHoursOut = mcurrentTime[Calendar.HOUR_OF_DAY]
mMinutesOut = mcurrentTime[Calendar.MINUTE]
} else {
mHoursOut = (mTimeOutEditText!!.text.toString().subSequence(0, 2)).toString().toInt()
mMinutesOut = (mTimeOutEditText!!.text.toString().subSequence(3, 5)).toString().toInt()
}
val mTimePicker: TimePickerDialog
mTimePicker = TimePickerDialog(context, object : OnTimeSetListener {
override fun onTimeSet(timePicker: TimePicker, selectedHour: Int, selectedMinute: Int) {
val ddTime = String.format("%02d", selectedHour) + ":" + String.format("%02d", selectedMinute)
setTime2(selectedMinute, selectedHour)
mTimeOutEditText!!.setText(ddTime)
}
}, mHoursOut, mMinutesOut, true) //Yes 24 hour time
mTimePicker.setTitle("Select Time")
mTimePicker.show()
}
})
mTimeInEditText!!.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, aft: Int) {}
override fun afterTextChanged(s: Editable) {
setDuration()
calculateTotalPay()
}
})
mTimeOutEditText!!.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, aft: Int) {}
override fun afterTextChanged(s: Editable) {
setDuration()
calculateTotalPay()
}
})
mBreakEditText!!.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, aft: Int) {}
override fun afterTextChanged(s: Editable) {
setDuration()
calculateTotalPay()
}
})
mUnitEditText!!.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun afterTextChanged(editable: Editable) {
// if(mRadioButtonTwo.isChecked()) {
// mUnits = 0.0f;
// if (!mUnitEditText.getText().toString().equals("")){
// mUnits = Float.parseFloat(mUnitEditText.getText().toString());
// }
// mPayRate = 0.0f;
// if (!mPayRateEditText.getText().toString().equals("")){
// mPayRate = Float.parseFloat(mPayRateEditText.getText().toString());
// }
// Float total = mPayRate * mUnits;
// mTotalPayTextView.setText(String.valueOf(total));
// }
calculateTotalPay()
}
})
mPayRateEditText!!.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun afterTextChanged(editable: Editable) {
calculateTotalPay()
}
})
val SubmitProduct = rootView.findViewById<View>(R.id.submit) as Button
SubmitProduct.setOnClickListener(object : View.OnClickListener {
override fun onClick(view: View) {
saveProduct()
}
})
return rootView
}
private fun calculateTotalPay() {
var total = 0.0f
mPayRate = 0.0f
if (mRadioButtonTwo!!.isChecked) {
mUnits = 0.0f
if (mUnitEditText!!.text.toString() != "") {
mUnits = mUnitEditText!!.text.toString().toFloat()
}
if (mPayRateEditText!!.text.toString() != "") {
mPayRate = mPayRateEditText!!.text.toString().toFloat()
}
total = mPayRate * mUnits
mTotalPayTextView!!.text = total.toString()
} else if (mRadioButtonOne!!.isChecked) {
if (mPayRateEditText!!.text.toString() != "") {
mPayRate = mPayRateEditText!!.text.toString().toFloat()
total = mPayRate * calculateDuration(mHoursIn, mMinutesIn, mHoursOut, mMinutesOut, mBreaks)
}
}
mTotalPayTextView!!.text = String.format("%.2f", total)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
menu.clear()
}
private fun saveProduct() {
val typeString = mType
val descriptionString = mLocationEditText!!.text.toString().trim { it <= ' ' }
if (TextUtils.isEmpty(descriptionString)) {
Toast.makeText(context, "please insert Location", Toast.LENGTH_SHORT).show()
return
}
val dateString = mDateEditText!!.text.toString().trim { it <= ' ' }
if (TextUtils.isEmpty(dateString)) {
Toast.makeText(context, "please insert Date", Toast.LENGTH_SHORT).show()
return
}
var timeInString: String = ""
var timeOutString: String = ""
var breaks = 0
var units = 0f
var duration = 0f
var payRate = 0f
val payRateString = mPayRateEditText!!.text.toString().trim { it <= ' ' }
if (!TextUtils.isEmpty(payRateString)) {
payRate = payRateString.toFloat()
}
var totalPay = 0f
if ((typeString == "Hourly")) {
timeInString = mTimeInEditText!!.text.toString().trim { it <= ' ' }
if (TextUtils.isEmpty(timeInString)) {
Toast.makeText(context, "please insert Time in", Toast.LENGTH_SHORT).show()
return
}
timeOutString = mTimeOutEditText!!.text.toString().trim { it <= ' ' }
if (TextUtils.isEmpty(timeOutString)) {
Toast.makeText(context, "please insert Time out", Toast.LENGTH_SHORT).show()
return
}
val breakMins = mBreakEditText!!.text.toString().trim { it <= ' ' }
if (!TextUtils.isEmpty(breakMins)) {
breaks = breakMins.toInt()
if ((breaks.toFloat() / 60) > calculateDurationWithoutBreak(mHoursIn, mMinutesIn, mHoursOut, mMinutesOut)) {
Toast.makeText(context, "Break larger than duration", Toast.LENGTH_SHORT).show()
return
}
}
duration = calculateDuration(mHoursIn, mMinutesIn, mHoursOut, mMinutesOut, breaks)
totalPay = duration * payRate
} else if ((typeString == "Piece Rate")) {
val unitsString = mUnitEditText!!.text.toString().trim { it <= ' ' }
if (TextUtils.isEmpty(unitsString) || unitsString.toFloat() <= 0) {
Toast.makeText(context, "Insert Units", Toast.LENGTH_SHORT).show()
return
} else {
units = unitsString.toFloat()
}
duration = 0f
totalPay = units * payRate
}
val values = ContentValues()
values.put(ShiftsEntry.COLUMN_SHIFT_TYPE, typeString)
values.put(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION, descriptionString)
values.put(ShiftsEntry.COLUMN_SHIFT_DATE, dateString)
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_IN, timeInString)
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_OUT, timeOutString)
values.put(ShiftsEntry.COLUMN_SHIFT_DURATION, duration)
values.put(ShiftsEntry.COLUMN_SHIFT_BREAK, breaks)
values.put(ShiftsEntry.COLUMN_SHIFT_UNIT, units)
values.put(ShiftsEntry.COLUMN_SHIFT_PAYRATE, payRate)
values.put(ShiftsEntry.COLUMN_SHIFT_TOTALPAY, totalPay)
if (mCurrentProductUri == null) {
val newUri = activity.contentResolver.insert(ShiftsEntry.CONTENT_URI, values)
if (newUri == null) {
Toast.makeText(context, getString(R.string.insert_item_failed),
Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, getString(R.string.insert_item_successful),
Toast.LENGTH_SHORT).show()
}
} else {
val rowsAffected = activity.contentResolver.update(mCurrentProductUri!!, values, null, null)
if (rowsAffected == 0) {
Toast.makeText(context, getString(R.string.update_item_failed),
Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, getString(R.string.update_item_successful),
Toast.LENGTH_SHORT).show()
}
}
(activity.fragmentManager)!!.popBackStack("main", 0)
}
private fun setDuration() {
val mcurrentTime = Calendar.getInstance()
mBreaks = 0
if (mBreakEditText!!.text.toString() != "") {
mBreaks = mBreakEditText!!.text.toString().toInt()
}
if ((mTimeOutEditText!!.text.toString() == "")) {
mHoursOut = mcurrentTime[Calendar.HOUR_OF_DAY]
mMinutesOut = mcurrentTime[Calendar.MINUTE]
} else {
mHoursOut = (mTimeOutEditText!!.text.toString().subSequence(0, 2)).toString().toInt()
mMinutesOut = (mTimeOutEditText!!.text.toString().subSequence(3, 5)).toString().toInt()
}
if ((mTimeInEditText!!.text.toString() == "")) {
mHoursIn = mcurrentTime[Calendar.HOUR_OF_DAY]
mMinutesIn = mcurrentTime[Calendar.MINUTE]
} else {
mHoursIn = (mTimeInEditText!!.text.toString().subSequence(0, 2)).toString().toInt()
mMinutesIn = (mTimeInEditText!!.text.toString().subSequence(3, 5)).toString().toInt()
}
mDurationTextView!!.text = calculateDuration(mHoursIn, mMinutesIn, mHoursOut, mMinutesOut, mBreaks).toString() + " hours"
}
private fun setDate(year: Int, month: Int, day: Int) {
mYear = year
mMonth = month
mDay = day
}
private fun setTime(minutes: Int, hours: Int) {
mMinutesIn = minutes
mHoursIn = hours
}
private fun setTime2(minutes: Int, hours: Int) {
mMinutesOut = minutes
mHoursOut = hours
}
private fun calculateDuration(hoursIn: Int, minutesIn: Int, hoursOut: Int, minutesOut: Int, breaks: Int): Float {
val duration: Float
if (hoursOut > hoursIn) {
duration = ((hoursOut.toFloat() + (minutesOut.toFloat() / 60)) - (hoursIn.toFloat() + (minutesIn.toFloat() / 60))) - (breaks.toFloat() / 60)
} else {
duration = (((hoursOut.toFloat() + (minutesOut.toFloat() / 60)) - (hoursIn.toFloat() + (minutesIn.toFloat() / 60))) - (breaks.toFloat() / 60) + 24)
}
val s = String.format("%.2f", duration)
return s.toFloat()
}
private fun calculateDurationWithoutBreak(hoursIn: Int, minutesIn: Int, hoursOut: Int, minutesOut: Int): Float {
val duration: Float
if (hoursOut > hoursIn) {
duration = ((hoursOut.toFloat() + (minutesOut.toFloat() / 60)) - (hoursIn.toFloat() + (minutesIn.toFloat() / 60)))
} else {
duration = (((hoursOut.toFloat() + (minutesOut.toFloat() / 60)) - (hoursIn.toFloat() + (minutesIn.toFloat() / 60))) + 24)
}
val s = String.format("%.2f", duration)
return s.toFloat()
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor?> {
progressBarAI!!.visibility = View.VISIBLE
scrollView!!.visibility = View.GONE
val projection = arrayOf<String?>(
ShiftsEntry._ID,
ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsEntry.COLUMN_SHIFT_TOTALPAY)
return CursorLoader((context)!!, (mCurrentProductUri)!!,
projection, null, null, null)
}
override fun onLoaderReset(loader: Loader<Cursor?>) {}
override fun onLoadFinished(loader: Loader<Cursor?>, cursor: Cursor?) {
progressBarAI!!.visibility = View.GONE
scrollView!!.visibility = View.VISIBLE
if (cursor == null || cursor.count < 1) {
return
}
if (cursor.moveToFirst()) {
val descriptionColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION)
val dateColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_DATE)
val timeInColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_TIME_IN)
val timeOutColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_TIME_OUT)
val breakColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_BREAK)
val durationColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_DURATION)
val typeColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_TYPE)
val unitColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_UNIT)
val payrateColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_PAYRATE)
val totalPayColumnIndex = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_TOTALPAY)
val type = cursor.getString(typeColumnIndex)
val description = cursor.getString(descriptionColumnIndex)
val date = cursor.getString(dateColumnIndex)
val timeIn = cursor.getString(timeInColumnIndex)
val timeOut = cursor.getString(timeOutColumnIndex)
val breaks = cursor.getInt(breakColumnIndex)
val duration = cursor.getFloat(durationColumnIndex)
val unit = cursor.getFloat(unitColumnIndex)
val payrate = cursor.getFloat(payrateColumnIndex)
val totalPay = cursor.getFloat(totalPayColumnIndex)
mLocationEditText!!.setText(description)
mDateEditText!!.setText(date)
if ((type == "Hourly") || (type == "hourly")) {
mRadioButtonOne!!.isChecked = true
mRadioButtonTwo!!.isChecked = false
mTimeInEditText!!.setText(timeIn)
mTimeOutEditText!!.setText(timeOut)
mBreakEditText!!.setText(Integer.toString(breaks))
mDurationTextView!!.text = String.format("%.2f", duration) + " Hours"
} else if ((type == "Piece Rate")) {
mRadioButtonOne!!.isChecked = false
mRadioButtonTwo!!.isChecked = true
mUnitEditText!!.setText(java.lang.Float.toString(unit))
}
mPayRateEditText!!.setText(String.format("%.2f", payrate))
mTotalPayTextView!!.text = String.format("%.2f", totalPay)
}
}
companion object {
private val EXISTING_PRODUCT_LOADER = 0
var mRadioGroup: RadioGroup? = null
}
}

View File

@@ -1,534 +0,0 @@
package com.appttude.h_mal.farmr;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.Toast;
import com.ajts.androidmads.library.SQLiteToExcel;
import com.appttude.h_mal.farmr.Data.ShiftsContract.ShiftsEntry;
import com.appttude.h_mal.farmr.Data.ShiftsDbHelper;
import java.io.File;
import static com.appttude.h_mal.farmr.MainActivity.args;
import static com.appttude.h_mal.farmr.MainActivity.filter;
import static com.appttude.h_mal.farmr.MainActivity.selection;
import static com.appttude.h_mal.farmr.MainActivity.sortOrder;
public class FragmentMain extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>{
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
private static final int DEFAULT_LOADER = 0;
public static int NEW_LOADER = 0;
ShiftsCursorAdapter mCursorAdapter;
ShiftsDbHelper shiftsDbhelper;
LoaderManager.LoaderCallbacks defaultLoaderCallback;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
setHasOptionsMenu(true);
MainActivity.setActionBarTitle(getString(R.string.app_name));
filter = getActivity().getSharedPreferences("PREFS", 0);
sortOrder = filter.getString("Filter",null);
defaultLoaderCallback = this;
ListView productListView = (ListView) rootView.findViewById(R.id.list_item_view);
View emptyView = rootView.findViewById(R.id.empty_view);
productListView.setEmptyView(emptyView);
mCursorAdapter = new ShiftsCursorAdapter((MainActivity) getActivity(), null);
productListView.setAdapter(mCursorAdapter);
getLoaderManager().initLoader(DEFAULT_LOADER, null, defaultLoaderCallback);
FloatingActionButton fab = (FloatingActionButton) rootView.findViewById(R.id.fab1);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction = (MainActivity.fragmentManager).beginTransaction();
fragmentTransaction.replace(R.id.container,new FragmentAddItem()).addToBackStack("additem").commit();
}
});
return rootView;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_all:
deleteAllProducts();
return true;
case R.id.help:
new AlertDialog.Builder(getContext())
.setTitle("Help & Support:")
.setView(R.layout.dialog_layout)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
}
}).create().show();
return true;
case R.id.filter_data:
FragmentTransaction fragmentTransaction = (MainActivity.fragmentManager).beginTransaction();
fragmentTransaction.replace(R.id.container,new FilterDataFragment()).addToBackStack("filterdata").commit();
return true;
case R.id.sort_data:
sortData();
return true;
case R.id.clear_filter:
args = null;
selection = null;
NEW_LOADER = 0;
getLoaderManager().restartLoader(DEFAULT_LOADER, null, this);
return true;
case R.id.export_data:
if(checkStoragePermissions(getActivity())){
new AlertDialog.Builder(getContext())
.setTitle("Export?")
.setMessage("Exporting current filtered data. Continue?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
ExportData();
}
}).create().show();
}else{
Toast.makeText(getContext(), "Storage permissions required", Toast.LENGTH_SHORT).show();
}
return true;
case R.id.action_favorite:
new AlertDialog.Builder(getContext())
.setTitle("Info:")
.setMessage(retrieveInfo())
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
}
}).create().show();
return true;
}
return super.onOptionsItemSelected(item);
}
private void sortData(){
final String[] grpname = {"Added","Date","Name"};
final String[] sortQuery = {""};
int checkedItem = -1;
if(sortOrder != null && sortOrder.contains(ShiftsEntry._ID)){
checkedItem = 0;
sortQuery[0] = ShiftsEntry._ID;
}else if(sortOrder != null && sortOrder.contains(ShiftsEntry.COLUMN_SHIFT_DATE)){
checkedItem = 1;
sortQuery[0] = ShiftsEntry.COLUMN_SHIFT_DATE;
}else if(sortOrder != null && sortOrder.contains(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION)){
checkedItem = 2;
sortQuery[0] = ShiftsEntry.COLUMN_SHIFT_DESCRIPTION;
}
AlertDialog.Builder alt_bld = new AlertDialog.Builder(getContext());
//alt_bld.setIcon(R.drawable.icon);
alt_bld.setTitle("Sort by:");
alt_bld.setSingleChoiceItems(grpname, checkedItem, new DialogInterface
.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
switch (item) {
case 0:
sortQuery[0] = ShiftsEntry._ID;
return;
case 1:
sortQuery[0] = ShiftsEntry.COLUMN_SHIFT_DATE;
return;
case 2:
sortQuery[0] = ShiftsEntry.COLUMN_SHIFT_DESCRIPTION;
}
}
}).setPositiveButton("Ascending", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
sortOrder = sortQuery[0] + " ASC";
filter.edit().putString("Filter",sortOrder).apply();
getLoaderManager().restartLoader(DEFAULT_LOADER, null, defaultLoaderCallback);
dialog.dismiss();
}
}).setNegativeButton("Descending", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
sortOrder = sortQuery[0] + " DESC";
filter.edit().putString("Filter",sortOrder).apply();
getLoaderManager().restartLoader(DEFAULT_LOADER, null, defaultLoaderCallback);
dialog.dismiss();
}
});
AlertDialog alert = alt_bld.create();
alert.show();
}
private void deleteAllProducts() {
new AlertDialog.Builder(getContext())
.setTitle("Delete?")
.setMessage("Are you sure you want to delete all date?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
int rowsDeleted = getActivity().getContentResolver().delete(ShiftsEntry.CONTENT_URI, null, null);
Toast.makeText(getContext(), rowsDeleted + " Items Deleted", Toast.LENGTH_SHORT).show();
}
}).create().show();
}
@Override
public void onResume() {
super.onResume();
if(NEW_LOADER > DEFAULT_LOADER) {
getLoaderManager().restartLoader(DEFAULT_LOADER, null, defaultLoaderCallback);
System.out.println("reloading loader");
}
}
private void ExportData() {
int permission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getContext(), "Storage permissions not granted", Toast.LENGTH_SHORT).show();
return;
}
shiftsDbhelper = new ShiftsDbHelper(getContext());
SQLiteDatabase database = shiftsDbhelper.getWritableDatabase();
String[] projection_export = {
ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsEntry.COLUMN_SHIFT_TOTALPAY};
Cursor cursor = getActivity().getContentResolver().query(
ShiftsEntry.CONTENT_URI,
projection_export,
selection,
args,
sortOrder);
database.delete(ShiftsEntry.TABLE_NAME_EXPORT,null,null);
float totalDuration = 0.00f;
float totalUnits = 0.00f;
float totalPay= 0.00f;
try {
while (cursor.moveToNext()) {
final String descriptionColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION));
final String dateColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DATE));
final String timeInColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TIME_IN));
final String timeOutColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TIME_OUT));
final Float durationColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DURATION));
final Integer breakOutColumnIndex = cursor.getInt(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_BREAK));
final String typeColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TYPE));
final Float unitColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_UNIT));
final Float payrateColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_PAYRATE));
final Float totalpayColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TOTALPAY));
totalUnits = totalUnits + unitColumnIndex;
totalDuration = totalDuration + durationColumnIndex;
totalPay = totalPay + totalpayColumnIndex;
ContentValues values = new ContentValues();
values.put(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION, descriptionColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_DATE, dateColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_IN, timeInColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_OUT, timeOutColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_BREAK, breakOutColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_DURATION, durationColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_TYPE, typeColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_UNIT, unitColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_PAYRATE, payrateColumnIndex);
values.put(ShiftsEntry.COLUMN_SHIFT_TOTALPAY, totalpayColumnIndex);
database.insert(ShiftsEntry.TABLE_NAME_EXPORT, null, values);
}
}catch (Exception e){
Log.e("FragmentMain", "ExportData: ", e);
}finally {
ContentValues values = new ContentValues();
values.put(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION, "");
values.put(ShiftsEntry.COLUMN_SHIFT_DATE, "");
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_IN, "");
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_OUT, "");
values.put(ShiftsEntry.COLUMN_SHIFT_BREAK, "Total duration:");
values.put(ShiftsEntry.COLUMN_SHIFT_DURATION, totalDuration);
values.put(ShiftsEntry.COLUMN_SHIFT_TYPE, "Total units:");
values.put(ShiftsEntry.COLUMN_SHIFT_UNIT, totalUnits);
values.put(ShiftsEntry.COLUMN_SHIFT_PAYRATE, "Total pay:");
values.put(ShiftsEntry.COLUMN_SHIFT_TOTALPAY, totalPay);
database.insert(ShiftsEntry.TABLE_NAME_EXPORT, null, values);
cursor.close();
}
final String savePath = Environment.getExternalStorageDirectory() + "/ShifttrackerTemp";
File file = new File(savePath);
if (!file.exists()) {
file.mkdirs();
}
SQLiteToExcel sqLiteToExcel = new SQLiteToExcel(getContext(), "shifts.db",savePath);
sqLiteToExcel.exportSingleTable("shiftsexport","shifthistory.xls", new SQLiteToExcel.ExportListener() {
@Override
public void onStart() {
}
@Override
public void onCompleted(String filePath) {
Toast.makeText(getContext(), filePath, Toast.LENGTH_SHORT).show();
Uri newPath = Uri.parse("file://" + savePath + "/" +"shifthistory.xls");
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent emailintent = new Intent(Intent.ACTION_SEND);
emailintent.setType("application/vnd.ms-excel");
emailintent.putExtra(Intent.EXTRA_SUBJECT, "historic shifts");
emailintent.putExtra(Intent.EXTRA_TEXT, "I'm email body.");
emailintent.putExtra(Intent.EXTRA_STREAM,newPath);
startActivity(Intent.createChooser(emailintent, "Send Email"));
}
@Override
public void onError(Exception e) {
System.out.println("Error msg: " + e);
Toast.makeText(getContext(), "Failed to Export data", Toast.LENGTH_SHORT).show();
}
});
}
private String retrieveInfo(){
String[] projection = {
ShiftsEntry._ID,
ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsEntry.COLUMN_SHIFT_TOTALPAY};
Cursor cursor = getActivity().getContentResolver().query(
ShiftsEntry.CONTENT_URI,
projection,
selection,
args,
sortOrder);
float totalDuration = 0.0f;
int countOfTypeH = 0;
int countOfTypeP = 0;
float totalUnits = 0;
float totalPay = 0;
int lines = 0;
try {
while (cursor.moveToNext()) {
final float durationColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DURATION));
final String typeColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TYPE));
final float unitColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_UNIT));
final float totalpayColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TOTALPAY));
totalDuration = totalDuration + durationColumnIndex;
if (typeColumnIndex.contains("Hourly")){
countOfTypeH = countOfTypeH + 1;
}else if (typeColumnIndex.contains("Piece")){
countOfTypeP = countOfTypeP +1;
}
totalUnits= totalUnits + unitColumnIndex;
totalPay = totalPay + totalpayColumnIndex;
}
} finally {
if ((cursor != null) && (cursor.getCount() > 0)) {
lines = cursor.getCount();
cursor.close();
}
}
return buildInfoString(totalDuration,countOfTypeH,countOfTypeP,totalUnits,totalPay,lines);
}
@SuppressLint("DefaultLocale")
public String buildInfoString(float totalDuration, int countOfTypeH, int countOfTypeP, float totalUnits, float totalPay, int lines){
String textString;
textString = lines + " Shifts";
if (countOfTypeH != 0 && countOfTypeP != 0){
textString = textString + " (" + countOfTypeH + " Hourly" + "/" + countOfTypeP + " Piece Rate)";
}
if(countOfTypeH != 0){
textString = textString
+ "\n" + "Total Hours: " + String.format("%.2f",totalDuration);
}
if(countOfTypeP != 0){
textString = textString
+ "\n" + "Total Units: " + String.format("%.2f",totalUnits);
}
if (totalPay != 0){
textString = textString
+ "\n" + "Total Pay: " + "$" + String.format("%.2f",totalPay);
}
return textString;
}
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String[] projection = {
ShiftsEntry._ID,
ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsEntry.COLUMN_SHIFT_TOTALPAY,};
return new android.support.v4.content.CursorLoader(getContext(),
ShiftsEntry.CONTENT_URI,
projection,
selection,
args,
sortOrder);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mCursorAdapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mCursorAdapter.swapCursor(null);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
System.out.println("request code" + requestCode);
if (requestCode == MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
exportDialog();
} else {
Toast.makeText(getContext(), "Storage Permissions denied", Toast.LENGTH_SHORT).show();
}
}
}
public void exportDialog(){
new AlertDialog.Builder(getContext())
.setTitle("Export?")
.setMessage("Exporting current filtered data. Continue?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
ExportData();
}
}).create().show();
}
// // Storage Permissions
// private static final int REQUEST_EXTERNAL_STORAGE = 1;
// private static String[] PERMISSIONS_STORAGE = {
// Manifest.permission.READ_EXTERNAL_STORAGE,
// Manifest.permission.WRITE_EXTERNAL_STORAGE
// };
// /**
// * Checks if the app has permission to write to device storage
// *
// * If the app does not has permission then the user will be prompted to grant permissions
// *
// * @param activity
// */
// public static void verifyStoragePermissions(Activity activity) {
// // Check if we have write permission
// int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
//
// if (permission != PackageManager.PERMISSION_GRANTED) {
// // We don't have permission so prompt the user
// ActivityCompat.requestPermissions(
// activity,
// PERMISSIONS_STORAGE,
// REQUEST_EXTERNAL_STORAGE
// );
// }
// }
public static boolean checkStoragePermissions(Activity activity){
boolean status = false;
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission == PackageManager.PERMISSION_GRANTED ){
status = true;
}
return status;
}
}

View File

@@ -0,0 +1,459 @@
package com.appttude.h_mal.farmr
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.ContentValues
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.os.StrictMode
import android.os.StrictMode.VmPolicy
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.loader.app.LoaderManager
import androidx.loader.content.CursorLoader
import androidx.loader.content.Loader
import com.ajts.androidmads.library.SQLiteToExcel
import com.ajts.androidmads.library.SQLiteToExcel.ExportListener
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry
import com.appttude.h_mal.farmr.data.ShiftsDbHelper
import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.io.File
class FragmentMain : Fragment(), LoaderManager.LoaderCallbacks<Cursor> {
var mCursorAdapter: ShiftsCursorAdapter? = null
var shiftsDbhelper: ShiftsDbHelper? = null
lateinit var defaultLoaderCallback: LoaderManager.LoaderCallbacks<Cursor>
lateinit var activity: MainActivity
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val rootView = inflater.inflate(R.layout.fragment_main, container, false)
setHasOptionsMenu(true)
activity = (requireActivity() as MainActivity)
activity.setActionBarTitle(getString(R.string.app_name))
activity.filter = activity.getSharedPreferences("PREFS", 0)
activity.sortOrder = activity.filter?.getString("Filter", null)
defaultLoaderCallback = this
val productListView = rootView.findViewById<View>(R.id.list_item_view) as ListView
val emptyView = rootView.findViewById<View>(R.id.empty_view)
productListView.emptyView = emptyView
mCursorAdapter = ShiftsCursorAdapter(activity, null)
productListView.adapter = mCursorAdapter
loaderManager.initLoader(DEFAULT_LOADER, null, defaultLoaderCallback)
val fab = rootView.findViewById<FloatingActionButton>(R.id.fab1)
fab.setOnClickListener {
val fragmentTransaction: FragmentTransaction = activity.fragmentManager!!.beginTransaction()
fragmentTransaction.replace(R.id.container, FragmentAddItem()).addToBackStack("additem").commit()
}
return rootView
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.delete_all -> {
deleteAllProducts()
return true
}
R.id.help -> {
AlertDialog.Builder(context)
.setTitle("Help & Support:")
.setView(R.layout.dialog_layout)
.setPositiveButton(android.R.string.yes) { arg0, arg1 -> }.create().show()
return true
}
R.id.filter_data -> {
val fragmentTransaction: FragmentTransaction = activity.fragmentManager!!.beginTransaction()
fragmentTransaction.replace(R.id.container, FilterDataFragment()).addToBackStack("filterdata").commit()
return true
}
R.id.sort_data -> {
sortData()
return true
}
R.id.clear_filter -> {
activity.args = null
activity.selection = null
NEW_LOADER = 0
loaderManager.restartLoader(DEFAULT_LOADER, null, this)
return true
}
R.id.export_data -> {
if (checkStoragePermissions(activity)) {
AlertDialog.Builder(context)
.setTitle("Export?")
.setMessage("Exporting current filtered data. Continue?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes) { arg0, arg1 -> ExportData() }.create().show()
} else {
Toast.makeText(context, "Storage permissions required", Toast.LENGTH_SHORT).show()
}
return true
}
R.id.action_favorite -> {
AlertDialog.Builder(context)
.setTitle("Info:")
.setMessage(retrieveInfo())
.setPositiveButton(android.R.string.yes) { arg0, arg1 -> }.create().show()
return true
}
}
return super.onOptionsItemSelected(item)
}
private fun sortData() {
val grpname = arrayOf("Added", "Date", "Name")
val sortQuery = arrayOf<String?>("")
var checkedItem = -1
if (activity.sortOrder != null && activity.sortOrder!!.contains(ShiftsEntry._ID)) {
checkedItem = 0
sortQuery[0] = ShiftsEntry._ID
} else if (activity.sortOrder != null && activity.sortOrder!!.contains(ShiftsEntry.COLUMN_SHIFT_DATE)) {
checkedItem = 1
sortQuery[0] = ShiftsEntry.COLUMN_SHIFT_DATE
} else if (activity.sortOrder != null && activity.sortOrder!!.contains(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION)) {
checkedItem = 2
sortQuery[0] = ShiftsEntry.COLUMN_SHIFT_DESCRIPTION
}
val alt_bld = AlertDialog.Builder(context)
//alt_bld.setIcon(R.drawable.icon);
alt_bld.setTitle("Sort by:")
alt_bld.setSingleChoiceItems(grpname, checkedItem, DialogInterface.OnClickListener { dialog, item ->
when (item) {
0 -> {
sortQuery[0] = ShiftsEntry._ID
return@OnClickListener
}
1 -> {
sortQuery[0] = ShiftsEntry.COLUMN_SHIFT_DATE
return@OnClickListener
}
2 -> sortQuery[0] = ShiftsEntry.COLUMN_SHIFT_DESCRIPTION
}
}).setPositiveButton("Ascending") { dialog, id ->
activity.sortOrder = sortQuery[0] + " ASC"
activity.filter!!.edit().putString("Filter", activity.sortOrder).apply()
loaderManager.restartLoader(DEFAULT_LOADER, null, defaultLoaderCallback)
dialog.dismiss()
}.setNegativeButton("Descending") { dialog, id ->
activity.sortOrder = sortQuery[0] + " DESC"
activity.filter!!.edit().putString("Filter", activity.sortOrder).apply()
loaderManager.restartLoader(DEFAULT_LOADER, null, defaultLoaderCallback)
dialog.dismiss()
}
val alert = alt_bld.create()
alert.show()
}
private fun deleteAllProducts() {
AlertDialog.Builder(context)
.setTitle("Delete?")
.setMessage("Are you sure you want to delete all date?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes) { arg0, arg1 ->
val rowsDeleted = activity.contentResolver.delete(ShiftsEntry.CONTENT_URI, null, null)
Toast.makeText(context, "$rowsDeleted Items Deleted", Toast.LENGTH_SHORT).show()
}.create().show()
}
override fun onResume() {
super.onResume()
if (NEW_LOADER > DEFAULT_LOADER) {
loaderManager.restartLoader(DEFAULT_LOADER, null, defaultLoaderCallback)
println("reloading loader")
}
}
private fun ExportData() {
val permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (permission != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context, "Storage permissions not granted", Toast.LENGTH_SHORT).show()
return
}
shiftsDbhelper = ShiftsDbHelper(context)
val database = shiftsDbhelper!!.writableDatabase
val projection_export = arrayOf<String?>(
ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsEntry.COLUMN_SHIFT_TOTALPAY)
val cursor = activity.contentResolver.query(
ShiftsEntry.CONTENT_URI,
projection_export,
activity.selection,
activity.args,
activity.sortOrder)
database.delete(ShiftsEntry.TABLE_NAME_EXPORT, null, null)
var totalDuration = 0.00f
var totalUnits = 0.00f
var totalPay = 0.00f
try {
while (cursor!!.moveToNext()) {
val descriptionColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION))
val dateColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DATE))
val timeInColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TIME_IN))
val timeOutColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TIME_OUT))
val durationColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DURATION))
val breakOutColumnIndex = cursor.getInt(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_BREAK))
val typeColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TYPE))
val unitColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_UNIT))
val payrateColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_PAYRATE))
val totalpayColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TOTALPAY))
totalUnits = totalUnits + unitColumnIndex
totalDuration = totalDuration + durationColumnIndex
totalPay = totalPay + totalpayColumnIndex
val values = ContentValues()
values.put(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION, descriptionColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_DATE, dateColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_IN, timeInColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_OUT, timeOutColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_BREAK, breakOutColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_DURATION, durationColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_TYPE, typeColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_UNIT, unitColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_PAYRATE, payrateColumnIndex)
values.put(ShiftsEntry.COLUMN_SHIFT_TOTALPAY, totalpayColumnIndex)
database.insert(ShiftsEntry.TABLE_NAME_EXPORT, null, values)
}
} catch (e: Exception) {
Log.e("FragmentMain", "ExportData: ", e)
} finally {
val values = ContentValues()
values.put(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION, "")
values.put(ShiftsEntry.COLUMN_SHIFT_DATE, "")
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_IN, "")
values.put(ShiftsEntry.COLUMN_SHIFT_TIME_OUT, "")
values.put(ShiftsEntry.COLUMN_SHIFT_BREAK, "Total duration:")
values.put(ShiftsEntry.COLUMN_SHIFT_DURATION, totalDuration)
values.put(ShiftsEntry.COLUMN_SHIFT_TYPE, "Total units:")
values.put(ShiftsEntry.COLUMN_SHIFT_UNIT, totalUnits)
values.put(ShiftsEntry.COLUMN_SHIFT_PAYRATE, "Total pay:")
values.put(ShiftsEntry.COLUMN_SHIFT_TOTALPAY, totalPay)
database.insert(ShiftsEntry.TABLE_NAME_EXPORT, null, values)
cursor!!.close()
}
val savePath = Environment.getExternalStorageDirectory().toString() + "/ShifttrackerTemp"
val file = File(savePath)
if (!file.exists()) {
file.mkdirs()
}
val sqLiteToExcel = SQLiteToExcel(context, "shifts.db", savePath)
sqLiteToExcel.exportSingleTable("shiftsexport", "shifthistory.xls", object : ExportListener {
override fun onStart() {}
override fun onCompleted(filePath: String) {
Toast.makeText(context, filePath, Toast.LENGTH_SHORT).show()
val newPath = Uri.parse("file://$savePath/shifthistory.xls")
val builder = VmPolicy.Builder()
StrictMode.setVmPolicy(builder.build())
val emailintent = Intent(Intent.ACTION_SEND)
emailintent.type = "application/vnd.ms-excel"
emailintent.putExtra(Intent.EXTRA_SUBJECT, "historic shifts")
emailintent.putExtra(Intent.EXTRA_TEXT, "I'm email body.")
emailintent.putExtra(Intent.EXTRA_STREAM, newPath)
startActivity(Intent.createChooser(emailintent, "Send Email"))
}
override fun onError(e: Exception) {
println("Error msg: $e")
Toast.makeText(context, "Failed to Export data", Toast.LENGTH_SHORT).show()
}
})
}
private fun retrieveInfo(): String {
val projection = arrayOf<String?>(
ShiftsEntry._ID,
ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsEntry.COLUMN_SHIFT_TOTALPAY)
val cursor = activity.contentResolver.query(
ShiftsEntry.CONTENT_URI,
projection,
activity.selection,
activity.args,
activity.sortOrder)
var totalDuration = 0.0f
var countOfTypeH = 0
var countOfTypeP = 0
var totalUnits = 0f
var totalPay = 0f
var lines = 0
try {
while (cursor!!.moveToNext()) {
val durationColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DURATION))
val typeColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TYPE))
val unitColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_UNIT))
val totalpayColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TOTALPAY))
totalDuration = totalDuration + durationColumnIndex
if (typeColumnIndex.contains("Hourly")) {
countOfTypeH = countOfTypeH + 1
} else if (typeColumnIndex.contains("Piece")) {
countOfTypeP = countOfTypeP + 1
}
totalUnits = totalUnits + unitColumnIndex
totalPay = totalPay + totalpayColumnIndex
}
} finally {
if (cursor != null && cursor.count > 0) {
lines = cursor.count
cursor.close()
}
}
return buildInfoString(totalDuration, countOfTypeH, countOfTypeP, totalUnits, totalPay, lines)
}
@SuppressLint("DefaultLocale")
fun buildInfoString(totalDuration: Float, countOfTypeH: Int, countOfTypeP: Int, totalUnits: Float, totalPay: Float, lines: Int): String {
var textString: String
textString = "$lines Shifts"
if (countOfTypeH != 0 && countOfTypeP != 0) {
textString = "$textString ($countOfTypeH Hourly/$countOfTypeP Piece Rate)"
}
if (countOfTypeH != 0) {
textString = """
$textString
Total Hours: ${String.format("%.2f", totalDuration)}
""".trimIndent()
}
if (countOfTypeP != 0) {
textString = """
$textString
Total Units: ${String.format("%.2f", totalUnits)}
""".trimIndent()
}
if (totalPay != 0f) {
textString = """
$textString
Total Pay: ${"$"}${String.format("%.2f", totalPay)}
""".trimIndent()
}
return textString
}
override fun onCreateLoader(i: Int, bundle: Bundle?): Loader<Cursor> {
val projection = arrayOf<String?>(
ShiftsEntry._ID,
ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsEntry.COLUMN_SHIFT_TOTALPAY)
return CursorLoader(context!!,
ShiftsEntry.CONTENT_URI,
projection,
activity.selection,
activity.args,
activity.sortOrder)
}
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) {
mCursorAdapter!!.swapCursor(cursor)
}
override fun onLoaderReset(loader: Loader<Cursor>) {
mCursorAdapter!!.swapCursor(null)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
println("request code$requestCode")
if (requestCode == MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE) {
if (grantResults.size > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
exportDialog()
} else {
Toast.makeText(context, "Storage Permissions denied", Toast.LENGTH_SHORT).show()
}
}
}
fun exportDialog() {
AlertDialog.Builder(context)
.setTitle("Export?")
.setMessage("Exporting current filtered data. Continue?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes) { arg0, arg1 -> ExportData() }.create().show()
}
companion object {
const val MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1
private const val DEFAULT_LOADER = 0
var NEW_LOADER = 0
// // Storage Permissions
// private static final int REQUEST_EXTERNAL_STORAGE = 1;
// private static String[] PERMISSIONS_STORAGE = {
// Manifest.permission.READ_EXTERNAL_STORAGE,
// Manifest.permission.WRITE_EXTERNAL_STORAGE
// };
// /**
// * Checks if the app has permission to write to device storage
// *
// * If the app does not has permission then the user will be prompted to grant permissions
// *
// * @param activity
// */
// public static void verifyStoragePermissions(Activity activity) {
// // Check if we have write permission
// int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
//
// if (permission != PackageManager.PERMISSION_GRANTED) {
// // We don't have permission so prompt the user
// ActivityCompat.requestPermissions(
// activity,
// PERMISSIONS_STORAGE,
// REQUEST_EXTERNAL_STORAGE
// );
// }
// }
fun checkStoragePermissions(activity: Activity?): Boolean {
var status = false
val permission = ActivityCompat.checkSelfPermission(activity!!, Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (permission == PackageManager.PERMISSION_GRANTED) {
status = true
}
return status
}
}
}

View File

@@ -1,184 +0,0 @@
package com.appttude.h_mal.farmr;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.appttude.h_mal.farmr.Data.ShiftsContract;
public class FurtherInfoFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor> {
private static final int DEFAULT_LOADER = 0;
private TextView typeTV;
private TextView descriptionTV;
private TextView dateTV;
private TextView times;
private TextView breakTV;
private TextView durationTV;
private TextView unitsTV;
private TextView payRateTV;
private TextView totalPayTV;
private LinearLayout hourlyDetailHolder;
private LinearLayout unitsHolder;
private LinearLayout wholeView;
private ProgressBar progressBarFI;
private Button editButton;
private Uri CurrentUri;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_futher_info, container, false);
MainActivity.setActionBarTitle(getString(R.string.further_info_title));
setHasOptionsMenu(true);
progressBarFI = (ProgressBar) rootView.findViewById(R.id.progressBar_info);
wholeView = (LinearLayout) rootView.findViewById(R.id.further_info_view);
typeTV = (TextView)rootView.findViewById(R.id.details_shift);
descriptionTV = (TextView)rootView.findViewById(R.id.details_desc);
dateTV = (TextView)rootView.findViewById(R.id.details_date);
times = (TextView)rootView.findViewById(R.id.details_time);
breakTV = (TextView)rootView.findViewById(R.id.details_breaks);
durationTV = (TextView)rootView.findViewById(R.id.details_duration);
unitsTV = (TextView)rootView.findViewById(R.id.details_units);
payRateTV = (TextView)rootView.findViewById(R.id.details_pay_rate);
totalPayTV = (TextView)rootView.findViewById(R.id.details_totalpay);
editButton = (Button) rootView.findViewById(R.id.details_edit);
hourlyDetailHolder = (LinearLayout) rootView.findViewById(R.id.details_hourly_details);
unitsHolder = (LinearLayout) rootView.findViewById(R.id.details_units_holder);
final Bundle b = getArguments();
CurrentUri = Uri.parse(b.getString("uri"));
getLoaderManager().initLoader(DEFAULT_LOADER, null, this);
editButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction = (MainActivity.fragmentManager).beginTransaction();
Fragment fragment = new FragmentAddItem();
fragment.setArguments(b);
fragmentTransaction.replace(R.id.container,fragment).addToBackStack("additem").commit();
}
});
return rootView;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
progressBarFI.setVisibility(View.VISIBLE);
wholeView.setVisibility(View.GONE);
String[] projection = {
ShiftsContract.ShiftsEntry._ID,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TOTALPAY,};
return new android.support.v4.content.CursorLoader(getContext(),CurrentUri,
projection,null,null,null);
}
@Override
public void onLoadFinished(android.support.v4.content.Loader<Cursor> loader, Cursor cursor) {
progressBarFI.setVisibility(View.GONE);
wholeView.setVisibility(View.VISIBLE);
if (cursor == null || cursor.getCount() < 1) {
return;
}
if (cursor.moveToFirst()) {
int descriptionColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DESCRIPTION);
int dateColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DATE);
int timeInColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_IN);
int timeOutColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TIME_OUT);
int breakColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_BREAK);
int durationColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_DURATION);
int typeColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TYPE);
int unitColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_UNIT);
int payrateColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_PAYRATE);
int totalPayColumnIndex = cursor.getColumnIndex(ShiftsContract.ShiftsEntry.COLUMN_SHIFT_TOTALPAY);
String type = cursor.getString(typeColumnIndex);
String description = cursor.getString(descriptionColumnIndex);
String date = cursor.getString(dateColumnIndex);
String timeIn = cursor.getString(timeInColumnIndex);
String timeOut = cursor.getString(timeOutColumnIndex);
int breaks = cursor.getInt(breakColumnIndex);
float duration = cursor.getFloat(durationColumnIndex);
float unit = cursor.getFloat(unitColumnIndex);
float payrate = cursor.getFloat(payrateColumnIndex);
float totalPay = cursor.getFloat(totalPayColumnIndex);
String durationString = ShiftsCursorAdapter.timeValues(duration)[0] + " Hours " + ShiftsCursorAdapter.timeValues(duration)[1] + " Minutes ";
if(breaks != 0){
durationString = durationString + " (+ " + Integer.toString(breaks) + " minutes break)";
}
typeTV.setText(type);
descriptionTV.setText(description);
dateTV.setText(date);
String totalPaid = "";
String currency = "$";
if(type.equals("Hourly")){
hourlyDetailHolder.setVisibility(View.VISIBLE);
unitsHolder.setVisibility(View.GONE);
times.setText(timeIn + " - " + timeOut);
breakTV.setText(Integer.toString(breaks) + "mins");
durationTV.setText(durationString);
totalPaid = String.format("%.2f",duration) + " Hours @ " + currency + String.format("%.2f",payrate) + " per Hour" + "\n"
+ "Equals: " + currency + String.format("%.2f",totalPay);
}else if(type.equals("Piece Rate")){
hourlyDetailHolder.setVisibility(View.GONE);
unitsHolder.setVisibility(View.VISIBLE);
unitsTV.setText(String.format("%.2f",unit));
totalPaid = String.format("%.2f",unit) + " Units @ " + currency + String.format("%.2f",payrate) + " per Unit" + "\n"
+ "Equals: " + currency + String.format("%.2f",totalPay);
}
payRateTV.setText(String.format("%.2f",payrate));
totalPayTV.setText(totalPaid);
}
}
@Override
public void onLoaderReset(android.support.v4.content.Loader<Cursor> loader) {
}
}

View File

@@ -0,0 +1,161 @@
package com.appttude.h_mal.farmr
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.loader.app.LoaderManager
import androidx.loader.content.CursorLoader
import androidx.loader.content.Loader
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry
class FurtherInfoFragment : Fragment(), LoaderManager.LoaderCallbacks<Cursor> {
private var typeTV: TextView? = null
private var descriptionTV: TextView? = null
private var dateTV: TextView? = null
private var times: TextView? = null
private var breakTV: TextView? = null
private var durationTV: TextView? = null
private var unitsTV: TextView? = null
private var payRateTV: TextView? = null
private var totalPayTV: TextView? = null
private var hourlyDetailHolder: LinearLayout? = null
private var unitsHolder: LinearLayout? = null
private var wholeView: LinearLayout? = null
private var progressBarFI: ProgressBar? = null
private var editButton: Button? = null
private var CurrentUri: Uri? = null
lateinit var activity: MainActivity
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
// Inflate the layout for this fragment
val rootView: View = inflater.inflate(R.layout.fragment_futher_info, container, false)
setHasOptionsMenu(true)
activity = (requireActivity() as MainActivity)
activity.setActionBarTitle(getString(R.string.further_info_title))
progressBarFI = rootView.findViewById<View>(R.id.progressBar_info) as ProgressBar?
wholeView = rootView.findViewById<View>(R.id.further_info_view) as LinearLayout?
typeTV = rootView.findViewById<View>(R.id.details_shift) as TextView?
descriptionTV = rootView.findViewById<View>(R.id.details_desc) as TextView?
dateTV = rootView.findViewById<View>(R.id.details_date) as TextView?
times = rootView.findViewById<View>(R.id.details_time) as TextView?
breakTV = rootView.findViewById<View>(R.id.details_breaks) as TextView?
durationTV = rootView.findViewById<View>(R.id.details_duration) as TextView?
unitsTV = rootView.findViewById<View>(R.id.details_units) as TextView?
payRateTV = rootView.findViewById<View>(R.id.details_pay_rate) as TextView?
totalPayTV = rootView.findViewById<View>(R.id.details_totalpay) as TextView?
editButton = rootView.findViewById<View>(R.id.details_edit) as Button?
hourlyDetailHolder = rootView.findViewById<View>(R.id.details_hourly_details) as LinearLayout?
unitsHolder = rootView.findViewById<View>(R.id.details_units_holder) as LinearLayout?
val b: Bundle? = arguments
CurrentUri = Uri.parse(b!!.getString("uri"))
loaderManager.initLoader(DEFAULT_LOADER, null, this)
editButton!!.setOnClickListener(object : View.OnClickListener {
override fun onClick(view: View) {
val fragmentTransaction: FragmentTransaction = (activity.fragmentManager)!!.beginTransaction()
val fragment: Fragment = FragmentAddItem()
fragment.arguments = b
fragmentTransaction.replace(R.id.container, fragment).addToBackStack("additem").commit()
}
})
return rootView
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
menu.clear()
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor?> {
progressBarFI!!.visibility = View.VISIBLE
wholeView!!.visibility = View.GONE
val projection: Array<String?> = arrayOf(
ShiftsEntry._ID,
ShiftsEntry.COLUMN_SHIFT_DESCRIPTION,
ShiftsEntry.COLUMN_SHIFT_DATE,
ShiftsEntry.COLUMN_SHIFT_TIME_IN,
ShiftsEntry.COLUMN_SHIFT_TIME_OUT,
ShiftsEntry.COLUMN_SHIFT_BREAK,
ShiftsEntry.COLUMN_SHIFT_DURATION,
ShiftsEntry.COLUMN_SHIFT_TYPE,
ShiftsEntry.COLUMN_SHIFT_PAYRATE,
ShiftsEntry.COLUMN_SHIFT_UNIT,
ShiftsEntry.COLUMN_SHIFT_TOTALPAY)
return CursorLoader((context)!!, (CurrentUri)!!,
projection, null, null, null)
}
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) {
progressBarFI!!.visibility = View.GONE
wholeView!!.visibility = View.VISIBLE
if (cursor == null || cursor.count < 1) {
return
}
if (cursor.moveToFirst()) {
val descriptionColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION)
val dateColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_DATE)
val timeInColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_TIME_IN)
val timeOutColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_TIME_OUT)
val breakColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_BREAK)
val durationColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_DURATION)
val typeColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_TYPE)
val unitColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_UNIT)
val payrateColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_PAYRATE)
val totalPayColumnIndex: Int = cursor.getColumnIndex(ShiftsEntry.COLUMN_SHIFT_TOTALPAY)
val type: String = cursor.getString(typeColumnIndex)
val description: String = cursor.getString(descriptionColumnIndex)
val date: String = cursor.getString(dateColumnIndex)
val timeIn: String = cursor.getString(timeInColumnIndex)
val timeOut: String = cursor.getString(timeOutColumnIndex)
val breaks: Int = cursor.getInt(breakColumnIndex)
val duration: Float = cursor.getFloat(durationColumnIndex)
val unit: Float = cursor.getFloat(unitColumnIndex)
val payrate: Float = cursor.getFloat(payrateColumnIndex)
val totalPay: Float = cursor.getFloat(totalPayColumnIndex)
var durationString: String = ShiftsCursorAdapter.Companion.timeValues(duration).get(0) + " Hours " + ShiftsCursorAdapter.Companion.timeValues(duration).get(1) + " Minutes "
if (breaks != 0) {
durationString = durationString + " (+ " + Integer.toString(breaks) + " minutes break)"
}
typeTV!!.text = type
descriptionTV!!.text = description
dateTV!!.text = date
var totalPaid: String? = ""
val currency: String = "$"
if ((type == "Hourly")) {
hourlyDetailHolder!!.visibility = View.VISIBLE
unitsHolder!!.visibility = View.GONE
times!!.text = timeIn + " - " + timeOut
breakTV!!.text = Integer.toString(breaks) + "mins"
durationTV!!.text = durationString
totalPaid = (String.format("%.2f", duration) + " Hours @ " + currency + String.format("%.2f", payrate) + " per Hour" + "\n"
+ "Equals: " + currency + String.format("%.2f", totalPay))
} else if ((type == "Piece Rate")) {
hourlyDetailHolder!!.visibility = View.GONE
unitsHolder!!.visibility = View.VISIBLE
unitsTV!!.text = String.format("%.2f", unit)
totalPaid = (String.format("%.2f", unit) + " Units @ " + currency + String.format("%.2f", payrate) + " per Unit" + "\n"
+ "Equals: " + currency + String.format("%.2f", totalPay))
}
payRateTV!!.text = String.format("%.2f", payrate)
totalPayTV!!.text = totalPaid
}
}
override fun onLoaderReset(loader: Loader<Cursor>) {}
companion object {
private val DEFAULT_LOADER: Int = 0
}
}

View File

@@ -1,179 +0,0 @@
package com.appttude.h_mal.farmr;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public static SharedPreferences filter;
public static Context context;
static String sortOrder;
public static String selection;
public static String[] args;
private static Toolbar toolbar;
public static FragmentManager fragmentManager;
private String currentFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
verifyStoragePermissions(this);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container,new FragmentMain()).addToBackStack("main").commit();
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
List<Fragment> f = fragmentManager.getFragments();
Fragment frag = f.get(0);
currentFragment = frag.getClass().getSimpleName();
}
});
}
public static void setActionBarTitle(String title){
toolbar.setTitle(title);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public void onBackPressed() {
switch (currentFragment) {
case "FragmentMain":
new AlertDialog.Builder(this)
.setTitle("Leave?")
.setMessage("Are you sure you want to exit Farmr?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
finish();
System.exit(0);
}
}).create().show();
return;
case "FragmentAddItem":
if(FragmentAddItem.mRadioGroup.getCheckedRadioButtonId() == -1) {
fragmentManager.popBackStack();
}else{
new AlertDialog.Builder(this)
.setTitle("Discard Changes?")
.setMessage("Are you sure you want to discard changes?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
fragmentManager.popBackStack();
}
}).create().show();
}
return;
default:
if (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStack();
}
}
}
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
// @Override
// protected void onUserLeaveHint() {
// super.onUserLeaveHint();
//
// Intent intent = getIntent();
// String activity = intent.getStringExtra("activity");
//
// if (activity == null || !activity.equals("first") || !activity.equals("firsttime")) {
// NavUtils.navigateUpFromSameTask(MainActivity.this);
// } else {
// getIntent().removeExtra("activity");
// }
//
// }
// @Override
// protected void onPause() {
// super.onPause();
// // If the screen is off then the device has been locked
// PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
// boolean isScreenOn;
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
// isScreenOn = powerManager.isInteractive();
// } else {
// isScreenOn = powerManager.isScreenOn();
// }
//
// if (!isScreenOn) {
// Intent intent = getIntent();
// String activity = intent.getStringExtra("activity");
// if (activity == null || !activity.equals("first") || !activity.equals("firsttime")){
// NavUtils.navigateUpFromSameTask(MainActivity.this);
// }else {
// getIntent().removeExtra("activity");
// }
// System.out.println("mainactivity");
// }
// }
}

View File

@@ -0,0 +1,116 @@
package com.appttude.h_mal.farmr
import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.Menu
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
import androidx.fragment.app.FragmentManager
class MainActivity : AppCompatActivity() {
var filter: SharedPreferences? = null
var context: Context? = null
var sortOrder: String? = null
var selection: String? = null
var args: Array<String>? = null
private var toolbar: Toolbar? = null
var fragmentManager: FragmentManager? = null
private var currentFragment: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_view)
verifyStoragePermissions(this)
toolbar = findViewById<View>(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager?.beginTransaction()
fragmentTransaction?.replace(R.id.container, FragmentMain())?.addToBackStack("main")?.commit()
fragmentManager?.addOnBackStackChangedListener {
val f = fragmentManager?.fragments
val frag = f?.get(0)
currentFragment = frag?.javaClass?.simpleName
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onBackPressed() {
when (currentFragment) {
"FragmentMain" -> {
AlertDialog.Builder(this)
.setTitle("Leave?")
.setMessage("Are you sure you want to exit Farmr?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes) { arg0, arg1 ->
val intent = Intent(Intent.ACTION_MAIN)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
intent.addCategory(Intent.CATEGORY_HOME)
startActivity(intent)
finish()
System.exit(0)
}.create().show()
return
}
"FragmentAddItem" -> {
if (FragmentAddItem.Companion.mRadioGroup!!.checkedRadioButtonId == -1) {
fragmentManager!!.popBackStack()
} else {
AlertDialog.Builder(this)
.setTitle("Discard Changes?")
.setMessage("Are you sure you want to discard changes?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes) { arg0, arg1 -> fragmentManager!!.popBackStack() }.create().show()
}
return
}
else -> if (fragmentManager!!.backStackEntryCount > 1) {
fragmentManager!!.popBackStack()
}
}
}
fun setActionBarTitle(title: String?) {
toolbar!!.title = title
}
// Storage Permissions
private val REQUEST_EXTERNAL_STORAGE = 1
private val PERMISSIONS_STORAGE = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
fun verifyStoragePermissions(activity: Activity?) {
// Check if we have write permission
val permission = ActivityCompat.checkSelfPermission(activity!!, Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
)
}
}
}

View File

@@ -1,171 +0,0 @@
package com.appttude.h_mal.farmr;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.appttude.h_mal.farmr.Data.ShiftProvider;
import com.appttude.h_mal.farmr.Data.ShiftsContract.ShiftsEntry;
/**
* Created by h_mal on 26/12/2017.
*/
public class ShiftsCursorAdapter extends CursorAdapter {
private final MainActivity activity;
private Context mContext;
ShiftProvider shiftProvider;
public ShiftsCursorAdapter(MainActivity context, Cursor c) {
super(context, c, 0);
this.activity = context;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.list_item_1, parent, false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
mContext = context;
TextView descriptionTextView = (TextView) view.findViewById(R.id.location);
TextView dateTextView = (TextView) view.findViewById(R.id.date);
TextView totalPay = (TextView) view.findViewById(R.id.total_pay);
TextView hoursView = (TextView) view.findViewById(R.id.hours);
TextView h = (TextView) view.findViewById(R.id.h);
TextView minutesView = (TextView) view.findViewById(R.id.minutes);
TextView m = (TextView) view.findViewById(R.id.m);
ImageView editView = (ImageView) view.findViewById(R.id.imageView);
h.setText("h");
m.setText("m");
final String typeColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TYPE));
final String descriptionColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION));
final String dateColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DATE));
final Float durationColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DURATION));
final Float unitsColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_UNIT));
final Float totalpayColumnIndex = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TOTALPAY));
descriptionTextView.setText(descriptionColumnIndex);
dateTextView.setText(newDate(dateColumnIndex));
totalPay.setText(String.format("%.2f",totalpayColumnIndex));
if (typeColumnIndex.equals("Piece Rate") && durationColumnIndex == 0){
hoursView.setText(String.valueOf(unitsColumnIndex));
h.setText("");
minutesView.setText("");
m.setText("pcs");
}else
// if(typeColumnIndex.equals("Hourly") || typeColumnIndex.equals("hourly"))
{
hoursView.setText(timeValues(durationColumnIndex)[0]);
minutesView.setText(timeValues(durationColumnIndex)[1]);
}
final long ID = cursor.getLong(cursor.getColumnIndexOrThrow(ShiftsEntry._ID));
final Uri currentProductUri = ContentUris.withAppendedId(ShiftsEntry.CONTENT_URI, ID);
final Bundle b = new Bundle();
b.putString("uri",String.valueOf(currentProductUri));
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// activity.clickOnViewItem(ID);
FragmentTransaction fragmentTransaction = (MainActivity.fragmentManager).beginTransaction();
FurtherInfoFragment fragment2 = new FurtherInfoFragment();
fragment2.setArguments(b);
fragmentTransaction.replace(R.id.container,fragment2).addToBackStack("furtherinfo").commit();
}
});
editView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction = (MainActivity.fragmentManager).beginTransaction();
FragmentAddItem fragment3 = new FragmentAddItem();
fragment3.setArguments(b);
fragmentTransaction.replace(R.id.container,fragment3).addToBackStack("additem").commit();
}
});
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
System.out.println("long click: " + ID);
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(mContext);
builder.setMessage("Are you sure you want to delete");
builder.setPositiveButton("delete", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
deleteProduct(ID);
}
});
builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (dialog != null) {
dialog.dismiss();
}
}
});
android.app.AlertDialog alertDialog = builder.create();
alertDialog.show();
return true;
}
});
}
private void deleteProduct(Long id) {
String[] args = new String [] {String.valueOf(id)};
// String whereClause = String.format(ShiftsEntry._ID + " in (%s)", new Object[] { TextUtils.join(",", Collections.nCopies(args.length, "?")) }); //for deleting multiple lines
mContext.getContentResolver().delete(ShiftsEntry.CONTENT_URI, ShiftsEntry._ID + "=?", args);
}
private String newDate(String dateString){
String returnString = "01/01/2010";
String year = dateString.substring(0, 4);
String month = dateString.substring(5, 7);
String day = dateString.substring(8);
returnString = day + "-" + month + "-" + year;
return returnString;
}
public static String[] timeValues(Float duration){
int hours = (int) Math.floor(duration);
int minutes = (int) ((duration - hours)*60);
String hoursString = hours + "";
String minutesString = String.format("%02d", minutes);
return new String[]{hoursString,minutesString};
}
}

View File

@@ -0,0 +1,117 @@
package com.appttude.h_mal.farmr
import android.app.AlertDialog
import android.content.ContentUris
import android.content.Context
import android.content.DialogInterface
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnLongClickListener
import android.view.ViewGroup
import android.widget.CursorAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.fragment.app.FragmentTransaction
import com.appttude.h_mal.farmr.data.ShiftProvider
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry
import kotlin.math.floor
/**
* Created by h_mal on 26/12/2017.
*/
class ShiftsCursorAdapter constructor(private val activity: MainActivity, c: Cursor?) : CursorAdapter(activity, c, 0) {
private var mContext: Context? = null
var shiftProvider: ShiftProvider? = null
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
return LayoutInflater.from(context).inflate(R.layout.list_item_1, parent, false)
}
override fun bindView(view: View, context: Context, cursor: Cursor) {
mContext = context
val descriptionTextView: TextView = view.findViewById<View>(R.id.location) as TextView
val dateTextView: TextView = view.findViewById<View>(R.id.date) as TextView
val totalPay: TextView = view.findViewById<View>(R.id.total_pay) as TextView
val hoursView: TextView = view.findViewById<View>(R.id.hours) as TextView
val h: TextView = view.findViewById<View>(R.id.h) as TextView
val minutesView: TextView = view.findViewById<View>(R.id.minutes) as TextView
val m: TextView = view.findViewById<View>(R.id.m) as TextView
val editView: ImageView = view.findViewById<View>(R.id.imageView) as ImageView
h.text = "h"
m.text = "m"
val typeColumnIndex: String = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TYPE))
val descriptionColumnIndex: String = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION))
val dateColumnIndex: String = cursor.getString(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DATE))
val durationColumnIndex: Float = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_DURATION))
val unitsColumnIndex: Float = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_UNIT))
val totalpayColumnIndex: Float = cursor.getFloat(cursor.getColumnIndexOrThrow(ShiftsEntry.COLUMN_SHIFT_TOTALPAY))
descriptionTextView.text = descriptionColumnIndex
dateTextView.text = newDate(dateColumnIndex)
totalPay.text = String.format("%.2f", totalpayColumnIndex)
if ((typeColumnIndex == "Piece Rate") && durationColumnIndex == 0f) {
hoursView.text = unitsColumnIndex.toString()
h.text = ""
minutesView.text = ""
m.text = "pcs"
} else // if(typeColumnIndex.equals("Hourly") || typeColumnIndex.equals("hourly"))
{
hoursView.text = timeValues(durationColumnIndex).get(0)
minutesView.text = timeValues(durationColumnIndex).get(1)
}
val ID: Long = cursor.getLong(cursor.getColumnIndexOrThrow(ShiftsEntry._ID))
val currentProductUri: Uri = ContentUris.withAppendedId(ShiftsEntry.CONTENT_URI, ID)
val b: Bundle = Bundle()
b.putString("uri", currentProductUri.toString())
view.setOnClickListener { // activity.clickOnViewItem(ID);
val fragmentTransaction: FragmentTransaction = (activity.fragmentManager)!!.beginTransaction()
val fragment2: FurtherInfoFragment = FurtherInfoFragment()
fragment2.arguments = b
fragmentTransaction.replace(R.id.container, fragment2).addToBackStack("furtherinfo").commit()
}
editView.setOnClickListener {
val fragmentTransaction: FragmentTransaction = (activity.fragmentManager)!!.beginTransaction()
val fragment3: FragmentAddItem = FragmentAddItem()
fragment3.arguments = b
fragmentTransaction.replace(R.id.container, fragment3).addToBackStack("additem").commit()
}
view.setOnLongClickListener {
println("long click: $ID")
val builder: AlertDialog.Builder = AlertDialog.Builder(mContext)
builder.setMessage("Are you sure you want to delete")
builder.setPositiveButton("delete") { dialog, id -> deleteProduct(ID) }
builder.setNegativeButton("cancel") { dialog, id ->
dialog?.dismiss()
}
val alertDialog: AlertDialog = builder.create()
alertDialog.show()
true
}
}
private fun deleteProduct(id: Long) {
val args: Array<String> = arrayOf(id.toString())
// String whereClause = String.format(ShiftsEntry._ID + " in (%s)", new Object[] { TextUtils.join(",", Collections.nCopies(args.length, "?")) }); //for deleting multiple lines
mContext!!.contentResolver.delete(ShiftsEntry.CONTENT_URI, ShiftsEntry._ID + "=?", args)
}
private fun newDate(dateString: String): String {
var returnString: String? = "01/01/2010"
val year: String = dateString.substring(0, 4)
val month: String = dateString.substring(5, 7)
val day: String = dateString.substring(8)
returnString = "$day-$month-$year"
return returnString
}
companion object {
fun timeValues(duration: Float): Array<String> {
val hours: Int = floor(duration.toDouble()).toInt()
val minutes: Int = ((duration - hours) * 60).toInt()
val hoursString: String = hours.toString() + ""
val minutesString: String = String.format("%02d", minutes)
return arrayOf(hoursString, minutesString)
}
}
}

View File

@@ -1,46 +0,0 @@
package com.appttude.h_mal.farmr;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ActivityOptionsCompat;
import android.widget.RelativeLayout;
/**
* Created by h_mal on 27/06/2017.
*/
public class SplashScreen extends Activity {
// Splash screen timer
private static int SPLASH_TIME_OUT = 2000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
final Bundle bundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.hyperspace_jump, android.R.anim.fade_out).toBundle();
final RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.splash_layout);
final Intent i = new Intent(SplashScreen.this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// This method will be executed once the timer is over
// Start your app main activity
// startActivity(i,bundle);
startActivity(i);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
// finish();
}
}, SPLASH_TIME_OUT);
}
}

View File

@@ -0,0 +1,36 @@
package com.appttude.h_mal.farmr
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.view.View
import android.widget.RelativeLayout
import androidx.core.app.ActivityOptionsCompat
/**
* Created by h_mal on 27/06/2017.
*/
class SplashScreen : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
val bundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.hyperspace_jump, android.R.anim.fade_out).toBundle()
val relativeLayout = findViewById<View>(R.id.splash_layout) as RelativeLayout
val i = Intent(this@SplashScreen, MainActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK)
Handler().postDelayed({
// This method will be executed once the timer is over
// Start your app main activity
// startActivity(i,bundle);
startActivity(i)
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
// finish();
}, SPLASH_TIME_OUT.toLong())
}
companion object {
// Splash screen timer
private const val SPLASH_TIME_OUT = 2000
}
}

View File

@@ -0,0 +1,178 @@
package com.appttude.h_mal.farmr.data
import android.content.ContentProvider
import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.content.UriMatcher
import android.database.Cursor
import android.net.Uri
import android.util.Log
import androidx.annotation.VisibleForTesting
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry
/**
* Created by h_mal on 26/12/2017.
*/
class ShiftProvider : ContentProvider() {
private var mDbHelper: ShiftsDbHelper? = null
override fun onCreate(): Boolean {
mDbHelper = ShiftsDbHelper(context)
return true
}
override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?,
sortOrder: String?): Cursor? {
var selection = selection
var selectionArgs = selectionArgs
val database = mDbHelper!!.readableDatabase
val cursor: Cursor
val match = sUriMatcher.match(uri)
when (match) {
SHIFTS -> cursor = database.query(ShiftsEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder)
SHIFT_ID -> {
selection = ShiftsEntry._ID + "=?"
selectionArgs = arrayOf(ContentUris.parseId(uri).toString())
cursor = database.query(ShiftsEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder)
}
else -> throw IllegalArgumentException("Cannot query $uri")
}
cursor.setNotificationUri(context!!.contentResolver, uri)
return cursor
}
override fun insert(uri: Uri, contentValues: ContentValues?): Uri? {
val match = sUriMatcher.match(uri)
return when (match) {
SHIFTS -> insertShift(uri, contentValues)
else -> throw IllegalArgumentException("Insertion is not supported for $uri")
}
}
private fun insertShift(uri: Uri, values: ContentValues?): Uri? {
val description = values!!.getAsString(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION)
?: throw IllegalArgumentException("Description required")
val date = values.getAsString(ShiftsEntry.COLUMN_SHIFT_DATE)
?: throw IllegalArgumentException("Date required")
val timeIn = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TIME_IN)
?: throw IllegalArgumentException("Time In required")
val timeOut = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TIME_OUT)
?: throw IllegalArgumentException("Time Out required")
val duration = values.getAsFloat(ShiftsEntry.COLUMN_SHIFT_DURATION)
require(duration >= 0) { "Duration cannot be negative" }
val shiftType = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TYPE)
?: throw IllegalArgumentException("Shift type required")
val shiftUnits = values.getAsFloat(ShiftsEntry.COLUMN_SHIFT_UNIT)
require(shiftUnits >= 0) { "Units cannot be negative" }
val payRate = values.getAsFloat(ShiftsEntry.COLUMN_SHIFT_PAYRATE)
require(payRate >= 0) { "Pay rate cannot be negative" }
val totalPay = values.getAsFloat(ShiftsEntry.COLUMN_SHIFT_TOTALPAY)
require(totalPay >= 0) { "Total Pay cannot be negative" }
val breakMins = values.getAsInteger(ShiftsEntry.COLUMN_SHIFT_BREAK)
require(breakMins >= 0) { "Break cannot be negative" }
val database = mDbHelper!!.writableDatabase
val id = database.insert(ShiftsEntry.TABLE_NAME, null, values)
if (id == -1L) {
Log.e(LOG_TAG, "row failed $uri")
return null
}
context!!.contentResolver.notifyChange(uri, null)
return ContentUris.withAppendedId(uri, id)
}
override fun update(uri: Uri, contentValues: ContentValues?, selection: String?,
selectionArgs: Array<String>?): Int {
var selection = selection
var selectionArgs = selectionArgs
val match = sUriMatcher.match(uri)
return when (match) {
SHIFTS -> updateShift(uri, contentValues, selection, selectionArgs)
SHIFT_ID -> {
selection = ShiftsEntry._ID + "=?"
selectionArgs = arrayOf(ContentUris.parseId(uri).toString())
updateShift(uri, contentValues, selection, selectionArgs)
}
else -> throw IllegalArgumentException("Update is not supported for $uri")
}
}
private fun updateShift(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int {
if (values!!.containsKey(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION)) {
val description = values.getAsString(ShiftsEntry.COLUMN_SHIFT_DESCRIPTION)
?: throw IllegalArgumentException("description required")
}
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_DATE)) {
val date = values.getAsString(ShiftsEntry.COLUMN_SHIFT_DATE)
?: throw IllegalArgumentException("date required")
}
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_TIME_IN)) {
val timeIn = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TIME_IN)
?: throw IllegalArgumentException("time in required")
}
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_TIME_OUT)) {
val timeOut = values.getAsString(ShiftsEntry.COLUMN_SHIFT_TIME_OUT)
?: throw IllegalArgumentException("time out required")
}
if (values.containsKey(ShiftsEntry.COLUMN_SHIFT_BREAK)) {
val breaks = values.getAsString(ShiftsEntry.COLUMN_SHIFT_BREAK)
?: throw IllegalArgumentException("break required")
}
if (values.size() == 0) {
return 0
}
val database = mDbHelper!!.writableDatabase
val rowsUpdated = database.update(ShiftsEntry.TABLE_NAME, values, selection, selectionArgs)
if (rowsUpdated != 0) {
context!!.contentResolver.notifyChange(uri, null)
}
return rowsUpdated
}
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
var selection = selection
var selectionArgs = selectionArgs
val database = mDbHelper!!.writableDatabase
val rowsDeleted: Int
val match = sUriMatcher.match(uri)
when (match) {
SHIFTS -> rowsDeleted = database.delete(ShiftsEntry.TABLE_NAME, selection, selectionArgs)
SHIFT_ID -> {
selection = ShiftsEntry._ID + "=?"
selectionArgs = arrayOf(ContentUris.parseId(uri).toString())
rowsDeleted = database.delete(ShiftsEntry.TABLE_NAME, selection, selectionArgs)
}
else -> throw IllegalArgumentException("Deletion is not supported for $uri")
}
if (rowsDeleted != 0) {
context!!.contentResolver.notifyChange(uri, null)
}
return rowsDeleted
}
override fun getType(uri: Uri): String {
return when (val match = sUriMatcher.match(uri)) {
SHIFTS -> ShiftsEntry.CONTENT_LIST_TYPE
SHIFT_ID -> ShiftsEntry.CONTENT_ITEM_TYPE
else -> throw IllegalStateException("Unknown URI $uri with match $match")
}
}
companion object {
val LOG_TAG: String = ShiftProvider::class.java.simpleName
private const val SHIFTS = 100
private const val SHIFT_ID = 101
private val sUriMatcher = UriMatcher(UriMatcher.NO_MATCH)
init {
sUriMatcher.addURI(ShiftsContract.CONTENT_AUTHORITY, ShiftsContract.PATH_SHIFTS, SHIFTS)
sUriMatcher.addURI(ShiftsContract.CONTENT_AUTHORITY, ShiftsContract.PATH_SHIFTS + "/#", SHIFT_ID)
}
}
}

View File

@@ -0,0 +1,33 @@
package com.appttude.h_mal.farmr.data
import android.content.ContentResolver
import android.net.Uri
import android.provider.BaseColumns
/**
* Created by h_mal on 26/12/2017.
*/
object ShiftsContract {
const val CONTENT_AUTHORITY = "com.appttude.h_mal.farmr"
val BASE_CONTENT_URI = Uri.parse("content://$CONTENT_AUTHORITY")
const val PATH_SHIFTS = "shifts"
object ShiftsEntry : BaseColumns {
val CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, PATH_SHIFTS)
const val CONTENT_LIST_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_SHIFTS
const val CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_SHIFTS
const val TABLE_NAME = "shifts"
const val TABLE_NAME_EXPORT = "shiftsexport"
const val _ID = BaseColumns._ID
const val COLUMN_SHIFT_TYPE = "shifttype"
const val COLUMN_SHIFT_DESCRIPTION = "description"
const val COLUMN_SHIFT_DATE = "date"
const val COLUMN_SHIFT_TIME_IN = "timein"
const val COLUMN_SHIFT_TIME_OUT = "timeout"
const val COLUMN_SHIFT_BREAK = "break"
const val COLUMN_SHIFT_DURATION = "duration"
const val COLUMN_SHIFT_UNIT = "unit"
const val COLUMN_SHIFT_PAYRATE = "payrate"
const val COLUMN_SHIFT_TOTALPAY = "totalpay"
}
}

View File

@@ -0,0 +1,51 @@
package com.appttude.h_mal.farmr.data
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import com.appttude.h_mal.farmr.data.ShiftsContract.ShiftsEntry
/**
* Created by h_mal on 26/12/2017.
*/
class ShiftsDbHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
val SQL_CREATE_PRODUCTS_TABLE = ("CREATE TABLE " + ShiftsEntry.TABLE_NAME + " ("
+ ShiftsEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ ShiftsEntry.COLUMN_SHIFT_DESCRIPTION + " TEXT NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_DATE + " DATE NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_TIME_IN + " TIME NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_TIME_OUT + " TIME NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_BREAK + " INTEGER NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_DURATION + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_TYPE + " TEXT NOT NULL DEFAULT " + DEFAULT_TEXT + ", "
+ ShiftsEntry.COLUMN_SHIFT_UNIT + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_PAYRATE + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_TOTALPAY + " FLOAT NOT NULL DEFAULT 0)")
db.execSQL(SQL_CREATE_PRODUCTS_TABLE)
db.execSQL(SQL_CREATE_PRODUCTS_TABLE_2)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
if (oldVersion < newVersion) {
db.execSQL(SQL_CREATE_PRODUCTS_TABLE_2)
}
}
companion object {
private const val DATABASE_NAME = "shifts.db"
private const val DATABASE_VERSION = 4
private const val DEFAULT_TEXT = "Hourly"
private const val SQL_CREATE_PRODUCTS_TABLE_2 = ("CREATE TABLE " + ShiftsEntry.TABLE_NAME_EXPORT + " ("
+ ShiftsEntry.COLUMN_SHIFT_DESCRIPTION + " TEXT NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_DATE + " DATE NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_TIME_IN + " TIME NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_TIME_OUT + " TIME NOT NULL, "
+ ShiftsEntry.COLUMN_SHIFT_BREAK + " INTEGER NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_DURATION + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_TYPE + " TEXT NOT NULL DEFAULT " + DEFAULT_TEXT + ", "
+ ShiftsEntry.COLUMN_SHIFT_UNIT + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_PAYRATE + " FLOAT NOT NULL DEFAULT 0, "
+ ShiftsEntry.COLUMN_SHIFT_TOTALPAY + " FLOAT NOT NULL DEFAULT 0)")
}
}

View File

@@ -0,0 +1,14 @@
package com.appttude.h_mal.farmr.model
data class Shift(
val type: ShiftType,
val description: String,
val date: String,
val timeIn: String?,
val timeOut: String?,
val duration: Float?,
val breakMins: Int?,
val units: Float?,
val rateOfPay: Float,
val totalPay: Float
)

View File

@@ -0,0 +1,6 @@
package com.appttude.h_mal.farmr.model
enum class ShiftType(val type: String) {
HOURLY("Hourly"),
PIECE("Piece Rate")
}

View File

@@ -5,5 +5,5 @@
android:viewportWidth="24.0"> android:viewportWidth="24.0">
<path <path
android:fillColor="#FF000000" android:fillColor="#FF000000"
android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-.25 1.97,-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01.25,-1.97.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z" /> android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-0.25 1.97,-0.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z" />
</vector> </vector>

View File

@@ -2,13 +2,12 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
tools:context=".homeFragment">
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/recycler"> android:id="@+id/recycler">
</android.support.v7.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
</FrameLayout> </FrameLayout>

View File

@@ -41,7 +41,7 @@
android:textColor="#A2AAB0"/> android:textColor="#A2AAB0"/>
</RelativeLayout> </RelativeLayout>
<android.support.design.widget.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab1" android:id="@+id/fab1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -13,7 +13,7 @@
<LinearLayout <LinearLayout
android:layout_width="87dp" android:layout_width="87dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
android:orientation="vertical"> android:orientation="vertical">
@@ -101,7 +101,7 @@
android:id="@+id/location" android:id="@+id/location"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_below="@+id/date" android:layout_below="@+id/date"
android:maxLines="3" android:maxLines="3"
@@ -112,7 +112,7 @@
android:id="@+id/date" android:id="@+id/date"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_marginBottom="3dp" android:layout_marginBottom="3dp"
@@ -126,7 +126,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
app:srcCompat="@android:drawable/ic_menu_edit" /> app:srcCompat="@android:drawable/ic_menu_edit" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity" tools:context=".MainActivity"
@@ -7,7 +7,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:id="@+id/appbar" android:id="@+id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -18,7 +18,7 @@
android:paddingTop="@dimen/appbar_padding_top" android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay"> android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
@@ -28,9 +28,9 @@
app:popupTheme="@style/AppTheme.PopupOverlay" app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/app_name"> app:title="@string/app_name">
</android.support.v7.widget.Toolbar> </androidx.appcompat.widget.Toolbar>
</android.support.design.widget.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<FrameLayout <FrameLayout
android:layout_below="@id/appbar" android:layout_below="@id/appbar"
@@ -42,4 +42,4 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/container"> android:id="@+id/container">
</FrameLayout> </FrameLayout>
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,12 +1,16 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext {
kotlin_version = '1.9.0'
}
repositories { repositories {
google() google()
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.6.1' classpath 'com.android.tools.build:gradle:7.4.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

View File

@@ -9,6 +9,8 @@
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Tue Apr 28 17:08:04 BST 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

298
gradlew vendored
View File

@@ -1,74 +1,129 @@
#!/usr/bin/env bash #!/bin/sh
#
# Copyright <20> 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
############################################################################## ##############################################################################
## #
## Gradle start up script for UN*X # Gradle start up script for POSIX generated by Gradle.
## #
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions <20>$var<61>, <20>${var}<7D>, <20>${var:-default}<7D>, <20>${var+SET}<7D>,
# <20>${var#prefix}<7D>, <20>${var%suffix}<7D>, and <20>$( cmd )<29>;
# * compound commands having a testable exit status, especially <20>case<73>;
# * various built-in commands including <20>command<6E>, <20>set<65>, and <20>ulimit<69>.
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
############################################################################## ##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Attempt to set APP_HOME
DEFAULT_JVM_OPTS=""
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle" APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD=maximum
warn ( ) { warn () {
echo "$*" echo "$*"
} } >&2
die ( ) { die () {
echo echo
echo "$*" echo "$*"
echo echo
exit 1 exit 1
} } >&2
# OS specific support (must be 'true' or 'false'). # OS specific support (must be 'true' or 'false').
cygwin=false cygwin=false
msys=false msys=false
darwin=false darwin=false
case "`uname`" in nonstop=false
CYGWIN* ) case "$( uname )" in #(
cygwin=true CYGWIN* ) cygwin=true ;; #(
;; Darwin* ) darwin=true ;; #(
Darwin* ) MSYS* | MINGW* ) msys=true ;; #(
darwin=true NONSTOP* ) nonstop=true ;;
;;
MINGW* )
msys=true
;;
esac esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java" JAVACMD=$JAVA_HOME/jre/sh/java
else else
JAVACMD="$JAVA_HOME/bin/java" JAVACMD=$JAVA_HOME/bin/java
fi fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -77,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
else else
JAVACMD="java" JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
@@ -85,76 +140,95 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
MAX_FD_LIMIT=`ulimit -H -n` case $MAX_FD in #(
if [ $? -eq 0 ] ; then max*)
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD=$( ulimit -H -n ) ||
MAX_FD="$MAX_FD_LIMIT" warn "Could not query maximum file descriptor limit"
fi esac
ulimit -n $MAX_FD case $MAX_FD in #(
if [ $? -ne 0 ] ; then '' | soft) :;; #(
warn "Could not set maximum file descriptor limit: $MAX_FD" *)
fi ulimit -n "$MAX_FD" ||
else warn "Could not set maximum file descriptor limit to $MAX_FD"
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac esac
fi fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules # Collect all arguments for the java command, stacking in reverse order:
function splitJvmOpts() { # * args from the command line
JVM_OPTS=("$@") # * the main class name
} # * -classpath
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS # * -D...appname settings
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" # * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

53
gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@@ -8,20 +24,23 @@
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,34 +64,14 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell