From 40c8d4858b52a3ea1000dc1b16c6e5290ab11937 Mon Sep 17 00:00:00 2001 From: saif Date: Wed, 8 May 2024 16:43:34 +0500 Subject: [PATCH] first commit --- .gitignore | 15 + .idea/.gitignore | 3 + .idea/compiler.xml | 6 + .idea/deploymentTargetDropDown.xml | 10 + .idea/gradle.xml | 19 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/migrations.xml | 10 + .idea/misc.xml | 9 + app/.gitignore | 1 + app/build.gradle | 54 ++ app/proguard-rules.pro | 21 + .../ExampleInstrumentedTest.java | 26 + app/src/main/AndroidManifest.xml | 62 ++ .../qualitychecker/apiservice/ApiService.java | 76 +++ .../apiservice/ApiServiceFactory.java | 14 + .../apiservice/BooleanTypeAdapter.java | 27 + .../apiservice/RetrofitClient.java | 28 + .../qualitychecker/models/Dimension.java | 63 ++ .../qualitychecker/models/EmployeePhoto.java | 59 ++ .../models/InspectionCheckPoint.java | 42 ++ .../models/InspectionDefect.java | 31 + .../models/InspectionDimension.java | 31 + .../models/InspectionItemCheckPoint.java | 111 ++++ .../models/InspectionItemDefect.java | 64 ++ .../models/InspectionItemDimension.java | 96 +++ .../models/InspectionReport.java | 140 +++++ .../models/InspectionReportItem.java | 267 +++++++++ .../qualitychecker/models/ItemUnit.java | 37 ++ .../qualitychecker/models/Product.java | 141 +++++ .../models/SaveReportCallback.java | 6 + .../models/VoiceOfCustomer.java | 80 +++ .../service/InspectionReportService.java | 120 ++++ .../example/qualitychecker/store/Store.java | 229 ++++++++ .../ui/activities/HomeActivity.java | 169 ++++++ .../ui/activities/LoginActivity.java | 142 +++++ .../ui/activities/MainActivity.java | 104 ++++ .../ui/adapter/CheckPointAdapter.java | 231 ++++++++ .../ui/adapter/DimensionAdapter.java | 188 ++++++ .../ui/adapter/ItemDimensionAdapter.java | 62 ++ .../ui/adapter/ItemHistoryAdapter.java | 84 +++ .../ui/adapter/ReportAdapter.java | 81 +++ .../qualitychecker/ui/adapter/VocAdapter.java | 79 +++ .../ui/fragments/FirstStepFragment.java | 546 ++++++++++++++++++ .../ui/fragments/ForthStepFragment.java | 43 ++ .../ui/fragments/SecondStepFragment.java | 165 ++++++ .../ui/fragments/ThirdStepFragment.java | 291 ++++++++++ app/src/main/res/anim/slide_in_left.xml | 7 + app/src/main/res/anim/slide_in_right.xml | 7 + app/src/main/res/anim/slide_out_left.xml | 7 + app/src/main/res/anim/slide_out_right.xml | 7 + .../main/res/drawable/background_image.xml | 4 + app/src/main/res/drawable/failed_bg.xml | 5 + app/src/main/res/drawable/ic_add.xml | 5 + app/src/main/res/drawable/ic_check.xml | 5 + app/src/main/res/drawable/ic_close.xml | 5 + app/src/main/res/drawable/ic_delete.xml | 5 + .../res/drawable/ic_launcher_background.xml | 170 ++++++ .../res/drawable/ic_launcher_foreground.xml | 30 + app/src/main/res/drawable/ic_left.xml | 5 + app/src/main/res/drawable/ic_right.xml | 5 + app/src/main/res/drawable/ic_search.xml | 5 + app/src/main/res/drawable/image_picker.xml | 5 + app/src/main/res/drawable/passed_bg.xml | 5 + .../main/res/drawable/rounded_corners_bg.xml | 4 + app/src/main/res/drawable/scan.xml | 5 + app/src/main/res/drawable/utopia_svg_logo.xml | 73 +++ app/src/main/res/layout/activity_home.xml | 154 +++++ app/src/main/res/layout/activity_login.xml | 118 ++++ app/src/main/res/layout/activity_main.xml | 67 +++ app/src/main/res/layout/check_point.xml | 109 ++++ app/src/main/res/layout/dimension_dialog.xml | 36 ++ app/src/main/res/layout/dimension_item.xml | 57 ++ .../main/res/layout/fragment_first_step.xml | 373 ++++++++++++ .../main/res/layout/fragment_forth_step.xml | 186 ++++++ .../main/res/layout/fragment_second_step.xml | 187 ++++++ .../main/res/layout/fragment_third_step.xml | 434 ++++++++++++++ app/src/main/res/layout/item_dimension.xml | 46 ++ app/src/main/res/layout/item_history.xml | 13 + app/src/main/res/layout/item_history_item.xml | 62 ++ app/src/main/res/layout/report_item.xml | 95 +++ app/src/main/res/layout/voc_item.xml | 108 ++++ app/src/main/res/menu/menu.xml | 15 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 6 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 4338 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2757 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 6030 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 11199 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 17454 bytes .../main/res/navigation/navigation_graph.xml | 98 ++++ app/src/main/res/values-night/themes.xml | 7 + app/src/main/res/values/colors.xml | 12 + app/src/main/res/values/strings.xml | 10 + app/src/main/res/values/themes.xml | 31 + app/src/main/res/xml/backup_rules.xml | 13 + .../main/res/xml/data_extraction_rules.xml | 19 + .../main/res/xml/network_security_config.xml | 9 + .../qualitychecker/ExampleUnitTest.java | 17 + build.gradle | 4 + gradle.properties | 21 + gradle/libs.versions.toml | 22 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 185 ++++++ gradlew.bat | 89 +++ settings.gradle | 23 + 106 files changed, 7091 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/migrations.xml create mode 100644 .idea/misc.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/example/qualitychecker/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/example/qualitychecker/apiservice/ApiService.java create mode 100644 app/src/main/java/com/example/qualitychecker/apiservice/ApiServiceFactory.java create mode 100644 app/src/main/java/com/example/qualitychecker/apiservice/BooleanTypeAdapter.java create mode 100644 app/src/main/java/com/example/qualitychecker/apiservice/RetrofitClient.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/Dimension.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/EmployeePhoto.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/InspectionCheckPoint.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/InspectionDefect.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/InspectionDimension.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/InspectionItemCheckPoint.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/InspectionItemDefect.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/InspectionItemDimension.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/InspectionReport.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/InspectionReportItem.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/ItemUnit.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/Product.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/SaveReportCallback.java create mode 100644 app/src/main/java/com/example/qualitychecker/models/VoiceOfCustomer.java create mode 100644 app/src/main/java/com/example/qualitychecker/service/InspectionReportService.java create mode 100644 app/src/main/java/com/example/qualitychecker/store/Store.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/activities/HomeActivity.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/activities/LoginActivity.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/activities/MainActivity.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/adapter/CheckPointAdapter.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/adapter/DimensionAdapter.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/adapter/ItemDimensionAdapter.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/adapter/ItemHistoryAdapter.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/adapter/ReportAdapter.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/adapter/VocAdapter.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/fragments/FirstStepFragment.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/fragments/ForthStepFragment.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/fragments/SecondStepFragment.java create mode 100644 app/src/main/java/com/example/qualitychecker/ui/fragments/ThirdStepFragment.java create mode 100644 app/src/main/res/anim/slide_in_left.xml create mode 100644 app/src/main/res/anim/slide_in_right.xml create mode 100644 app/src/main/res/anim/slide_out_left.xml create mode 100644 app/src/main/res/anim/slide_out_right.xml create mode 100644 app/src/main/res/drawable/background_image.xml create mode 100644 app/src/main/res/drawable/failed_bg.xml create mode 100644 app/src/main/res/drawable/ic_add.xml create mode 100644 app/src/main/res/drawable/ic_check.xml create mode 100644 app/src/main/res/drawable/ic_close.xml create mode 100644 app/src/main/res/drawable/ic_delete.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_left.xml create mode 100644 app/src/main/res/drawable/ic_right.xml create mode 100644 app/src/main/res/drawable/ic_search.xml create mode 100644 app/src/main/res/drawable/image_picker.xml create mode 100644 app/src/main/res/drawable/passed_bg.xml create mode 100644 app/src/main/res/drawable/rounded_corners_bg.xml create mode 100644 app/src/main/res/drawable/scan.xml create mode 100644 app/src/main/res/drawable/utopia_svg_logo.xml create mode 100644 app/src/main/res/layout/activity_home.xml create mode 100644 app/src/main/res/layout/activity_login.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/check_point.xml create mode 100644 app/src/main/res/layout/dimension_dialog.xml create mode 100644 app/src/main/res/layout/dimension_item.xml create mode 100644 app/src/main/res/layout/fragment_first_step.xml create mode 100644 app/src/main/res/layout/fragment_forth_step.xml create mode 100644 app/src/main/res/layout/fragment_second_step.xml create mode 100644 app/src/main/res/layout/fragment_third_step.xml create mode 100644 app/src/main/res/layout/item_dimension.xml create mode 100644 app/src/main/res/layout/item_history.xml create mode 100644 app/src/main/res/layout/item_history_item.xml create mode 100644 app/src/main/res/layout/report_item.xml create mode 100644 app/src/main/res/layout/voc_item.xml create mode 100644 app/src/main/res/menu/menu.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/navigation/navigation_graph.xml create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/main/res/xml/backup_rules.xml create mode 100644 app/src/main/res/xml/data_extraction_rules.xml create mode 100644 app/src/main/res/xml/network_security_config.xml create mode 100644 app/src/test/java/com/example/qualitychecker/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..0c0c338 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..0897082 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..022ab29 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8978d23 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..a6439af --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,54 @@ +plugins { + alias(libs.plugins.androidApplication) +} + + +android { + namespace 'com.example.qualitychecker' + compileSdk 34 + + defaultConfig { + applicationId "com.example.qualitychecker" + minSdk 24 + targetSdk 34 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + + implementation libs.appcompat + implementation libs.material + implementation libs.activity + implementation libs.constraintlayout + testImplementation libs.junit + androidTestImplementation libs.ext.junit + androidTestImplementation libs.espresso.core + dependencies { + // Other dependencies + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation "androidx.navigation:navigation-fragment:2.4.0" + implementation "androidx.navigation:navigation-ui:2.4.0" + implementation 'androidx.lifecycle:lifecycle-viewmodel:2.4.0' + implementation 'androidx.lifecycle:lifecycle-livedata:2.4.0' + implementation 'com.github.bumptech.glide:glide:4.12.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' + implementation 'com.journeyapps:zxing-android-embedded:4.1.0' + } + +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/qualitychecker/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/qualitychecker/ExampleInstrumentedTest.java new file mode 100644 index 0000000..4720bb1 --- /dev/null +++ b/app/src/androidTest/java/com/example/qualitychecker/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.qualitychecker; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.example.qualitychecker", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a2160cd --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/apiservice/ApiService.java b/app/src/main/java/com/example/qualitychecker/apiservice/ApiService.java new file mode 100644 index 0000000..7d11b7c --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/apiservice/ApiService.java @@ -0,0 +1,76 @@ +package com.example.qualitychecker.apiservice; + +import com.example.qualitychecker.models.EmployeePhoto; +import com.example.qualitychecker.models.InspectionCheckPoint; +import com.example.qualitychecker.models.InspectionDefect; +import com.example.qualitychecker.models.InspectionDimension; +import com.example.qualitychecker.models.InspectionReport; +import com.example.qualitychecker.models.InspectionReportItem; +import com.example.qualitychecker.models.ItemUnit; +import com.example.qualitychecker.models.Product; +import com.example.qualitychecker.models.VoiceOfCustomer; + +import java.util.List; + +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Path; +import retrofit2.http.Query; + +public interface ApiService { + + @GET("rest/uic/inspection-report") + Call> fetchAllReports(); + + @GET("rest/uic/inspection-report/{id}") + Call fetchReport( + @Path("id") long id + ); + + @POST("rest/authentication/authenticate-user") + Call isUserAuthenticated( + @Query("username") String username, + @Query("password") String password, + @Query("roles") String[] roles + ); + + @POST("rest/uic/inspection-report") + Call saveInspectionReport( + @Body InspectionReport inspectionReport + ); + + @GET("rest/uic/cosmos-products/find-by-sku") + Call> fetchProductBySku( + @Query("sku") String sku + ); + + @GET("rest/uic/inspection-report/checkpoints") + Call> fetchCheckPoints(); + + @GET( "rest/uic/inspection-report/defects" ) + Call> fetchDefects(); + + @GET( "rest/uic/inspection-report/dimensions" ) + Call> fetchDimensions(); + + @GET( "rest/hrms/employees/attendance") + Call fetchEmployeePhoto( @Query("username") String username ); + + @GET("rest/cosmos/amazon-voc") + Call> fetchVocs( @Query("asin") String asin ); + + @GET( "rest/uic/cosmos-products/find-by-fnsku") + Call fetchByFnsku( + @Query("fnsku") String fnsku + ); + + @GET( "rest/uic/inspection-report/inspection-items-logs" ) + Call> fetchItemsLogs( + @Query("sku") String sku + ); + + @GET( "rest/uic/items/units" ) + Call> fetchItemUnits(); +} diff --git a/app/src/main/java/com/example/qualitychecker/apiservice/ApiServiceFactory.java b/app/src/main/java/com/example/qualitychecker/apiservice/ApiServiceFactory.java new file mode 100644 index 0000000..07f8037 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/apiservice/ApiServiceFactory.java @@ -0,0 +1,14 @@ +package com.example.qualitychecker.apiservice; + +import retrofit2.Retrofit; + +public class ApiServiceFactory { + private static ApiService apiService; + public synchronized static ApiService getApiService() { + if ( apiService == null ) { + Retrofit retrofit = RetrofitClient.getClient(); + apiService = retrofit.create( ApiService.class ); + } + return apiService; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/apiservice/BooleanTypeAdapter.java b/app/src/main/java/com/example/qualitychecker/apiservice/BooleanTypeAdapter.java new file mode 100644 index 0000000..5b7b1a3 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/apiservice/BooleanTypeAdapter.java @@ -0,0 +1,27 @@ +package com.example.qualitychecker.apiservice; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; + +public class BooleanTypeAdapter extends TypeAdapter { + @Override + public Boolean read(JsonReader in) throws IOException { + JsonToken token = in.peek(); + if (token == JsonToken.BOOLEAN) { + return in.nextBoolean(); + } else if (token == JsonToken.STRING) { + String value = in.nextString(); + return Boolean.parseBoolean(value); + } + return null; + } + + @Override + public void write(JsonWriter out, Boolean value) throws IOException { + out.value(value); + } +} diff --git a/app/src/main/java/com/example/qualitychecker/apiservice/RetrofitClient.java b/app/src/main/java/com/example/qualitychecker/apiservice/RetrofitClient.java new file mode 100644 index 0000000..0bc8701 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/apiservice/RetrofitClient.java @@ -0,0 +1,28 @@ +package com.example.qualitychecker.apiservice; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class RetrofitClient { + + private final static String BASE_URL = "http://192.168.91.16:8080/uind/"; + private static Retrofit retrofit; + + public synchronized static Retrofit getClient() { + + Gson gson = new GsonBuilder() + .registerTypeAdapter(Boolean.class, new BooleanTypeAdapter()) + .create(); + + if ( retrofit == null ) { + retrofit = new Retrofit.Builder() + .baseUrl( BASE_URL ) + .addConverterFactory( GsonConverterFactory.create( gson ) ) + .build(); + } + return retrofit; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/Dimension.java b/app/src/main/java/com/example/qualitychecker/models/Dimension.java new file mode 100644 index 0000000..6164cdd --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/Dimension.java @@ -0,0 +1,63 @@ +package com.example.qualitychecker.models; + +public class Dimension { + + private String type; + private float actual; + private float required; + private float difference; + private String unit; + + public Dimension(){ + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public float getActual() { + return actual; + } + + public void setActual(float actual) { + this.actual = actual; + } + + public float getRequired() { + return required; + } + + public void setRequired(float required) { + this.required = required; + } + + public float getDifference() { + return difference; + } + + public void setDifference(float difference) { + this.difference = difference; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + @Override + public String toString() { + return "Dimension{" + + "type='" + type + '\'' + + ", actual=" + actual + + ", required=" + required + + ", difference=" + difference + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/EmployeePhoto.java b/app/src/main/java/com/example/qualitychecker/models/EmployeePhoto.java new file mode 100644 index 0000000..b99003e --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/EmployeePhoto.java @@ -0,0 +1,59 @@ +package com.example.qualitychecker.models; + + +public class EmployeePhoto { + private long id; + private long employeeId; + private String photoBlob; + private String name; + + public EmployeePhoto() { + } + + public EmployeePhoto( long employeeId, String photoBlob ) { + this.employeeId = employeeId; + this.photoBlob = photoBlob; + } + + public long getId() { + return id; + } + + public void setId( long id ) { + this.id = id; + } + + public long getEmployeeId() { + return employeeId; + } + + public void setEmployeeId( long employeeId ) { + this.employeeId = employeeId; + } + + public String getPhotoBlob() { + return photoBlob; + } + + public void setPhotoBlob( String photoBlob ) { + this.photoBlob = photoBlob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "EmployeePhoto{" + + "id=" + id + + ", employeeId=" + employeeId + + ", photoBlob='" + photoBlob + '\'' + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/InspectionCheckPoint.java b/app/src/main/java/com/example/qualitychecker/models/InspectionCheckPoint.java new file mode 100644 index 0000000..179441e --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/InspectionCheckPoint.java @@ -0,0 +1,42 @@ +package com.example.qualitychecker.models; + + +public class InspectionCheckPoint { + + private long id; + private String title; + private String category; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + @Override + public String toString() { + return "InspectionCheckPoint{" + + "id=" + id + + ", title='" + title + '\'' + + ", category='" + category + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/InspectionDefect.java b/app/src/main/java/com/example/qualitychecker/models/InspectionDefect.java new file mode 100644 index 0000000..4825d2e --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/InspectionDefect.java @@ -0,0 +1,31 @@ +package com.example.qualitychecker.models; + +public class InspectionDefect { + + private String category; + private String defect; + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getDefect() { + return defect; + } + + public void setDefect(String defect) { + this.defect = defect; + } + + @Override + public String toString() { + return "InspectionDefect{" + + "category='" + category + '\'' + + ", defect='" + defect + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/InspectionDimension.java b/app/src/main/java/com/example/qualitychecker/models/InspectionDimension.java new file mode 100644 index 0000000..4942ac5 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/InspectionDimension.java @@ -0,0 +1,31 @@ +package com.example.qualitychecker.models; + +public class InspectionDimension { + + private long id; + private String title; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public String toString() { + return "InspectionDimension{" + + "id=" + id + + ", title='" + title + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/InspectionItemCheckPoint.java b/app/src/main/java/com/example/qualitychecker/models/InspectionItemCheckPoint.java new file mode 100644 index 0000000..f19dd14 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/InspectionItemCheckPoint.java @@ -0,0 +1,111 @@ +package com.example.qualitychecker.models; + +import java.util.Arrays; + +public class InspectionItemCheckPoint { + + private long id; + private long inspectionItemId; + private String title; + private boolean checked; + private String remarks; + // wrapper + private String defectSeverity; + private InspectionItemDefect defect; + private byte[] file; + private String imagePath; + + private String defectTitle; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public boolean getChecked() { + return checked; + } + + public void setChecked(boolean checked) { + this.checked = checked; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public long getInspectionItemId() { + return inspectionItemId; + } + + public void setInspectionItemId(long inspectionItemId) { + this.inspectionItemId = inspectionItemId; + } + + public byte[] getFile() { + return file; + } + + public void setFile(byte[] file) { + this.file = file; + } + + public String getDefectSeverity() { + return defectSeverity; + } + + public void setDefectSeverity(String defectSeverity) { + this.defectSeverity = defectSeverity; + } + + public void setDefect(InspectionItemDefect defect) { + this.defect = defect; + } + + public String getDefectTitle() { + return defectTitle; + } + + public void setDefectTitle(String defectTitle) { + this.defectTitle = defectTitle; + } + + public String getImagePath() { + return imagePath; + } + + public void setImagePath(String imagePath) { + this.imagePath = imagePath; + } + + @Override + public String toString() { + return "InspectionItemCheckPoint{" + + "id=" + id + + ", inspectionItemId=" + inspectionItemId + + ", title='" + title + '\'' + + ", checked=" + checked + + ", remarks='" + remarks + '\'' + + ", defectSeverity='" + defectSeverity + '\'' + + ", defect=" + defect + + ", file=" + Arrays.toString(file) + + ", imagePath='" + imagePath + '\'' + + ", defectTitle='" + defectTitle + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/InspectionItemDefect.java b/app/src/main/java/com/example/qualitychecker/models/InspectionItemDefect.java new file mode 100644 index 0000000..94348d4 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/InspectionItemDefect.java @@ -0,0 +1,64 @@ +package com.example.qualitychecker.models; + +import java.util.Arrays; + +public class InspectionItemDefect { + + private long id; + private long cpId; + private String title; + private String defectSeverity; + // wrapper + private byte[] file; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public long getCpId() { + return cpId; + } + + public void setCpId(long cpId) { + this.cpId = cpId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDefectSeverity() { + return defectSeverity; + } + + public void setDefectSeverity(String defectSeverity) { + this.defectSeverity = defectSeverity; + } + + public byte[] getFile() { + return file; + } + + public void setFile(byte[] file) { + this.file = file; + } + + + @Override + public String toString() { + return "InspectionItemDefect{" + + "id=" + id + + ", cpId=" + cpId + + ", title='" + title + '\'' + + ", file=" + Arrays.toString(file) + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/InspectionItemDimension.java b/app/src/main/java/com/example/qualitychecker/models/InspectionItemDimension.java new file mode 100644 index 0000000..ed63646 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/InspectionItemDimension.java @@ -0,0 +1,96 @@ +package com.example.qualitychecker.models; + + +import androidx.annotation.NonNull; + +import java.util.Arrays; + +public class InspectionItemDimension { + + private long id; + private long inspectionItemId; + private String type; + private float actual; + private float required; + private float difference; + private String unit; + + public InspectionItemDimension() { + } + public InspectionItemDimension(String type, float actual, float required, float difference, String unit) { + this.type = type; + this.actual = actual; + this.required = required; + this.difference = difference; + this.unit = unit; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public long getInspectionItemId() { + return inspectionItemId; + } + + public void setInspectionItemId(long inspectionItemId) { + this.inspectionItemId = inspectionItemId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public float getActual() { + return actual; + } + + public void setActual(float actual) { + this.actual = actual; + } + + public float getRequired() { + return required; + } + + public void setRequired(float required) { + this.required = required; + } + + public float getDifference() { + return difference; + } + + public void setDifference(float difference) { + this.difference = difference; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + @Override + public String toString() { + return "InspectionItemDimension{" + + "id=" + id + + ", inspectionItemId=" + inspectionItemId + + ", type='" + type + '\'' + + ", actual=" + actual + + ", required=" + required + + ", difference=" + difference + + ", unit='" + unit + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/InspectionReport.java b/app/src/main/java/com/example/qualitychecker/models/InspectionReport.java new file mode 100644 index 0000000..27d7864 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/InspectionReport.java @@ -0,0 +1,140 @@ +package com.example.qualitychecker.models; + +import androidx.annotation.NonNull; +import java.util.List; + +public class InspectionReport { + + private long id; + private boolean fri; + private String code; + private String generatedBy; + private String generatedAt; + private long siteId; + private long floorId; + private long departmentId; + private long functionId; + private String generalRemarks; + private String reportResult; + + // wrapper + List items; + + public InspectionReport(){ + this.fri = true; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getGeneratedBy() { + return generatedBy; + } + + public void setGeneratedBy(String generatedBy) { + this.generatedBy = generatedBy; + } + + public String getGeneratedAt() { + return generatedAt; + } + + public void setGeneratedAt(String generatedAt) { + this.generatedAt = generatedAt; + } + + public long getSiteId() { + return siteId; + } + + public void setSiteId(long siteId) { + this.siteId = siteId; + } + + public long getFloorId() { + return floorId; + } + + public void setFloorId(long floorId) { + this.floorId = floorId; + } + + public long getDepartmentId() { + return departmentId; + } + + public void setDepartmentId(long departmentId) { + this.departmentId = departmentId; + } + + public long getFunctionId() { + return functionId; + } + + public void setFunctionId(long functionId) { + this.functionId = functionId; + } + + public String getGeneralRemarks() { + return generalRemarks; + } + + public void setGeneralRemarks(String generalRemarks) { + this.generalRemarks = generalRemarks; + } + + public String getReportResult() { + return reportResult; + } + + public void setReportResult(String reportResult) { + this.reportResult = reportResult; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public boolean getFri() { + return fri; + } + + public void setFri(boolean fri) { + this.fri = fri; + } + + @NonNull + @Override + public String toString() { + return "InspectionReport{" + + "id=" + id + + ", code='" + code + '\'' + + ", generatedBy='" + generatedBy + '\'' + + ", generatedAt=" + generatedAt + + ", siteId=" + siteId + + ", floorId=" + floorId + + ", departmentId=" + departmentId + + ", functionId=" + functionId + + ", generalRemarks='" + generalRemarks + '\'' + + ", reportResult='" + reportResult + '\'' + + ", items=" + items + + '}'; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/models/InspectionReportItem.java b/app/src/main/java/com/example/qualitychecker/models/InspectionReportItem.java new file mode 100644 index 0000000..a8b6ae5 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/InspectionReportItem.java @@ -0,0 +1,267 @@ +package com.example.qualitychecker.models; + +import androidx.annotation.NonNull; + +import java.util.List; + +public class InspectionReportItem { + + private long id; + private long reportId; + private String asin; + private String parentAsin; + private String marketplace; + private String sku; + private String title; + private String hsCode; + private String modelNumber; + private long itemPerBox; + private String smColor; + private String smSize; + private String smItemName; + private String orderNumber; + private String article; + private float totalPresentPieces; + private float totalPresentPacks; + private float totalPresentCartons; + // sqrt( totalPresentCartons ) + private float cartonsSelected; + private float packsSelected; + private float piecesSelected; + private String packingDetails; + private String sampleSize; + private String dateAdded; + // wrapper + private List checkPoints; + private List dimensions; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public long getReportId() { + return reportId; + } + + public void setReportId(long reportId) { + this.reportId = reportId; + } + + public String getAsin() { + return asin; + } + + public void setAsin(String asin) { + this.asin = asin; + } + + public String getParentAsin() { + return parentAsin; + } + + public void setParentAsin(String parentAsin) { + this.parentAsin = parentAsin; + } + + public String getMarketplace() { + return marketplace; + } + + public void setMarketplace(String marketplace) { + this.marketplace = marketplace; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getHsCode() { + return hsCode; + } + + public void setHsCode(String hsCode) { + this.hsCode = hsCode; + } + + public String getModelNumber() { + return modelNumber; + } + + public void setModelNumber(String modelNumber) { + this.modelNumber = modelNumber; + } + + public long getItemPerBox() { + return itemPerBox; + } + + public void setItemPerBox(long itemPerBox) { + this.itemPerBox = itemPerBox; + } + + public String getSmColor() { + return smColor; + } + + public void setSmColor(String smColor) { + this.smColor = smColor; + } + + public String getSmSize() { + return smSize; + } + + public void setSmSize(String smSize) { + this.smSize = smSize; + } + + public String getSmItemName() { + return smItemName; + } + + public void setSmItemName(String smItemName) { + this.smItemName = smItemName; + } + + public List getCheckPoints() { + return checkPoints; + } + + public void setCheckPoints(List checkPoints) { + this.checkPoints = checkPoints; + } + + public List getDimensions() { + return dimensions; + } + + public void setDimensions(List dimensions) { + this.dimensions = dimensions; + } + + public String getOrderNumber() { + return orderNumber; + } + + public void setOrderNumber(String orderNumber) { + this.orderNumber = orderNumber; + } + + public String getArticle() { + return article; + } + + public void setArticle(String article) { + this.article = article; + } + + public float getTotalPresentPieces() { + return totalPresentPieces; + } + + public void setTotalPresentPieces(float totalPresentPieces) { + this.totalPresentPieces = totalPresentPieces; + } + + public float getTotalPresentPacks() { + return totalPresentPacks; + } + + public void setTotalPresentPacks(float totalPresentPacks) { + this.totalPresentPacks = totalPresentPacks; + } + + public float getTotalPresentCartons() { + return totalPresentCartons; + } + + public void setTotalPresentCartons(float totalPresentCartons) { + this.totalPresentCartons = totalPresentCartons; + } + + public float getCartonsSelected() { + return cartonsSelected; + } + + public void setCartonsSelected(float cartonsSelected) { + this.cartonsSelected = cartonsSelected; + } + + public float getPacksSelected() { + return packsSelected; + } + + public void setPacksSelected(float packsSelected) { + this.packsSelected = packsSelected; + } + + public String getPackingDetails() { + return packingDetails; + } + + public void setPackingDetails(String packingDetails) { + this.packingDetails = packingDetails; + } + + public float getPiecesSelected() { + return piecesSelected; + } + + public void setPiecesSelected(float piecesSelected) { + this.piecesSelected = piecesSelected; + } + + public String getSampleSize() { + return sampleSize; + } + + public void setSampleSize(String sampleSize) { + this.sampleSize = sampleSize; + } + + public String getDateAdded() { + return dateAdded; + } + + public void setDateAdded(String dateAdded) { + this.dateAdded = dateAdded; + } + + @NonNull + @Override + public String toString() { + return "InspectionAuditReportItem{" + + "id=" + id + + ", reportId=" + reportId + + ", asin='" + asin + '\'' + + ", parentAsin='" + parentAsin + '\'' + + ", marketplace='" + marketplace + '\'' + + ", sku='" + sku + '\'' + + ", title='" + title + '\'' + + ", hsCode='" + hsCode + '\'' + + ", modelNumber='" + modelNumber + '\'' + + ", itemPerBox=" + itemPerBox + + ", smColor='" + smColor + '\'' + + ", smSize='" + smSize + '\'' + + ", smItemName='" + smItemName + '\'' + + ", checkPoints=" + checkPoints + + ", dimensions=" + dimensions + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/ItemUnit.java b/app/src/main/java/com/example/qualitychecker/models/ItemUnit.java new file mode 100644 index 0000000..cb879cd --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/ItemUnit.java @@ -0,0 +1,37 @@ +package com.example.qualitychecker.models; + +public class ItemUnit { + private long id; + private String title; + + public ItemUnit() { + } + + public ItemUnit( String title ) { + this.title = title; + } + + public long getId() { + return id; + } + + public void setId( long id ) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle( String title ) { + this.title = title; + } + + @Override + public String toString() { + return "ItemUnit{" + + "id=" + id + + ", title='" + title + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/models/Product.java b/app/src/main/java/com/example/qualitychecker/models/Product.java new file mode 100644 index 0000000..15ded8f --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/Product.java @@ -0,0 +1,141 @@ +package com.example.qualitychecker.models; + +public class Product { + + private String asin; + private String parentAsin; + private String marketplace; + private String sku; + private String title; + private String hsCode; + private String modelNumber; + private long itemPerBox; + private String smColor; + private String smSize; + private String smItemName; + private long itemPerPack; + private long inventory; + + public String getAsin() { + return asin; + } + + public void setAsin(String asin) { + this.asin = asin; + } + + public String getParentAsin() { + return parentAsin; + } + + public void setParentAsin(String parentAsin) { + this.parentAsin = parentAsin; + } + + public String getMarketplace() { + return marketplace; + } + + public void setMarketplace(String marketplace) { + this.marketplace = marketplace; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getHsCode() { + return hsCode; + } + + public void setHsCode(String hsCode) { + this.hsCode = hsCode; + } + + public String getModelNumber() { + return modelNumber; + } + + public void setModelNumber(String modelNumber) { + this.modelNumber = modelNumber; + } + + public long getItemPerBox() { + return itemPerBox; + } + + public void setItemPerBox(long itemPerBox) { + this.itemPerBox = itemPerBox; + } + + public String getSmColor() { + return smColor; + } + + public void setSmColor(String smColor) { + this.smColor = smColor; + } + + public String getSmSize() { + return smSize; + } + + public void setSmSize(String smSize) { + this.smSize = smSize; + } + + public String getSmItemName() { + return smItemName; + } + + public void setSmItemName(String smItemName) { + this.smItemName = smItemName; + } + + public long getItemPerPack() { + return itemPerPack; + } + + public void setItemPerPack(long itemPerPack) { + this.itemPerPack = itemPerPack; + } + + public long getInventory() { + return inventory; + } + + public void setInventory(long inventory) { + this.inventory = inventory; + } + + @Override + public String toString() { + return "Product{" + + "asin='" + asin + '\'' + + ", parentAsin='" + parentAsin + '\'' + + ", marketplace='" + marketplace + '\'' + + ", sku='" + sku + '\'' + + ", title='" + title + '\'' + + ", hsCode='" + hsCode + '\'' + + ", modelNumber='" + modelNumber + '\'' + + ", itemPerBox=" + itemPerBox + + ", smColor='" + smColor + '\'' + + ", smSize='" + smSize + '\'' + + ", smItemName='" + smItemName + '\'' + + ", itemPerPack=" + itemPerPack + + ", inventory=" + inventory + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/models/SaveReportCallback.java b/app/src/main/java/com/example/qualitychecker/models/SaveReportCallback.java new file mode 100644 index 0000000..56279d3 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/SaveReportCallback.java @@ -0,0 +1,6 @@ +package com.example.qualitychecker.models; + +public interface SaveReportCallback { + void onSuccess(); + void onFailure(Throwable throwable); +} \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/models/VoiceOfCustomer.java b/app/src/main/java/com/example/qualitychecker/models/VoiceOfCustomer.java new file mode 100644 index 0000000..b761495 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/models/VoiceOfCustomer.java @@ -0,0 +1,80 @@ +package com.example.qualitychecker.models; + +public class VoiceOfCustomer { + private String mskus; + private String marketplace; + private String itemName; + private String fnsku; + private String pcxHealth; + private String imageUrl; + private String asin; + + public String getFnsku() { + return fnsku; + } + + public void setFnsku(String fnsku) { + this.fnsku = fnsku; + } + + public String getPcxHealth() { + return pcxHealth; + } + + public void setPcxHealth(String pcxHealth) { + this.pcxHealth = pcxHealth; + } + + public String getMarketplace() { + return marketplace; + } + + public void setMarketplace(String marketplace) { + this.marketplace = marketplace; + } + + public String getAsin() { + return asin; + } + + public void setAsin(String asin) { + this.asin = asin; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public String getMskus() { + return mskus; + } + + public void setMskus(String mskus) { + this.mskus = mskus; + } + + + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + + @Override + public String toString() { + return "VoiceOfCustomer{" + + "mskus='" + mskus + '\'' + + ", marketplace='" + marketplace + '\'' + + ", itemName='" + itemName + '\'' + + ", fnsku='" + fnsku + '\'' + + ", pcxHealth='" + pcxHealth + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/service/InspectionReportService.java b/app/src/main/java/com/example/qualitychecker/service/InspectionReportService.java new file mode 100644 index 0000000..6869957 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/service/InspectionReportService.java @@ -0,0 +1,120 @@ +package com.example.qualitychecker.service; + +import androidx.annotation.NonNull; + +import com.example.qualitychecker.apiservice.ApiService; +import com.example.qualitychecker.apiservice.ApiServiceFactory; +import com.example.qualitychecker.models.InspectionItemCheckPoint; +import com.example.qualitychecker.models.InspectionItemDefect; +import com.example.qualitychecker.models.InspectionReport; +import com.example.qualitychecker.models.SaveReportCallback; +import com.example.qualitychecker.store.Store; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class InspectionReportService { + + private static InspectionReportService instance; + private ApiService apiService; + private List defectTypes; + private List dimensionTypes; + private List reportResult; + private Store store; + + // singleton instance + public synchronized static InspectionReportService getInstance(){ + if( instance == null ){ + instance = new InspectionReportService(); + } + return instance; + } + + // initialize api service + { + apiService = ApiServiceFactory.getApiService(); + defectTypes = Arrays.asList( "CRITICAL","MINOR","MAJOR" ); + dimensionTypes = Arrays.asList( "LENGTH", "WIDTH", "DROP" ); + reportResult = Arrays.asList("PASSED","FAILED"); + store = Store.getInstance(); + } + + public void isUserAuthenticated( String username, + String password, + String[] roles, + Callback callback){ + + + apiService.isUserAuthenticated(username, password, roles).enqueue( + new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + callback.onResponse(call, response); + } else { + // Handle error + callback.onFailure(call, new Throwable("Failed to authenticate user")); + } + } + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + // Handle failure + callback.onFailure(call, t); + } + }); + } + + public List getDefectTypes(){ + return defectTypes; + } + public List getDimensionTypes(){return dimensionTypes;} + + public List getReportResult() { + return reportResult; + } + + public void setReportResult(List reportResult) { + this.reportResult = reportResult; + } + + public void saveReport(InspectionReport inspectionReport , SaveReportCallback callback){ + + if( Objects.nonNull( inspectionReport ) && inspectionReport.getItems().get(0).getSku() != null && inspectionReport.getItems() != null && + ! inspectionReport.getItems().isEmpty() && + ! inspectionReport.getItems().get(0).getCheckPoints().isEmpty() ){ + // populate defects in cp + for( InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints() ){ + InspectionItemDefect defect = new InspectionItemDefect(); + defect.setDefectSeverity(itemCp.getDefectSeverity()); + defect.setTitle( itemCp.getDefectTitle() ); + itemCp.setDefect( defect ); + } + // post object + apiService.saveInspectionReport( inspectionReport ).enqueue( + new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + callback.onSuccess(); + } else { + callback.onFailure(new Exception("API call failed with status code: " + response.code())); + } + } + @Override + public void onFailure(Call call, Throwable t) { + callback.onFailure( t ); + } + } + ); + } else { + callback.onFailure( new Exception("Please Fill the required Fields..") ); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/store/Store.java b/app/src/main/java/com/example/qualitychecker/store/Store.java new file mode 100644 index 0000000..243187e --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/store/Store.java @@ -0,0 +1,229 @@ +package com.example.qualitychecker.store; + +import com.example.qualitychecker.apiservice.ApiService; +import com.example.qualitychecker.apiservice.ApiServiceFactory; +import com.example.qualitychecker.models.Dimension; +import com.example.qualitychecker.models.EmployeePhoto; +import com.example.qualitychecker.models.InspectionCheckPoint; +import com.example.qualitychecker.models.InspectionDefect; +import com.example.qualitychecker.models.InspectionDimension; +import com.example.qualitychecker.models.InspectionItemCheckPoint; +import com.example.qualitychecker.models.InspectionItemDimension; +import com.example.qualitychecker.models.InspectionReport; +import com.example.qualitychecker.models.InspectionReportItem; +import com.example.qualitychecker.models.ItemUnit; +import com.example.qualitychecker.models.Product; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class Store { + + private static Store instance; + private InspectionReport report; + private ApiService apiService; + private List checkPoints; + private List defects; + private List dimensionList; + private List dimensions; + private List products; + private EmployeePhoto employeePhoto; + private List itemUnits; + + private Store(){ + } + + public static synchronized Store getInstance(){ + if( instance == null ){ + instance = new Store(); + } + return instance; + } + + public synchronized void initializeNewReport() { + checkPoints = new ArrayList<>(); + defects = new ArrayList<>(); + dimensions = new ArrayList<>(); + products = new ArrayList<>(); + itemUnits = new ArrayList<>(); + dimensionList = new ArrayList<>(); + apiService = ApiServiceFactory.getApiService(); + report = new InspectionReport(); + InspectionReportItem item = new InspectionReportItem(); + item.setDimensions( new ArrayList<>() ); + report.setItems(Collections.singletonList( item )); + + apiService.fetchCheckPoints().enqueue( + new Callback>() { + @Override + public void onResponse( Call> call, + Response> response) { + if( response.isSuccessful() && response.body() != null ){ + checkPoints = response.body() ; + } + } + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + + apiService.fetchDefects().enqueue( + new Callback>() { + @Override + public void onResponse( Call> call, + Response> response) { + if( response.isSuccessful() && response.body() != null ){ + defects = response.body(); + } + } + @Override + public void onFailure( Call> call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + + + apiService.fetchCheckPoints().enqueue( + new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + + if( response.isSuccessful() && response.body() != null ){ + List itemCp = new ArrayList<>(); + for( InspectionCheckPoint cp : response.body() ){ + InspectionItemCheckPoint icp = new InspectionItemCheckPoint(); + icp.setTitle( cp.getTitle() ); + icp.setDefectSeverity("MINOR"); + icp.setChecked( false ); + icp.setRemarks(""); + itemCp.add( icp ); + } + report.getItems().get( 0 ).setCheckPoints( itemCp ); + } + } + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + + apiService.fetchItemUnits().enqueue( + new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + if( response.isSuccessful() && response.body() != null ){ + System.out.println( response.body() ); + itemUnits = response.body(); + } + } + + @Override + public void onFailure(Call> call, + Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + + apiService.fetchDimensions().enqueue( + new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if( response.isSuccessful() && response.body() != null ){ + dimensionList = response.body(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + } + + public InspectionReport getReport() { + return report; + } + + public void setReport(InspectionReport report) { + this.report = report; + } + + public List getCheckPoints() { + return checkPoints; + } + + public List getDefects() { + return defects; + } + + public List getDimensions() { + return dimensions; + } + + public void setDimensions(List dimensions) { + this.dimensions = dimensions; + } + + public List getProducts() { + return products; + } + + public void setProducts(List products) { + this.products = products; + } + + public EmployeePhoto getEmployeePhoto() { + return employeePhoto; + } + + public void setEmployeePhoto(EmployeePhoto employeePhoto) { + this.employeePhoto = employeePhoto; + } + + public List getItemUnits() { + return itemUnits.stream().map( ItemUnit::getTitle ).collect(Collectors.toList()); + } + + public void setItemUnits(List itemUnits) { + this.itemUnits = itemUnits; + } + + public String getProfileImage( ) { + if( employeePhoto != null ){ + return "https://portal.utopiaindustries.pk/uind/employee-photo/" + employeePhoto.getEmployeeId() +".jpeg"; + } + return ""; + } + + public List getDimensionList() { + return dimensionList.stream().map( InspectionDimension::getTitle ).collect(Collectors.toList()); + } + + public void setDimensionList(List dimensionList) { + this.dimensionList = dimensionList; + } + + @Override + public String toString() { + return "Store{" + + "report=" + report + + ", apiService=" + apiService + + ", checkPoints=" + checkPoints + + ", defects=" + defects + + '}'; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/activities/HomeActivity.java b/app/src/main/java/com/example/qualitychecker/ui/activities/HomeActivity.java new file mode 100644 index 0000000..84a1226 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/activities/HomeActivity.java @@ -0,0 +1,169 @@ +package com.example.qualitychecker.ui.activities; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.example.qualitychecker.R; +import com.example.qualitychecker.apiservice.ApiService; +import com.example.qualitychecker.apiservice.ApiServiceFactory; +import com.example.qualitychecker.models.EmployeePhoto; +import com.example.qualitychecker.models.InspectionReport; +import com.example.qualitychecker.store.Store; +import com.example.qualitychecker.ui.adapter.ReportAdapter; + +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class HomeActivity extends AppCompatActivity implements View.OnClickListener { + + private Button createReportBtn,refreshReportsBtn,logoutBtn; + private RecyclerView recyclerView; + private ApiService apiService; + private TextView usernameTitle; + private ImageView profileImage; + private Store store; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + if( ! isNetworkConnected() ){ + Toast.makeText( this, "No Internet Connection", Toast.LENGTH_LONG ).show(); + } + setContentView(R.layout.activity_home); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); + + // initialize views + store = Store.getInstance(); + apiService = ApiServiceFactory.getApiService(); + createReportBtn = findViewById( R.id.create_report_btn ); + refreshReportsBtn = findViewById( R.id.refresh_btn ); + logoutBtn = findViewById( R.id.logout_btn ); + recyclerView = findViewById( R.id.reports_recyclerview ); + usernameTitle = findViewById( R.id.username_title ); + profileImage = findViewById( R.id.profile_image ); + + refreshReportsBtn.setOnClickListener( this ); + createReportBtn.setOnClickListener( this ); + logoutBtn.setOnClickListener( this ); + + recyclerView.setLayoutManager( new LinearLayoutManager( this ) ); + + updateProfileImage(); + refreshReportData(); + } + + private void refreshReportData(){ + apiService.fetchAllReports().enqueue( + new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if( response.isSuccessful() && response.body() != null ){ + System.out.println( response.body() ); + ReportAdapter adapter = new ReportAdapter( response.body() ); + recyclerView.setAdapter( adapter ); + } else { + System.out.println("Error"); + } + } + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + } + + @Override + public void onClick(View v) { + int id = v.getId(); + if( id == R.id.create_report_btn ){ + Intent intent = new Intent( this, MainActivity.class ); + startActivity( intent ); + } + if( id == R.id.logout_btn ){ + SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString("username", null ); + editor.putString("password", null ); + editor.apply(); + Intent intent = new Intent( HomeActivity.this, LoginActivity.class ); + startActivity( intent ); + finish(); + } + if( id == R.id.refresh_btn ){ + refreshReportData(); + updateProfileImage(); + } + } + + private void updateProfileImage(){ + SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + String username = sharedPreferences.getString("username", null ); + System.out.println( ); + if( username != null ){ + apiService.fetchEmployeePhoto( username ).enqueue( + new Callback() { + @Override + public void onResponse(Call call, Response response) { + System.out.println( response.body() ); + if( response.isSuccessful() && response.body() != null ){ + System.out.println( response.body() ); + usernameTitle.setText( response.body().getName() ); + store.setEmployeePhoto( response.body() ); + Glide.with( getBaseContext() ) + .load( store.getProfileImage( ) ) + .into( profileImage ); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + + } + } + private boolean isNetworkConnected() { + ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); + return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); + } + + @Override + protected void onResume() { + super.onResume(); + refreshReportData(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/ui/activities/LoginActivity.java b/app/src/main/java/com/example/qualitychecker/ui/activities/LoginActivity.java new file mode 100644 index 0000000..2d9239b --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/activities/LoginActivity.java @@ -0,0 +1,142 @@ +package com.example.qualitychecker.ui.activities; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ProgressBar; +import android.widget.Toast; + +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +import com.example.qualitychecker.R; +import com.example.qualitychecker.service.InspectionReportService; +import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.textfield.TextInputEditText; + +import java.util.Objects; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class LoginActivity extends AppCompatActivity { + + private TextInputEditText username,password; + private ProgressBar progressBar; + private Button loginButton; + private InspectionReportService reportService; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + if( ! isNetworkConnected() ){ + Toast.makeText( this, "No Internet Connection", Toast.LENGTH_LONG ).show(); + } + reportService = InspectionReportService.getInstance(); + isUserAlreadyLoginAndAuthorize(); + setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); + setContentView(R.layout.activity_login); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + + username = findViewById( R.id.username ); + password = findViewById( R.id.password ); + loginButton = findViewById( R.id.login_btn ); + progressBar = findViewById( R.id.progressBar ); + + SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + + loginButton.setOnClickListener(v -> { + try { + progressBar.setVisibility( View.VISIBLE ); + String usernameStr = Objects.requireNonNull( username.getText() ).toString().trim(); + String passwordStr = Objects.requireNonNull( password.getText() ).toString().trim(); + // check both are valid + if( ! usernameStr.isEmpty() && ! passwordStr.isEmpty() ) { + reportService.isUserAuthenticated(usernameStr, passwordStr, new String[]{"ROLE_DEVELOPER"}, new Callback() { + @Override + public void onResponse(Call call, Response response) { + if( response.isSuccessful() && response.body() != null && response.body() ){ + editor.putString("username", usernameStr ); + editor.putString("password", passwordStr ); + editor.apply(); + progressBar.setVisibility( View.INVISIBLE ); + Intent intent = new Intent( LoginActivity.this, HomeActivity.class ); + startActivity( intent ); + // close login screen + LoginActivity.this.finish(); + } else { + progressBar.setVisibility( View.INVISIBLE ); + Snackbar.make( v, "Invalid Credential or Access not Authorized", Snackbar.LENGTH_LONG ).show(); + } + } + @Override + public void onFailure(Call call, Throwable t) { + progressBar.setVisibility( View.INVISIBLE ); + Snackbar.make( v, "Something went wrong", Snackbar.LENGTH_LONG ).show(); + } + }); + } + else { + Snackbar.make( v, "Please Enter Your Credentials!!", Snackbar.LENGTH_LONG ).show(); + progressBar.setVisibility( View.INVISIBLE ); + } + } catch ( NullPointerException exception ){ + Snackbar.make( v, Objects.requireNonNull( exception.getMessage() ), Snackbar.LENGTH_LONG ).show(); + } + }); + } + + private void isUserAlreadyLoginAndAuthorize() { + SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + + String username = sharedPreferences.getString("username", null); + String password = sharedPreferences.getString("password", null); + + reportService.isUserAuthenticated(username, + password, + new String[]{"ROLE_DEVELOPER"}, + new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + boolean isAuthenticated = response.body(); + if (isAuthenticated) { + Intent intent = new Intent(LoginActivity.this, HomeActivity.class); + startActivity(intent); + // close login screen + LoginActivity.this.finish(); + } + } + } + @Override + public void onFailure(Call call, Throwable t) { + Log.d(t.getMessage(), "onFailure: "); + } + }); + } + + private boolean isNetworkConnected() { + ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); + return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/ui/activities/MainActivity.java b/app/src/main/java/com/example/qualitychecker/ui/activities/MainActivity.java new file mode 100644 index 0000000..6407fc1 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/activities/MainActivity.java @@ -0,0 +1,104 @@ +package com.example.qualitychecker.ui.activities; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; +import android.os.Bundle; +import android.view.View; +import android.widget.Toast; + +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.navigation.fragment.NavHostFragment; + +import com.example.qualitychecker.R; +import com.example.qualitychecker.store.Store; +import com.example.qualitychecker.ui.fragments.FirstStepFragment; +import com.example.qualitychecker.ui.fragments.SecondStepFragment; +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentResult; + +public class MainActivity extends AppCompatActivity implements View.OnClickListener { + + private NavController navController; + private Store store; + + { + store = Store.getInstance(); + store.initializeNewReport(); + } + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + setContentView(R.layout.activity_main); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); + + // initializing fields + navController = Navigation.findNavController( this, R.id.nav_host_fragment ); + updateUsername(); + } + private void updateUsername() { + if ( store.getReport() != null ) { + SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + String username = sharedPreferences.getString("username", null); + store.getReport().setGeneratedBy(username); + } + } + + @Override + public void onClick(View v) { + int id = v.getId(); + System.out.println( navController.getCurrentDestination().getId() ); + navigate("","",R.id.action_firstStepFragment_to_secondStepFragment ); + } + + private void navigate(String fromFragment, + String toFragment, + int toId ){ + System.out.println( navController.getCurrentDestination().getId() ); + navController.navigate( toId ); + } + + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); + if (result != null) { + if (result.getContents() == null) { + Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show(); + } else { + super.onActivityResult(requestCode, resultCode, data); + FirstStepFragment firstStepFragment = ( FirstStepFragment) getCurrentVisibleFragment(); + firstStepFragment.onBarcodeScanResult( result.getContents() ); + } + } else { + super.onActivityResult(requestCode, resultCode, data); + SecondStepFragment secondStepFragment = ( SecondStepFragment) getCurrentVisibleFragment(); + secondStepFragment.onImagePickerResult( requestCode, resultCode, data ); + } + } + + private Fragment getCurrentVisibleFragment() { + NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().getPrimaryNavigationFragment(); + assert navHostFragment != null; + FragmentManager fragmentManager = navHostFragment.getChildFragmentManager(); + return fragmentManager.getPrimaryNavigationFragment(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/qualitychecker/ui/adapter/CheckPointAdapter.java b/app/src/main/java/com/example/qualitychecker/ui/adapter/CheckPointAdapter.java new file mode 100644 index 0000000..015fb7d --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/adapter/CheckPointAdapter.java @@ -0,0 +1,231 @@ +package com.example.qualitychecker.ui.adapter; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.example.qualitychecker.R; +import com.example.qualitychecker.models.InspectionCheckPoint; +import com.example.qualitychecker.models.InspectionDefect; +import com.example.qualitychecker.models.InspectionItemCheckPoint; + +import java.util.List; +import java.util.stream.Collectors; + +public class CheckPointAdapter extends + RecyclerView.Adapter { + + private final List checkPointList; + private final List checkPoints; + private final List defects; + private final List defectTypes; + private final Context context; + public CheckPointAdapter( List checkPointList, + List checkPoints, + List defects, + List defectTypes, + Context context ) { + + this.checkPointList = checkPointList; + this.checkPoints = checkPoints; + this.defects = defects; + this.defectTypes = defectTypes; + this.context = context; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from( parent.getContext() ) + .inflate(R.layout.check_point, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + InspectionItemCheckPoint checkPoint = checkPointList.get( position ); + holder.bind(checkPoints, defects, defectTypes, checkPoint); + // spinner on change + { + holder.checkpointSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + String selectedItem = parent.getItemAtPosition(position).toString(); + InspectionCheckPoint cp = checkPoints.stream().filter(check -> check.getTitle().equalsIgnoreCase(selectedItem)) + .findFirst().orElse(new InspectionCheckPoint()); + holder.populateDefects(cp, defects, checkPoint); + checkPoint.setTitle(selectedItem); + } + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + holder.defectsSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + String selectedItem = parent.getItemAtPosition(position).toString(); + checkPoint.setDefectTitle(selectedItem); + } + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + holder.defectTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + String selectedItem = parent.getItemAtPosition(position).toString(); + checkPoint.setDefectSeverity(selectedItem); + } + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } + // checkboxes on change + { + holder.okCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked) { + holder.linearLayout.setVisibility(View.INVISIBLE); + } + checkPoint.setChecked ( false ); + holder.noCheckBox.setChecked( !isChecked ); + }); + + holder.noCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked) { + holder.linearLayout.setVisibility(View.VISIBLE); + } + checkPoint.setChecked( true ); + holder.okCheckBox.setChecked( !isChecked ); + }); + } + // remarks on change + { + holder.remarks.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + checkPoint.setRemarks( s.toString() ); + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + } + + holder.imagePicker.setOnClickListener( v -> { + Intent intent = new Intent( Intent.ACTION_GET_CONTENT ); + intent.addCategory( Intent.CATEGORY_OPENABLE ); + intent.setType( "image/*" ); + ( ( Activity ) context ).startActivityForResult( intent, position ); + }); + } + + + @Override + public int getItemCount() { + return checkPointList.size(); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + private final Spinner checkpointSpinner, defectsSpinner, defectTypeSpinner; + private final CheckBox okCheckBox, noCheckBox; + private final EditText remarks; + private final ImageButton imagePicker; + private final LinearLayout linearLayout; + private final TextView selectedImage; + + public ViewHolder( @NonNull View itemView) { + super(itemView); + checkpointSpinner = itemView.findViewById(R.id.check_point_spinner); + okCheckBox = itemView.findViewById(R.id.check_point_ok); + noCheckBox = itemView.findViewById(R.id.check_point_no); + remarks = itemView.findViewById(R.id.check_point_remarks); + imagePicker = itemView.findViewById(R.id.image_picker ); + selectedImage = itemView.findViewById( R.id.selected_image ); + defectsSpinner = itemView.findViewById(R.id.defect_spinner); + defectTypeSpinner = itemView.findViewById(R.id.defect_type_spinner); + linearLayout = itemView.findViewById(R.id.defect_layout); + } + public void bind(List checkPoints, + List defects, + List defectTypeOptions, + InspectionItemCheckPoint data ) { + List checkPointsList = checkPoints.stream().map(InspectionCheckPoint::getTitle).collect(Collectors.toList()); + + // Populate checklist Spinner dropdown + ArrayAdapter spinnerAdapter = new ArrayAdapter<>(checkpointSpinner.getContext(), + android.R.layout.simple_spinner_item, checkPointsList); + spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + checkpointSpinner.setAdapter(spinnerAdapter); + + // Populate defect type Spinner dropdown + ArrayAdapter defectTypeSpinnerAdapter = new ArrayAdapter<>(defectTypeSpinner.getContext(), + android.R.layout.simple_spinner_item, defectTypeOptions); + defectTypeSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + defectTypeSpinner.setAdapter(defectTypeSpinnerAdapter); + + // Pre populate + String defaultSelectedItem = data.getTitle(); + int defaultPosition = checkPointsList.indexOf(defaultSelectedItem); + checkpointSpinner.setSelection(defaultPosition); + + String defaultSelectedDefectType = data.getDefectSeverity(); + int defaultSelectedDefectTypePosition = defectTypeOptions.indexOf(defaultSelectedDefectType); + defectTypeSpinner.setSelection(defaultSelectedDefectTypePosition); + + remarks.setText( data.getRemarks() ); + okCheckBox.setChecked( data.getChecked() ); + noCheckBox.setChecked( ! data.getChecked()); + + if( data.getChecked()){ + linearLayout.setVisibility(View.INVISIBLE); + } else { + linearLayout.setVisibility(View.VISIBLE); + } + + selectedImage.setText( data.getImagePath() ); + } + private void populateDefects(InspectionCheckPoint cp, List defects, InspectionItemCheckPoint data) { + + List filteredDefects = defects.stream() + .filter(d -> d.getCategory().equalsIgnoreCase(cp.getCategory())) + .collect(Collectors.toList()); + List defectList = filteredDefects.stream().map(InspectionDefect::getDefect).collect(Collectors.toList()); + // Populate defect Spinner dropdown + ArrayAdapter defectSpinnerAdapter = new ArrayAdapter<>(defectsSpinner.getContext(), + android.R.layout.simple_spinner_item, defectList); + defectSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + defectsSpinner.setAdapter(defectSpinnerAdapter); + + String defaultDefectSelectedItem = data.getDefectTitle(); + int defaultSelectedDefectPosition = defectList.indexOf(defaultDefectSelectedItem); + defectsSpinner.setSelection(defaultSelectedDefectPosition); + } + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/adapter/DimensionAdapter.java b/app/src/main/java/com/example/qualitychecker/ui/adapter/DimensionAdapter.java new file mode 100644 index 0000000..bf27336 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/adapter/DimensionAdapter.java @@ -0,0 +1,188 @@ +package com.example.qualitychecker.ui.adapter; + +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.Spinner; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.example.qualitychecker.R; +import com.example.qualitychecker.models.InspectionItemDimension; +import com.example.qualitychecker.service.InspectionReportService; + +import java.util.List; + +public class DimensionAdapter extends + RecyclerView.Adapter{ + + private final List dimensions; + private final List dimensionTypes; + private final List dimensionUnits; + public DimensionAdapter(List dimensions, List dimensionTypes, List dimensionUnits) { + this.dimensions = dimensions; + this.dimensionTypes = dimensionTypes; + this.dimensionUnits = dimensionUnits; + } + + @NonNull + @Override + public DimensionAdapter.DimensionAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.dimension_item , parent, false); + return new DimensionAdapterViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull DimensionAdapterViewHolder holder, int position) { + InspectionItemDimension item = dimensions.get( position ); + holder.bind( item , dimensionTypes , dimensionUnits ) ; + holder.deleteItemBtn.setOnClickListener( v ->{ + removeItem( holder.getAdapterPosition() ); + }); + } + + @Override + public int getItemCount() { + return dimensions.size(); + } + + public void removeItem(int position) { + if( position >= 0 && position < dimensions.size() ){ + dimensions.remove(position); + notifyItemRemoved(position); + } + } + + + public static class DimensionAdapterViewHolder extends RecyclerView.ViewHolder { + + private final Spinner dimensionTypeSpinner,dimensionUnitSpinner; + private final EditText requiredEditText,actualEditText,differenceEditText; + private final ImageButton deleteItemBtn; + + public DimensionAdapterViewHolder(@NonNull View itemView) { + super(itemView); + dimensionTypeSpinner = itemView.findViewById( R.id.dimension_type_spinner ); + dimensionUnitSpinner = itemView.findViewById( R.id.dimension_unit_spinner ); + requiredEditText = itemView.findViewById( R.id.required ); + actualEditText = itemView.findViewById( R.id.actual ); + differenceEditText = itemView.findViewById( R.id.difference ); + deleteItemBtn = itemView.findViewById( R.id.dimension_item_delete ); + } + + public void bind( InspectionItemDimension dimension , + List dimensionTypes, + List dimensionUnits ){ + + // Populate dimension type Spinner dropdown + ArrayAdapter spinnerAdapter = new ArrayAdapter<>(dimensionTypeSpinner.getContext(), + android.R.layout.simple_spinner_item, dimensionTypes ); + spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + dimensionTypeSpinner.setAdapter(spinnerAdapter); + + String defaultSelection = dimension.getType(); + int defaultSelectedPosition = dimensionTypes.indexOf(defaultSelection); + dimensionTypeSpinner.setSelection(defaultSelectedPosition); + + // Populate dimension unit Spinner dropdown + ArrayAdapter unitSpinnerAdapter = new ArrayAdapter<>(dimensionUnitSpinner.getContext(), + android.R.layout.simple_spinner_item, dimensionUnits ); + unitSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + dimensionUnitSpinner.setAdapter(unitSpinnerAdapter); + + String defaultUnitSelection = dimension.getUnit(); + int defaultItemSelectedPosition = dimensionUnits.indexOf(defaultUnitSelection); + dimensionUnitSpinner.setSelection(defaultItemSelectedPosition); + + + requiredEditText.setText( String.valueOf( dimension.getRequired() )); + actualEditText.setText( String.valueOf( dimension.getActual() )); + differenceEditText.setText( String.valueOf( dimension.getDifference() )); + + // Spinner listener + { + dimensionTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + String selectedItem = parent.getItemAtPosition(position).toString(); + dimension.setType( selectedItem ); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + } + // unit spinner + { + dimensionUnitSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + String selectedItem = parent.getItemAtPosition(position).toString(); + dimension.setUnit( selectedItem ); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + } + + // edit text listeners + { + requiredEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + try { + dimension.setRequired( Float.parseFloat( s.toString() ) ); + float difference = dimension.getActual() - dimension.getRequired(); + differenceEditText.setText( String.valueOf( difference )); + dimension.setDifference( difference ); + } catch ( Exception e ){ + differenceEditText.setText( "0" ); + dimension.setDifference( 0 ); + } + } + + @Override + public void afterTextChanged(Editable s) { + } + }); + + actualEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + try { + dimension.setActual( Float.parseFloat( s.toString() ) ); + float difference = dimension.getActual() - dimension.getRequired(); + differenceEditText.setText( String.valueOf( difference )); + dimension.setDifference( difference ); + } catch ( Exception e ){ + differenceEditText.setText( "0" ); + dimension.setDifference( 0 ); + } + } + + @Override + public void afterTextChanged(Editable s) { + } + }); + } + } + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/adapter/ItemDimensionAdapter.java b/app/src/main/java/com/example/qualitychecker/ui/adapter/ItemDimensionAdapter.java new file mode 100644 index 0000000..be21b11 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/adapter/ItemDimensionAdapter.java @@ -0,0 +1,62 @@ +package com.example.qualitychecker.ui.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.example.qualitychecker.R; +import com.example.qualitychecker.models.InspectionItemDimension; + +import java.util.List; + +public class ItemDimensionAdapter extends + RecyclerView.Adapter { + + private final List dimensions; + + public ItemDimensionAdapter( List dimensions ){ + this.dimensions = dimensions; + } + @NonNull + @Override + public ItemDiemsionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_dimension , parent, false); + return new ItemDiemsionViewHolder( view ); + } + + @Override + public void onBindViewHolder(@NonNull ItemDiemsionViewHolder holder, int position) { + InspectionItemDimension dimension = dimensions.get( position ); + holder.bind( dimension ); + } + + @Override + public int getItemCount() { + return dimensions.size(); + } + + public static class ItemDiemsionViewHolder extends RecyclerView.ViewHolder{ + + private final EditText dimensionType,dimensionUnit,dimensionRequired,dimensionActual,dimensionDifference; + + public ItemDiemsionViewHolder(@NonNull View itemView) { + super(itemView); + dimensionType = itemView.findViewById( R.id.dimension_type ); + dimensionUnit = itemView.findViewById( R.id.dimension_unit ); + dimensionRequired = itemView.findViewById( R.id.dimension_required ); + dimensionActual = itemView.findViewById( R.id.dimension_actual ); + dimensionDifference = itemView.findViewById( R.id.dimension_difference ); + } + public void bind( InspectionItemDimension dimension ){ + dimensionType.setText( dimension.getType() ); + dimensionUnit.setText( dimension.getUnit() ); + dimensionRequired.setText( String.valueOf( dimension.getRequired() )); + dimensionActual.setText( String.valueOf( dimension.getActual() ) ); + dimensionDifference.setText( String.valueOf( dimension.getDifference() )); + } + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/adapter/ItemHistoryAdapter.java b/app/src/main/java/com/example/qualitychecker/ui/adapter/ItemHistoryAdapter.java new file mode 100644 index 0000000..3ab4248 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/adapter/ItemHistoryAdapter.java @@ -0,0 +1,84 @@ +package com.example.qualitychecker.ui.adapter; + +import android.annotation.SuppressLint; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.example.qualitychecker.R; +import com.example.qualitychecker.models.InspectionReportItem; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +public class ItemHistoryAdapter extends + RecyclerView.Adapter { + + private final List items; + + public ItemHistoryAdapter(List items) { + this.items = items; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_history_item, parent, false); + return new ViewHolder( view ); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + InspectionReportItem item = items.get( position ); + try { + holder.bind( item ); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + @Override + public int getItemCount() { + return items.size(); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + + private final TextView itemSku,itemAsin,itemDate,itemCartons,itemPacks,itemPieces; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + itemSku = itemView.findViewById( R.id.item_history_sku ); + itemAsin = itemView.findViewById( R.id.item_history_asin ); + itemDate = itemView.findViewById( R.id.item_history_date ); + itemCartons = itemView.findViewById( R.id.item_history_cartons ); + itemPacks = itemView.findViewById( R.id.item_history_packs ); + itemPieces = itemView.findViewById( R.id.item_history_pieces ); + } + + @SuppressLint("DefaultLocale") + public void bind(InspectionReportItem item ) throws ParseException { + SimpleDateFormat jsonDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault()); + SimpleDateFormat displayDateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm a", Locale.getDefault()); + itemSku.setText( item.getSku() ); + itemAsin.setText( item.getAsin() ); + if( item.getDateAdded() != null ){ + Date date = jsonDateFormat.parse( item.getDateAdded() ); + String formattedDateTime = displayDateFormat.format( date ); + itemDate.setText( formattedDateTime ); + } else { + itemDate.setText(""); + } + itemCartons.setText( String.format("Cartons : %f", item.getCartonsSelected() ) ); + itemPacks.setText( String.format("Packs : %f", item.getPacksSelected() ) ); + itemPieces.setText( String.format("Pieces : %f", item.getPiecesSelected() ) ); + } + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/adapter/ReportAdapter.java b/app/src/main/java/com/example/qualitychecker/ui/adapter/ReportAdapter.java new file mode 100644 index 0000000..dc78da7 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/adapter/ReportAdapter.java @@ -0,0 +1,81 @@ +package com.example.qualitychecker.ui.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.example.qualitychecker.R; +import com.example.qualitychecker.models.InspectionReport; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +public class ReportAdapter extends + RecyclerView.Adapter{ + private final List reports; + + public ReportAdapter(List reports) { + this.reports = reports; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from( parent.getContext() ).inflate(R.layout.report_item , parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + try { + holder.bindDate( reports.get( position ) ); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + @Override + public int getItemCount() { + return reports.size(); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + private final TextView codeTv,createdByTv, remarksTv,dateTv,status; + private final SimpleDateFormat jsonDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault()); + private final SimpleDateFormat displayDateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm a", Locale.getDefault()); + + public ViewHolder(@NonNull View itemView) { + super(itemView); + codeTv = itemView.findViewById( R.id.code ); + createdByTv = itemView.findViewById( R.id.created_by ); + remarksTv = itemView.findViewById( R.id.remarks ); + dateTv = itemView.findViewById( R.id.date ); + status = itemView.findViewById( R.id.status ); + } + + public void bindDate( InspectionReport report ) throws ParseException { + codeTv.setText( report.getCode() ); + createdByTv.setText( report.getGeneratedBy() ); + remarksTv.setText( report.getGeneralRemarks() ); + + Date date = jsonDateFormat.parse( report.getGeneratedAt() ); + // Format the date in 12-hour format + String formattedDateTime = displayDateFormat.format( date ); + dateTv.setText( formattedDateTime ); + if( report.getReportResult().equalsIgnoreCase("FAILED") ){ + status.setBackgroundResource( R.drawable.failed_bg ); + } + if( report.getReportResult().equalsIgnoreCase("Passed") ){ + status.setBackgroundResource( R.drawable.passed_bg ); + } + status.setText( report.getReportResult() ); + } + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/adapter/VocAdapter.java b/app/src/main/java/com/example/qualitychecker/ui/adapter/VocAdapter.java new file mode 100644 index 0000000..1122ae2 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/adapter/VocAdapter.java @@ -0,0 +1,79 @@ +package com.example.qualitychecker.ui.adapter; + +import static com.example.qualitychecker.ui.adapter.VocAdapter.*; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.example.qualitychecker.R; +import com.example.qualitychecker.models.VoiceOfCustomer; + +import java.util.List; + +public class VocAdapter extends + RecyclerView.Adapter { + + private final List vocs; + private final Context context; + + public VocAdapter (List vocs, Context context) { + this.vocs = vocs; + this.context = context; + } + + @NonNull + @Override + public VocViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.voc_item, parent, false); + return new VocViewHolder( view , context); + } + + @Override + public void onBindViewHolder(@NonNull VocViewHolder holder, int position) { + VoiceOfCustomer voc = vocs.get( position ); + holder.bind( voc ); + } + + @Override + public int getItemCount() { + return vocs.size(); + } + + public static class VocViewHolder extends RecyclerView.ViewHolder { + + private final TextView asin, fnsku,health,item,markeplace; + private final ImageView imageView; + private final Context context; + + public VocViewHolder(@NonNull View itemView, Context context) { + super(itemView); + this.context = context; + asin = itemView.findViewById( R.id.asin ); + fnsku = itemView.findViewById( R.id.fnsku ); + health = itemView.findViewById( R.id.health ); + item = itemView.findViewById( R.id.item ); + markeplace = itemView.findViewById( R.id.marketplace ); + imageView = itemView.findViewById( R.id.voc_item_imageview ); + } + + public void bind( VoiceOfCustomer voc ){ + asin.setText( voc.getAsin() ); + fnsku.setText( voc.getFnsku() ); + health.setText( voc.getPcxHealth() ); + item .setText( voc.getItemName() ); + markeplace.setText( voc.getMarketplace() ); + Glide.with( context ) + .load( voc.getImageUrl() ) + .into( imageView ); + + } + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/fragments/FirstStepFragment.java b/app/src/main/java/com/example/qualitychecker/ui/fragments/FirstStepFragment.java new file mode 100644 index 0000000..c3ef7e3 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/fragments/FirstStepFragment.java @@ -0,0 +1,546 @@ +package com.example.qualitychecker.ui.fragments; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.Fragment; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.example.qualitychecker.R; +import com.example.qualitychecker.apiservice.ApiService; +import com.example.qualitychecker.apiservice.ApiServiceFactory; +import com.example.qualitychecker.models.InspectionReportItem; +import com.example.qualitychecker.models.Product; +import com.example.qualitychecker.store.Store; +import com.example.qualitychecker.ui.adapter.ItemHistoryAdapter; +import com.google.android.material.snackbar.Snackbar; +import com.google.zxing.integration.android.IntentIntegrator; +import com.journeyapps.barcodescanner.CaptureActivity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class FirstStepFragment extends Fragment implements View.OnClickListener { + + private NavController navController; + private Button leftFab,rightFab,showHistoryBtn; + private EditText sku,boxCarton,itemPerBox,pieces,packagingDetails,boxCartonSelected,itemPerBoxSelected,piecesSelected; + private Spinner markerplace,modelNumber,title,color,size; + private CheckBox fri,refri; + private ImageButton searchSku,scanBtn; + private TextView profileName; + private ImageView profileImage; + private ApiService apiService; + private Store store; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_first_step , container, false ); + initializeViews( view ); + apiService = ApiServiceFactory.getApiService(); + store = Store.getInstance(); + // set on click listener + leftFab.setOnClickListener( this ); + rightFab.setOnClickListener( this ); + searchSku.setOnClickListener( this ); + scanBtn.setOnClickListener( this ); + showHistoryBtn.setOnClickListener( this ); + populateItem( store.getProducts() ); + prePopulateData( store.getProducts() ); + + + profileName.setText( store.getEmployeePhoto().getName() !=null ? store.getEmployeePhoto().getName() : "" ); + Glide.with( getContext() ) + .load( store.getProfileImage( ) ) + .into( profileImage ); + + fri.setOnCheckedChangeListener((buttonView, isChecked) -> { + if( isChecked ){ + store.getReport().setFri( true ); + refri.setChecked( false ); + } else { + store.getReport().setFri( false ); + refri.setChecked( true ); + } + }); + + refri.setOnCheckedChangeListener((buttonView, isChecked) -> { + if( isChecked ){ + store.getReport().setFri( false ); + fri.setChecked( false ); + } else { + store.getReport().setFri( true ); + fri.setChecked( true ); + } + }); + // marketplace + markerplace.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if( parent.getItemAtPosition( position ) != null ){ + String marketplaceOption = parent.getItemAtPosition( position ).toString(); + store.getReport().getItems().get(0).setMarketplace( marketplaceOption ); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + store.getReport().getItems().get(0).setMarketplace(""); + } + }); + + // title + title.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if( parent.getItemAtPosition( position ) != null ){ + String titleOption = parent.getItemAtPosition( position ).toString(); + store.getReport().getItems().get(0).setTitle( titleOption ); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + store.getReport().getItems().get(0).setTitle(""); + } + }); + + // model + modelNumber.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if( parent.getItemAtPosition( position ) != null ){ + String modelOption = parent.getItemAtPosition( position ).toString(); + store.getReport().getItems().get(0).setModelNumber( modelOption ); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + store.getReport().getItems().get(0).setModelNumber(""); + } + }); + + // color + color.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if( parent.getItemAtPosition( position ) != null ){ + String colorOption = parent.getItemAtPosition( position ).toString(); + store.getReport().getItems().get(0).setSmColor( colorOption ); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + store.getReport().getItems().get(0).setSmColor(""); + } + }); + + // size + size.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if( parent.getItemAtPosition( position ) != null ){ + String sizeOption = parent.getItemAtPosition( position ).toString(); + store.getReport().getItems().get(0).setSmSize( sizeOption ); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + store.getReport().getItems().get(0).setSmSize(""); + } + }); + + boxCartonSelected.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + try { + store.getReport().getItems().get(0).setCartonsSelected( Long.parseLong( s.toString() ) ); + } catch ( Exception e ){ + store.getReport().getItems().get(0).setCartonsSelected( 0 ); + } + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + + itemPerBoxSelected.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + try { + store.getReport().getItems().get(0).setPacksSelected( Long.parseLong( s.toString() ) ); + } catch ( Exception e ){ + store.getReport().getItems().get(0).setPacksSelected( 0 ); + } + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + + piecesSelected.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + try { + store.getReport().getItems().get(0).setPiecesSelected( Long.parseLong( s.toString() ) ); + } catch ( Exception e ){ + store.getReport().getItems().get(0).setPiecesSelected( 0 ); + } + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + +// generalRemarks.addTextChangedListener(new TextWatcher() { +// @Override +// public void beforeTextChanged(CharSequence s, int start, int count, int after) { +// +// } +// +// @Override +// public void onTextChanged(CharSequence s, int start, int before, int count) { +// try { +// store.getReport().setGeneralRemarks( s.toString() ); +// } catch ( Exception e ){ +// store.getReport().setGeneralRemarks( ""); +// } +// } +// +// @Override +// public void afterTextChanged(Editable s) { +// +// } +// }); + + return view; + } + + @Override + public void onClick(View v) { + navController = Navigation.findNavController( requireView() ); + if( v.getId() == R.id.button_left_frag_1 ){ + if( getActivity() != null ){ + getActivity().finish(); + } + } + if( v.getId() == R.id.button_right_frag_1 ){ + navController.navigate( R.id.action_firstStepFragment_to_secondStepFragment ); + } + if( v.getId() == R.id.search_sku_btn ){ + if( sku.getText() != null ){ + String skuStr = sku.getText().toString().trim(); + apiService.fetchProductBySku( skuStr ).enqueue( + new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if( response.isSuccessful() && response.body() != null ){ + Product product = response.body().stream().findFirst().orElse(new Product()); + store.getReport().getItems().get(0).setSku( skuStr ); + store.getReport().getItems().get(0).setAsin( product.getAsin() ); + populateItem( response.body() ); + store.setProducts( response.body() ); + } else { + Snackbar.make(v, "Error in response", Snackbar.LENGTH_LONG ).show(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + } + } + if( v.getId() == R.id.scan_sku_btn ){ + IntentIntegrator integrator = new IntentIntegrator( getActivity() ); + integrator.setCaptureActivity(CaptureActivity.class); + integrator.setOrientationLocked( true ); + integrator.setBarcodeImageEnabled( true ); + integrator.initiateScan(); + } + if( v.getId() == R.id.button_show_history ){ + openItemHistoryDialog(); + } + } + + private void prePopulateData( List products ){ + fri.setChecked( store.getReport().getFri() ); + refri.setChecked( ! store.getReport().getFri() ); + // sku + sku.setText( store.getReport().getItems().get(0).getSku() ); + System.out.println( products ); + System.out.println( store.getReport().getItems().get(0) ); + + if( ! products.isEmpty() ){ + List modelNumbers = products.stream().map( Product::getModelNumber ).distinct().collect(Collectors.toList()) ; + + String defaultModelSelection = store.getReport().getItems().get(0).getModelNumber(); + int defaultModelSelectionIndex = modelNumbers.indexOf( defaultModelSelection ); + modelNumber.setSelection( defaultModelSelectionIndex ); + } + + if( ! products.isEmpty() ){ + List titles = products.stream().map( Product::getTitle ).distinct().collect(Collectors.toList()) ; + String defaultTitleSelection = store.getReport().getItems().get(0).getTitle(); + int defaultTitleSelectionIndex = titles.indexOf( defaultTitleSelection ); + title.setSelection( defaultTitleSelectionIndex ); + } + + } + + private void populateItem( List products ){ + populateMarketplaces( products ); + populateMmodelNumber(products ); + populateTitle( products ); + populateColor( products ); + populateSize( products ); + populateItemPresentedDetails( products ); + } + + private void populateItemPresentedDetails( List products ){ + try{ + if( ! products.isEmpty() ){ + Product product = products.get( 0 ); + String inventory = String.valueOf( product.getInventory() ); + String itemPerBoxText = String.valueOf( product.getInventory() * product.getItemPerPack() ); + String boxCartonText = String.valueOf( ( product.getInventory() / product.getItemPerBox() ) ); + + String packagingDetailsText = String.format("%d Item per Pack, %d Pack per Box", product.getItemPerPack(), product.getItemPerBox() ); + + itemPerBox.setText( inventory ); + pieces.setText( itemPerBoxText ); + boxCarton.setText( boxCartonText ); + packagingDetails.setText( packagingDetailsText ); + + boxCartonSelected.setText( String.valueOf( store.getReport().getItems().get(0).getCartonsSelected() )); + itemPerBoxSelected.setText( String.valueOf( store.getReport().getItems().get(0).getPacksSelected() ) ); + piecesSelected.setText( String.valueOf( store.getReport().getItems().get(0).getPiecesSelected() ) ); + // generalRemarks.setText( store.getReport().getItems().get(0).getSampleSize() ); + + store.getReport().getItems().get(0).setTotalPresentPieces( Long.parseLong( inventory ) ); + store.getReport().getItems().get(0).setTotalPresentPacks( Long.parseLong( itemPerBoxText ) ); + store.getReport().getItems().get(0).setTotalPresentCartons( Long.parseLong( boxCartonText ) ); + store.getReport().getItems().get(0).setPackingDetails( packagingDetailsText ); + + } + } catch ( Exception e){ + itemPerBox.setText( "0" ); + pieces.setText( "0" ); + boxCarton.setText( "0" ); + packagingDetails.setText( "" ); + } + } + + + private void populateSize( List products ){ + List sizes = Collections.singletonList("[Size]"); + if( ! products.isEmpty() ){ + sizes = products.stream().map( Product::getSmSize ).distinct().collect(Collectors.toList() ); + } + ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, sizes.toArray( new String[0]) ); + size.setAdapter( adapter ); + // + String sizeOption = (String) size.getSelectedItem(); + store.getReport().getItems().get(0).setSmSize( sizeOption ); + } + + private void populateColor( List products ){ + List colors = Collections.singletonList("[Color]"); + if( ! products.isEmpty() ){ + colors = products.stream().map( Product::getSmColor ).distinct().collect(Collectors.toList() ); + } + ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, colors.toArray( new String[0]) ); + color.setAdapter( adapter ); + // + String colorOption = (String) color.getSelectedItem(); + store.getReport().getItems().get(0).setSmColor( colorOption ); + } + + private void populateTitle( List products ){ + List titles = Collections.singletonList("[Title]"); + if( ! products.isEmpty() ){ + titles = products.stream().map( Product::getTitle ).distinct().collect(Collectors.toList()) ; + } + ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, titles.toArray( new String[0] )); + title.setAdapter( adapter ); + // + String titleOption = (String) title.getSelectedItem(); + store.getReport().getItems().get(0).setTitle( titleOption ); + } + + + private void populateMmodelNumber( List products ){ + List modelNumbers = Collections.singletonList("[Model Number]"); + if( ! products.isEmpty() ){ + modelNumbers = products.stream().map( Product::getModelNumber ).distinct().collect(Collectors.toList()) ; + } + ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, modelNumbers.toArray(new String[0] )); + modelNumber.setAdapter( adapter ); + + String modelOption = (String) modelNumber.getSelectedItem(); + store.getReport().getItems().get(0).setMarketplace( modelOption ); + } + + private void populateMarketplaces( List products ){ + List marketplaces = Collections.singletonList("[ Marketplace ]"); + if( ! products.isEmpty() ){ + marketplaces = products.stream().map( Product::getMarketplace ).distinct().collect(Collectors.toList() ); + } + ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, marketplaces.toArray(new String[0] )); + markerplace.setAdapter( adapter ); + // + String marketplaceOption = (String) markerplace.getSelectedItem(); + store.getReport().getItems().get(0).setMarketplace( marketplaceOption ); + } + + + /* + * initialize views + * */ + private void initializeViews( View view ){ + leftFab = view.findViewById( R.id.button_left_frag_1 ); + rightFab = view.findViewById( R.id.button_right_frag_1 ); + markerplace = view.findViewById( R.id.marketplace ); + sku = view.findViewById( R.id.sku ); + modelNumber = view.findViewById( R.id.model_number ); + title = view.findViewById( R.id.title ); + color = view.findViewById( R.id.color ); + size = view.findViewById( R.id.size ); + boxCarton = view.findViewById( R.id. box_carton ); + itemPerBox = view.findViewById( R.id.item_per_box ); + pieces = view.findViewById( R.id.pieces ); + packagingDetails = view.findViewById( R.id.packaging ); + boxCartonSelected = view.findViewById( R.id.box_carton_selected ); + itemPerBoxSelected = view.findViewById( R.id.item_per_box_selected ); + piecesSelected = view.findViewById( R.id.pieces_selected ); + fri = view.findViewById( R.id.fri ); + refri = view.findViewById( R.id.refri ); + searchSku = view.findViewById( R.id.search_sku_btn ); + profileName= view.findViewById( R.id.first_step_name ); + profileImage = view.findViewById( R.id.first_step_profile_image ); + scanBtn = view.findViewById( R.id.scan_sku_btn ); + showHistoryBtn = view.findViewById( R.id.button_show_history ); + } + public void onBarcodeScanResult( String result ){ + if( result != null && ! result.isEmpty() ){ + apiService.fetchByFnsku( result ).enqueue( + new Callback() { + @Override + public void onResponse(Call call, Response response) { + if( response.isSuccessful() && response.body() != null ){ + store.getReport().getItems().get(0).setSku( response.body().getSku() ); + sku.setText( response.body().getSku() ); + } + } + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText( getContext(), t.getMessage().toString(), Toast.LENGTH_LONG ).show(); + } + } + ); + } + } + + private void openItemHistoryDialog() { + LayoutInflater inflater = LayoutInflater.from( getContext() ); + View dialogView = inflater.inflate( R.layout.item_history, null); + // recycler view + RecyclerView itemHistoryRecyclerView = dialogView.findViewById( R.id.item_history_recyclerview ); + LinearLayoutManager layoutManager = new LinearLayoutManager( getContext() ); + itemHistoryRecyclerView.setLayoutManager( layoutManager ); + AlertDialog.Builder builder = new AlertDialog.Builder( getContext() ); + + // set adapter + ItemHistoryAdapter itemHistoryAdapter = new ItemHistoryAdapter( new ArrayList<>()); + itemHistoryRecyclerView.setAdapter( itemHistoryAdapter ); + + builder.setView(dialogView) + .setTitle("Item History") + .setPositiveButton( "OK",(dialog, which) -> { + dialog.dismiss(); + } ) + .setNegativeButton("Cancel", (dialog, which) -> { + // Handle Cancel button click + dialog.dismiss(); + }); + System.out.println( "SKU" + store.getReport().getItems().get(0).getSku() ); + if( store.getReport().getItems().get(0).getSku() != null ){ + apiService.fetchItemsLogs( store.getReport().getItems().get(0).getSku() ).enqueue( + new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if( response.isSuccessful() && response.body() != null ){ + // set adapter + System.out.println( response.body() ); + ItemHistoryAdapter itemHistoryAdapter = new ItemHistoryAdapter( response.body() ); + itemHistoryRecyclerView.setAdapter( itemHistoryAdapter ); + itemHistoryAdapter.notifyDataSetChanged(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + } + // Show the dialog + AlertDialog dialog = builder.create(); + dialog.show(); + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/fragments/ForthStepFragment.java b/app/src/main/java/com/example/qualitychecker/ui/fragments/ForthStepFragment.java new file mode 100644 index 0000000..52fe56a --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/fragments/ForthStepFragment.java @@ -0,0 +1,43 @@ +package com.example.qualitychecker.ui.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; + +import com.example.qualitychecker.R; + +public class ForthStepFragment extends Fragment implements View.OnClickListener { + + + private NavController navController; + private Button leftFab,rightFab; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_forth_step , container, false ); + leftFab = view.findViewById( R.id.button_left_frag_4 ); + rightFab = view.findViewById( R.id.button_right_frag_4 ); + + // set on click listener + leftFab.setOnClickListener( this ); + rightFab.setOnClickListener( this ); + return view; + } + + @Override + public void onClick(View v) { + navController = Navigation.findNavController( requireView() ); + if( v.getId() == R.id.button_left_frag_4 ){ + navController.navigate( R.id.action_forthStepFragment_to_thirdStepFragment ); + } + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/fragments/SecondStepFragment.java b/app/src/main/java/com/example/qualitychecker/ui/fragments/SecondStepFragment.java new file mode 100644 index 0000000..a7a19bc --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/fragments/SecondStepFragment.java @@ -0,0 +1,165 @@ +package com.example.qualitychecker.ui.fragments; + +import static android.app.Activity.RESULT_OK; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.example.qualitychecker.R; +import com.example.qualitychecker.apiservice.ApiService; +import com.example.qualitychecker.apiservice.ApiServiceFactory; +import com.example.qualitychecker.models.InspectionCheckPoint; +import com.example.qualitychecker.models.InspectionDefect; +import com.example.qualitychecker.service.InspectionReportService; +import com.example.qualitychecker.store.Store; +import com.example.qualitychecker.ui.adapter.CheckPointAdapter; + + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + + +public class SecondStepFragment extends Fragment + implements View.OnClickListener { + + private NavController navController; + private Button leftFab,rightFab; + private RecyclerView recyclerView; + private CheckPointAdapter adapter; + private ApiService apiService; + private TextView profileName; + private ImageView profileImage; + private List checkPoints; + private List defects; + private InspectionReportService inspectionReportService; + private Store store; + private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 100; + private static final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 101; + + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_second_step , container, false ); + + apiService = ApiServiceFactory.getApiService(); + store = Store.getInstance(); + inspectionReportService = InspectionReportService.getInstance(); + checkPoints = new ArrayList<>(); + defects = new ArrayList<>(); + leftFab = view.findViewById( R.id.button_left_frag_2 ); + rightFab = view.findViewById( R.id.button_right_frag_2 ); + recyclerView = view.findViewById( R.id.check_point_recycler_view ); + profileName = view.findViewById( R.id.second_profile_name ); + profileImage = view.findViewById( R.id.second_step_profile_image ); + recyclerView.setLayoutManager( new LinearLayoutManager( getContext() ) ); + + // PERMISSIONS + { + // Check if permission is not granted + if ( ContextCompat.checkSelfPermission( getContext(), Manifest.permission.READ_EXTERNAL_STORAGE ) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted, request it + ActivityCompat.requestPermissions( getActivity(), + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); + } + + if (ContextCompat.checkSelfPermission( getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + ActivityCompat.requestPermissions(getActivity(), + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); + } + } + + profileName.setText( store.getEmployeePhoto().getName() ); + Glide.with( getContext() ) + .load( store.getProfileImage( ) ) + .into( profileImage ); + + adapter = new CheckPointAdapter( store.getReport().getItems().get( 0 ).getCheckPoints(), + store.getCheckPoints(), + store.getDefects(), + inspectionReportService.getDefectTypes(), + getContext()); + recyclerView.setAdapter( adapter ); + // set on click listener + leftFab.setOnClickListener( this ); + rightFab.setOnClickListener( this ); + return view; + } + + @Override + public void onClick(View v) { + navController = Navigation.findNavController( requireView() ); + if( v.getId() == R.id.button_left_frag_2 ){ + navController.navigate( R.id.action_secondStepFragment_to_firstStepFragment ); + } + if( v.getId() == R.id.button_right_frag_2 ){ + navController.navigate( R.id.action_secondStepFragment_to_thirdStepFragment ); + } + } + + public void onImagePickerResult(int requestCode, int resultCode, Intent data) { + if ( resultCode == RESULT_OK && data != null ) { + try { + Uri selectedImageUri = data.getData(); + String imagePath = selectedImageUri.getPath(); + store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setImagePath( imagePath ); + store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setFile( getBytesFromUri( getContext(), selectedImageUri ) ); + adapter.notifyItemChanged( requestCode ); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + private byte[] getBytesFromUri(Context context, Uri uri) { + if( uri != null ) { + try { + InputStream inputStream = context.getContentResolver().openInputStream(uri); + if (inputStream != null) { + ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = inputStream.read(buffer)) != -1) { + byteBuffer.write(buffer, 0, len); + } + inputStream.close(); + return byteBuffer.toByteArray(); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + return null; + } + } + return null; + } +} diff --git a/app/src/main/java/com/example/qualitychecker/ui/fragments/ThirdStepFragment.java b/app/src/main/java/com/example/qualitychecker/ui/fragments/ThirdStepFragment.java new file mode 100644 index 0000000..2e62403 --- /dev/null +++ b/app/src/main/java/com/example/qualitychecker/ui/fragments/ThirdStepFragment.java @@ -0,0 +1,291 @@ +package com.example.qualitychecker.ui.fragments; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.Fragment; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.example.qualitychecker.R; +import com.example.qualitychecker.apiservice.ApiService; +import com.example.qualitychecker.apiservice.ApiServiceFactory; +import com.example.qualitychecker.models.InspectionItemDimension; +import com.example.qualitychecker.models.SaveReportCallback; +import com.example.qualitychecker.models.VoiceOfCustomer; +import com.example.qualitychecker.service.InspectionReportService; +import com.example.qualitychecker.store.Store; +import com.example.qualitychecker.ui.adapter.DimensionAdapter; +import com.example.qualitychecker.ui.adapter.ItemDimensionAdapter; +import com.example.qualitychecker.ui.adapter.VocAdapter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class ThirdStepFragment extends Fragment implements View.OnClickListener { + private NavController navController; + private Button backBtn,nextBtn,openDimensionDialog; + private TextView profileName; + private ImageView profileImage; + private InspectionReportService inspectionReportService; + private RecyclerView vocRecyclerView,itemDimensionsRecyclerView; + private Store store; + private Spinner resultSpinner; + private ApiService apiService; + private EditText generalRemarks; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_third_step , container, false ); + + inspectionReportService = InspectionReportService.getInstance(); + store = Store.getInstance(); + apiService = ApiServiceFactory.getApiService(); + + initializeViews( view ); + populateViews(); + setOnClickListeners(); + vocRecyclerView.setLayoutManager( new LinearLayoutManager( getContext() ) ); + itemDimensionsRecyclerView.setLayoutManager( new LinearLayoutManager( getContext() ) ); + + String asin = store.getReport().getItems().get(0).getAsin(); + apiService.fetchVocs( asin ).enqueue( + new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + if( response.isSuccessful() && response.body() != null ){ + VocAdapter adapter = new VocAdapter( response.body(), getContext() ); + vocRecyclerView.setAdapter( adapter ); + } + } + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t.getMessage() ); + } + } + ); + + ItemDimensionAdapter adapter = new ItemDimensionAdapter( store.getReport().getItems().get(0).getDimensions() ); + itemDimensionsRecyclerView.setAdapter( adapter ); + + generalRemarks.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + try { + store.getReport().setGeneralRemarks( s.toString() ); + } catch ( Exception e ){ + store.getReport().setGeneralRemarks( ""); + } + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + return view; + } + + @Override + public void onClick(View v) { + navController = Navigation.findNavController( requireView() ); + if( v.getId() == R.id.button_left_frag_3 ){ + navController.navigate( R.id.action_thirdStepFragment_to_secondStepFragment ); + } + if( v.getId() == R.id.button_right_frag_3 ){ + saveReportDialog(); + } + if( v.getId() == R.id.button_open_dimension ){ + openDimensionDialog(); + } + } + + private void saveReportDialog(){ + AlertDialog.Builder builder = new AlertDialog.Builder( getContext() ); + builder.setTitle("So you want to save report?") + .setPositiveButton( "Save",(dialog, which) -> { + inspectionReportService.saveReport(store.getReport(), new SaveReportCallback() { + @Override + public void onSuccess() { + Toast.makeText( getContext(), "Report saved Successfully", Toast.LENGTH_LONG ).show(); + getActivity().finish(); + } + @Override + public void onFailure(Throwable throwable) { + Toast.makeText( getContext(), throwable.getMessage(), Toast.LENGTH_LONG ).show(); + } + }); + }) + .setNegativeButton("Cancel", (dialog, which) -> { + // Handle Cancel button click + dialog.dismiss(); + }); + // Show the dialog + AlertDialog dialog = builder.create(); + dialog.show(); + } + + private void openDimensionDialog() { + LayoutInflater inflater = LayoutInflater.from( getContext() ); + View dialogView = inflater.inflate( R.layout.dimension_dialog, null); + // recycler view + RecyclerView dimensionRecyclerView = dialogView.findViewById( R.id.dimension_recycler_view ); + LinearLayoutManager layoutManager = new LinearLayoutManager( getContext() ); + dimensionRecyclerView.setLayoutManager( layoutManager ); + // set adapter + DimensionAdapter dimensionAdapter = new DimensionAdapter( store.getDimensions(), + store.getDimensionList(), + store.getItemUnits() ); + dimensionRecyclerView.setAdapter( dimensionAdapter ); + AlertDialog.Builder builder = new AlertDialog.Builder( getContext() ); + builder.setView(dialogView) + .setTitle("Select Dimensions") + .setPositiveButton( "Save",(dialog, which) -> { + calculateDimensions(); + dialog.dismiss(); + } ) + .setNegativeButton("Cancel", (dialog, which) -> { + // Handle Cancel button click + dialog.dismiss(); + }); + + Button addItemBtn = dialogView.findViewById( R.id.add_dimension_item ); + addItemBtn.setOnClickListener(v -> { + int position = store.getDimensions().size(); + store.getDimensions().add( new InspectionItemDimension() ); + dimensionAdapter.notifyItemInserted( position ); + dimensionRecyclerView.smoothScrollToPosition( position ); + + }); + + // Show the dialog + AlertDialog dialog = builder.create(); + dialog.show(); + // After show, clear the flags and set the soft input mode + dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); + + } + + private void populateViews(){ + + profileName.setText( store.getEmployeePhoto().getName() ); + Glide.with( getContext() ) + .load( store.getProfileImage( ) ) + .into( profileImage ); + + generalRemarks.setText( store.getReport().getGeneralRemarks() ); + + ArrayAdapter adapter = new ArrayAdapter( getContext(), + android.R.layout.simple_spinner_item, + inspectionReportService.getReportResult() ); + resultSpinner.setAdapter( adapter ); + + String defaultSelection = store.getReport().getReportResult(); + int defaultIndexResultIndex = inspectionReportService.getReportResult().indexOf( defaultSelection ); + resultSpinner.setSelection( defaultIndexResultIndex ); + + resultSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + String result = parent.getItemAtPosition( position ).toString(); + store.getReport().setReportResult( result ); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } + + private void calculateDimensions(){ + List dimensions = store.getDimensions(); + List newDimensions = new ArrayList<>(); + // calculations for averaging + Map> typeToDimensionsMap = + dimensions.stream().collect(Collectors.groupingBy( InspectionItemDimension::getType) ); + + for( Map.Entry> entry : typeToDimensionsMap.entrySet() ){ + float required = 0f; + float actual = 0f; + float difference =0f; + String unit = null; + float size = entry.getValue().size(); + + for( InspectionItemDimension dimen : entry.getValue() ){ + required += dimen.getRequired(); + actual += dimen.getActual(); + difference += dimen.getDifference(); + if( unit == null ){ + unit = dimen.getUnit(); + } + } + // average + required /= size; + actual /= size; + difference /= size; + + InspectionItemDimension newDimen = new InspectionItemDimension( + entry.getKey(), + actual, + required, + difference, + unit + ); + newDimensions.add( newDimen ); + } + store.getReport().getItems().get(0).setDimensions( newDimensions ); + ItemDimensionAdapter adapter = new ItemDimensionAdapter( store.getReport().getItems().get(0).getDimensions() ); + itemDimensionsRecyclerView.setAdapter( adapter ); + } + + private void initializeViews( View view ){ + backBtn = view.findViewById( R.id.button_left_frag_3 ); + nextBtn = view.findViewById( R.id.button_right_frag_3 ); + openDimensionDialog = view.findViewById( R.id.button_open_dimension ); + profileImage = view.findViewById( R.id.third_step_profile_image ); + profileName = view.findViewById( R.id.third_profile_name ); + vocRecyclerView = view.findViewById( R.id.voc_recyclerview ); + resultSpinner = view.findViewById( R.id.result_spinner ); + generalRemarks = view.findViewById( R.id.general_remarks ); + itemDimensionsRecyclerView = view.findViewById( R.id.item_dimensions_recyclerview ); + } + private void setOnClickListeners(){ + nextBtn.setOnClickListener( this ); + backBtn.setOnClickListener( this ); + openDimensionDialog.setOnClickListener( this); + } +} diff --git a/app/src/main/res/anim/slide_in_left.xml b/app/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000..556d875 --- /dev/null +++ b/app/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..ac2053d --- /dev/null +++ b/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..6cf15b1 --- /dev/null +++ b/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/anim/slide_out_right.xml b/app/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000..3cb1ce2 --- /dev/null +++ b/app/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/drawable/background_image.xml b/app/src/main/res/drawable/background_image.xml new file mode 100644 index 0000000..1b88a00 --- /dev/null +++ b/app/src/main/res/drawable/background_image.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable/failed_bg.xml b/app/src/main/res/drawable/failed_bg.xml new file mode 100644 index 0000000..4255cd8 --- /dev/null +++ b/app/src/main/res/drawable/failed_bg.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml new file mode 100644 index 0000000..2ae27b8 --- /dev/null +++ b/app/src/main/res/drawable/ic_add.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_check.xml b/app/src/main/res/drawable/ic_check.xml new file mode 100644 index 0000000..562b621 --- /dev/null +++ b/app/src/main/res/drawable/ic_check.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml new file mode 100644 index 0000000..bcc56a1 --- /dev/null +++ b/app/src/main/res/drawable/ic_close.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml new file mode 100644 index 0000000..883bcaa --- /dev/null +++ b/app/src/main/res/drawable/ic_delete.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..7b7c7d0 --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..38ac379 --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_search.xml b/app/src/main/res/drawable/ic_search.xml new file mode 100644 index 0000000..d29c6ea --- /dev/null +++ b/app/src/main/res/drawable/ic_search.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/image_picker.xml b/app/src/main/res/drawable/image_picker.xml new file mode 100644 index 0000000..fd890ce --- /dev/null +++ b/app/src/main/res/drawable/image_picker.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/passed_bg.xml b/app/src/main/res/drawable/passed_bg.xml new file mode 100644 index 0000000..8069d8b --- /dev/null +++ b/app/src/main/res/drawable/passed_bg.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/rounded_corners_bg.xml b/app/src/main/res/drawable/rounded_corners_bg.xml new file mode 100644 index 0000000..384f98c --- /dev/null +++ b/app/src/main/res/drawable/rounded_corners_bg.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable/scan.xml b/app/src/main/res/drawable/scan.xml new file mode 100644 index 0000000..5ab50c7 --- /dev/null +++ b/app/src/main/res/drawable/scan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/utopia_svg_logo.xml b/app/src/main/res/drawable/utopia_svg_logo.xml new file mode 100644 index 0000000..4afe746 --- /dev/null +++ b/app/src/main/res/drawable/utopia_svg_logo.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml new file mode 100644 index 0000000..f11feca --- /dev/null +++ b/app/src/main/res/layout/activity_home.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +