From 1b53281f738e2c026eb3c458d7a619d845c93d69 Mon Sep 17 00:00:00 2001 From: saif Date: Thu, 29 Aug 2024 09:22:17 +0500 Subject: [PATCH] - feedback 1 implemented --- .idea/inspectionProfiles/Project_Default.xml | 1 + app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 15 +- .../qualitychecker/apiservice/ApiService.java | 12 +- .../apiservice/RetrofitClient.java | 35 ++- .../apiservice/SSLCheckHttpClient.java | 52 ++++ .../qualitychecker/async/ImageProcessor.java | 27 +- .../db/CheckpointRepository.java | 85 ++++++ .../qualitychecker/db/DatabaseHelper.java | 138 +++++++++ .../qualitychecker/db/DefectRepository.java | 82 +++++ .../db/DimensionRepository.java | 97 ++++++ .../qualitychecker/db/ItemRepository.java | 82 +++++ .../qualitychecker/db/ProductRepository.java | 181 +++++++++++ .../qualitychecker/db/ReportRepository.java | 129 ++++++++ .../qualitychecker/models/Dimension.java | 5 +- .../models/InspectionCheckPoint.java | 5 +- .../models/InspectionDefect.java | 6 +- .../models/InspectionDimension.java | 5 +- .../models/InspectionItemCheckPoint.java | 11 +- .../models/InspectionItemDefect.java | 4 +- .../models/InspectionItemDimension.java | 5 +- .../models/InspectionReport.java | 29 +- .../models/InspectionReportItem.java | 4 +- .../models/InspectionReportWrapper.java | 65 ++++ .../qualitychecker/models/ItemUnit.java | 5 +- .../qualitychecker/models/Product.java | 5 +- .../models/SaveReportCallback.java | 6 - .../models/VoiceOfCustomer.java | 5 +- .../models/callback/SaveCallback.java | 6 + .../callback/SaveCheckpointCallback.java | 4 + .../models/callback/SaveDefectCallback.java | 4 + .../callback/SaveDimensionCallback.java | 4 + .../models/callback/SaveItemCallback.java | 4 + .../models/callback/SaveProductCallBack.java | 5 + .../models/callback/SaveReportCallback.java | 4 + .../notification/NotificationHelper.java | 25 ++ .../receiver/NetworkReceiver.java | 32 ++ .../service/InspectionReportService.java | 288 +++++++++++++++--- .../service/NetworkService.java | 123 ++++++++ .../qualitychecker/store/Store.java | 181 ++++++----- .../ui/activities/HomeActivity.java | 200 +++++++++++- .../ui/activities/LoginActivity.java | 49 +-- .../ui/activities/MainActivity.java | 10 +- .../ui/adapter/CheckPointAdapter.java | 12 +- .../ui/adapter/DefectsAdapter.java | 37 ++- .../ui/adapter/ReportAdapter.java | 5 +- .../ui/fragments/FirstStepFragment.java | 198 ++++++------ .../ui/fragments/SecondStepFragment.java | 84 ++--- .../ui/fragments/ThirdStepFragment.java | 96 +++--- .../qualitychecker/utils/FileUtils.java | 66 ++++ app/src/main/res/drawable/hold_bg.xml | 5 + app/src/main/res/drawable/ic_down.xml | 5 + app/src/main/res/layout/activity_home.xml | 11 +- app/src/main/res/layout/defect_item.xml | 22 +- .../main/res/layout/fragment_forth_step.xml | 1 - .../main/res/xml/network_security_config.xml | 12 +- settings.gradle | 2 +- 57 files changed, 2173 insertions(+), 422 deletions(-) create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/SSLCheckHttpClient.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/db/CheckpointRepository.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/db/DatabaseHelper.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/db/DefectRepository.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/db/DimensionRepository.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/db/ItemRepository.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/db/ProductRepository.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/db/ReportRepository.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportWrapper.java delete mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/SaveReportCallback.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveCallback.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveCheckpointCallback.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveDefectCallback.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveDimensionCallback.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveItemCallback.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveProductCallBack.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveReportCallback.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/receiver/NetworkReceiver.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/service/NetworkService.java create mode 100644 app/src/main/java/com/utopiaindustries/qualitychecker/utils/FileUtils.java create mode 100644 app/src/main/res/drawable/hold_bg.xml create mode 100644 app/src/main/res/drawable/ic_down.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 022ab29..ddb2e84 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -2,5 +2,6 @@ \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 3272e3d..bc4c771 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,6 @@ plugins { alias(libs.plugins.androidApplication) } - android { namespace 'com.utopiaindustries.qualitychecker' compileSdk 34 @@ -45,10 +44,9 @@ dependencies { 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' + implementation 'com.squareup.okhttp3:okhttp:4.9.3' } - } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fba3db2..a83ff78 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,7 +10,7 @@ - - + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/ApiService.java b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/ApiService.java index 28eb4f8..d357ab7 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/ApiService.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/ApiService.java @@ -55,10 +55,13 @@ public interface ApiService { @GET( "rest/uic/inspection-report/defects" ) Call> fetchDefects(); +// @GET( "rest/uic/inspection-report/dimensions" ) +// Call> fetchDimensions( +// @Query("sku") String sku +// ); + @GET( "rest/uic/inspection-report/dimensions" ) - Call> fetchDimensions( - @Query("sku") String sku - ); + Call> fetchDimensions(); @GET( "rest/hrms/employees/attendance") Call fetchEmployeePhoto( @@ -82,4 +85,7 @@ public interface ApiService { @GET( "rest/uic/items/units" ) Call> fetchItemUnits(); + + @GET( "rest/uic/cosmos-products/" ) + Call> fetchAllProducts(); } diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/RetrofitClient.java b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/RetrofitClient.java index 738ff01..dac0a01 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/RetrofitClient.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/RetrofitClient.java @@ -3,14 +3,23 @@ package com.utopiaindustries.qualitychecker.apiservice; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitClient { - private final static String BASE_URL = "https://portal.utopiaindustries.pk/uind/"; + private final static String BASE_URL = "https://portal.utopiaindustries.pk/uind/"; // private final static String BASE_URL = "http://192.168.91.16:8080/uind/"; private static Retrofit retrofit; @@ -21,19 +30,17 @@ public class RetrofitClient { .registerTypeAdapter(Boolean.class, new BooleanTypeAdapter()) .create(); - if ( retrofit == null ) { - OkHttpClient okHttpClient = new OkHttpClient.Builder() - .connectTimeout(60, TimeUnit.SECONDS) - .readTimeout(60, TimeUnit.SECONDS) - .writeTimeout(60, TimeUnit.SECONDS) - .build(); - - retrofit = new Retrofit.Builder() - .baseUrl( BASE_URL ) - .client( okHttpClient ) - .addConverterFactory( GsonConverterFactory.create( gson ) ) - .build(); + if (retrofit == null) { + try { + retrofit = new Retrofit.Builder() + .baseUrl(BASE_URL) + .client( SSLCheckHttpClient.getOkHttpClient() ) + .addConverterFactory(GsonConverterFactory.create(gson)) + .build(); + } catch (Exception e) { + throw new RuntimeException(e); + } } return retrofit; } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/SSLCheckHttpClient.java b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/SSLCheckHttpClient.java new file mode 100644 index 0000000..2da4af6 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/SSLCheckHttpClient.java @@ -0,0 +1,52 @@ +package com.utopiaindustries.qualitychecker.apiservice; + +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import okhttp3.OkHttpClient; + +public class SSLCheckHttpClient { + public static OkHttpClient getOkHttpClient() throws NoSuchAlgorithmException, KeyManagementException { + // Create a trust manager that does not validate certificate chains + final TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + } + }; + + // Install the all-trusting trust manager + final SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + + // Create an ssl socket factory with our all-trusting manager + final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); + + + return new OkHttpClient.Builder() + .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]) + .hostnameVerifier((hostname, session) -> true) + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .writeTimeout(60, TimeUnit.SECONDS) + .build(); + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/async/ImageProcessor.java b/app/src/main/java/com/utopiaindustries/qualitychecker/async/ImageProcessor.java index a41cc9e..8db0bc9 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/async/ImageProcessor.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/async/ImageProcessor.java @@ -28,21 +28,18 @@ public class ImageProcessor { } public void compressImageFromUriAsync(final Context context, final Uri uri, final int maxSizeKB, final OnImageCompressedListener listener) { - backgroundHandler.post(new Runnable() { - @Override - public void run() { - byte[] imageData = getBytesFromUri(context, uri); - if (imageData != null) { - final byte[] compressedData = compressImageToMaxSize(imageData, maxSizeKB); - mainHandler.post(() -> listener.onImageCompressed(compressedData)); - } else { - mainHandler.post(new Runnable() { - @Override - public void run() { - listener.onImageCompressed(null); - } - }); - } + backgroundHandler.post(() -> { + byte[] imageData = getBytesFromUri(context, uri); + if (imageData != null) { + final byte[] compressedData = compressImageToMaxSize(imageData, maxSizeKB); + mainHandler.post(() -> listener.onImageCompressed(compressedData)); + } else { + mainHandler.post(new Runnable() { + @Override + public void run() { + listener.onImageCompressed(null); + } + }); } }); } diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/db/CheckpointRepository.java b/app/src/main/java/com/utopiaindustries/qualitychecker/db/CheckpointRepository.java new file mode 100644 index 0000000..af3418d --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/db/CheckpointRepository.java @@ -0,0 +1,85 @@ +package com.utopiaindustries.qualitychecker.db; + +import android.annotation.SuppressLint; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint; +import com.utopiaindustries.qualitychecker.models.InspectionDimension; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class CheckpointRepository { + + private final DatabaseHelper dbHelper; + private final SQLiteDatabase database; + private final ExecutorService executorService; + + public CheckpointRepository( Context context ) { + dbHelper = new DatabaseHelper ( context ); + database = dbHelper.getWritableDatabase(); + executorService = Executors.newSingleThreadExecutor(); + } + + /* + * Insert list of checkpoints in batch + * */ + public void insert( List checkPoints ) { + executorService.execute(() -> { + database.beginTransaction(); + try { + for ( InspectionCheckPoint checkPoint : checkPoints ) { + ContentValues values = new ContentValues(); + values.put(DatabaseHelper.CHECKPOINT_COLUMN_ID, checkPoint.getId() ); + values.put(DatabaseHelper.CHECKPOINT_COLUMN_TITLE, checkPoint.getTitle() ); + values.put(DatabaseHelper.CHECKPOINT_COLUMN_CATEGORY, checkPoint.getCategory() ); + database.insertWithOnConflict(DatabaseHelper.CHECKPOINT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE); + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + close(); + } + }); + } + + + @SuppressLint("Range") + public List findAll( ) { + Cursor cursor = database.query( DatabaseHelper.CHECKPOINT_TABLE_NAME, + null, + null, + null, + null, + null, + null); + + List checkPoints = new ArrayList<>(); + if (cursor != null && cursor.moveToFirst()) { + do { + InspectionCheckPoint checkPoint = new InspectionCheckPoint(); + checkPoint.setId(cursor.getLong( cursor.getColumnIndex(DatabaseHelper.CHECKPOINT_COLUMN_ID ))); + checkPoint.setTitle(cursor.getString(cursor.getColumnIndex(DatabaseHelper.CHECKPOINT_COLUMN_TITLE) )); + checkPoint.setCategory(cursor.getString(cursor.getColumnIndex(DatabaseHelper.CHECKPOINT_COLUMN_CATEGORY ))); + checkPoints.add( checkPoint ); + } while ( cursor.moveToNext() ); + cursor.close(); + } + close(); + return checkPoints; + } + + /* + * Close the database + */ + public void close() { + dbHelper.close(); + executorService.shutdown(); + } + +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/db/DatabaseHelper.java b/app/src/main/java/com/utopiaindustries/qualitychecker/db/DatabaseHelper.java new file mode 100644 index 0000000..8099a0c --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/db/DatabaseHelper.java @@ -0,0 +1,138 @@ +package com.utopiaindustries.qualitychecker.db; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +public class DatabaseHelper extends SQLiteOpenHelper { + + private static final int DATABASE_VERSION = 1; + + private static final String DATABASE_NAME = "inventory"; + // Table and columns + public static final String PRODUCT_TABLE_NAME = "product"; + public static final String PRODUCT_COLUMN_ASIN = "asin"; + public static final String PRODUCT_COLUMN_PARENT_ASIN = "parentAsin"; + public static final String PRODUCT_COLUMN_MARKETPLACE = "marketplace"; + public static final String PRODUCT_COLUMN_SKU = "sku"; + public static final String PRODUCT_COLUMN_TITLE = "title"; + public static final String PRODUCT_COLUMN_HS_CODE = "hsCode"; + public static final String PRODUCT_COLUMN_MODEL_NUMBER = "modelNumber"; + public static final String PRODUCT_COLUMN_ITEM_PER_BOX = "itemPerBox"; + public static final String PRODUCT_COLUMN_SM_COLOR = "smColor"; + public static final String PRODUCT_COLUMN_SM_SIZE = "smSize"; + public static final String PRODUCT_COLUMN_SM_ITEM_NAME = "smItemName"; + public static final String PRODUCT_COLUMN_ITEM_PER_PACK = "itemPerPack"; + public static final String PRODUCT_COLUMN_INVENTORY = "inventory"; + public static final String PRODUCT_COLUMN_CATEGORY = "category"; + + /* + * dimension table + */ + public static final String INSPECTION_DIMENSION_TABLE_NAME = "dimension"; + public static final String DIMENSION_COLUMN_ID = "id"; + public static final String DIMENSION_COLUMN_TITLE = "title"; + public static final String DIMENSION_COLUMN_CATEGORY = "category"; + + /* + * checkpoints table + * */ + public static final String CHECKPOINT_TABLE_NAME = "checkpoint"; + public static final String CHECKPOINT_COLUMN_ID = "id"; + public static final String CHECKPOINT_COLUMN_TITLE = "title"; + public static final String CHECKPOINT_COLUMN_CATEGORY = "category"; + + /* + * defect table + * */ + public static final String DEFECT_TABLE_NAME = "defect"; + public static final String DEFECT_COLUMN_DEFECT = "defect"; + public static final String DEFECT_COLUMN_CATEGORY = "category"; + + /* + * unit table + * */ + public static final String UNIT_TABLE_NAME = "unit"; + public static final String UNIT_COLUMN_ID = "id"; + public static final String UNIT_COLUMN_TITLE = "title"; + + /* + * report table + * */ + public static final String REPORT_TABLE_NAME = "report"; + public static final String REPORT_COLUMN_ID = "id"; + public static final String REPORT_COLUMN_CONTENT = "content"; + public static final String REPORT_COLUMN_SYNCED = "synced"; + + public DatabaseHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + // creating product table + String CREATE_PRODUCT_TABLE = "CREATE TABLE " + PRODUCT_TABLE_NAME + "(" + + PRODUCT_COLUMN_ASIN + " TEXT," + + PRODUCT_COLUMN_PARENT_ASIN + " TEXT," + + PRODUCT_COLUMN_MARKETPLACE + " TEXT," + + PRODUCT_COLUMN_SKU + " TEXT," + + PRODUCT_COLUMN_TITLE + " TEXT," + + PRODUCT_COLUMN_HS_CODE + " TEXT," + + PRODUCT_COLUMN_MODEL_NUMBER + " TEXT," + + PRODUCT_COLUMN_ITEM_PER_BOX + " INTEGER," + + PRODUCT_COLUMN_SM_COLOR + " TEXT," + + PRODUCT_COLUMN_SM_SIZE + " TEXT," + + PRODUCT_COLUMN_SM_ITEM_NAME + " TEXT," + + PRODUCT_COLUMN_ITEM_PER_PACK + " INTEGER," + + PRODUCT_COLUMN_INVENTORY + " INTEGER," + + PRODUCT_COLUMN_CATEGORY + " TEXT," + + "PRIMARY KEY (" + PRODUCT_COLUMN_ASIN + ", " + PRODUCT_COLUMN_MARKETPLACE + ", " + PRODUCT_COLUMN_SKU + ")" + + ")"; + + + String CREATE_INSPECTION_DIMENSION_TABLE = "CREATE TABLE " + INSPECTION_DIMENSION_TABLE_NAME + " (" + + DIMENSION_COLUMN_ID + " INTEGER PRIMARY KEY," + + DIMENSION_COLUMN_TITLE + " TEXT NOT NULL," + + DIMENSION_COLUMN_CATEGORY + " TEXT NOT NULL);"; + + String CREATE_CHECKPOINT_TABLE = "CREATE TABLE " + CHECKPOINT_TABLE_NAME + " (" + + CHECKPOINT_COLUMN_ID + " INTEGER PRIMARY KEY," + + CHECKPOINT_COLUMN_TITLE + " TEXT NOT NULL," + + CHECKPOINT_COLUMN_CATEGORY + " TEXT NOT NULL);"; + + String CREATE_DEFECT_TABLE = "CREATE TABLE " + DEFECT_TABLE_NAME + " (" + + DEFECT_COLUMN_DEFECT + " TEXT NOT NULL," + + DEFECT_COLUMN_CATEGORY + " TEXT NOT NULL," + + "PRIMARY KEY (" + DEFECT_COLUMN_DEFECT + ", " + DEFECT_COLUMN_CATEGORY + ")" + + ")"; + + + String CREATE_UNIT_TABLE = "CREATE TABLE " + UNIT_TABLE_NAME + " (" + + UNIT_COLUMN_ID + " INTEGER PRIMARY KEY," + + UNIT_COLUMN_TITLE + " TEXT NOT NULL )"; + + String CREATE_REPORT_TABLE = "CREATE TABLE " + REPORT_TABLE_NAME + " (" + + REPORT_COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + + REPORT_COLUMN_CONTENT + " TEXT NOT NULL," + + REPORT_COLUMN_SYNCED + " INTEGER DEFAULT 0 CHECK(synced IN (0, 1))" + + ")"; + + db.execSQL( CREATE_PRODUCT_TABLE ); + db.execSQL( CREATE_INSPECTION_DIMENSION_TABLE ); + db.execSQL( CREATE_CHECKPOINT_TABLE ); + db.execSQL( CREATE_DEFECT_TABLE ); + db.execSQL( CREATE_UNIT_TABLE ); + db.execSQL( CREATE_REPORT_TABLE ); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + db.execSQL( "DROP TABLE IF EXISTS " + PRODUCT_TABLE_NAME); + db.execSQL( "DROP TABLE IF EXISTS " + INSPECTION_DIMENSION_TABLE_NAME ); + db.execSQL( "DROP TABLE IF EXISTS " + CHECKPOINT_TABLE_NAME ); + db.execSQL( "DROP TABLE IF EXISTS " + DEFECT_TABLE_NAME ); + db.execSQL( "DROP TABLE IF EXISTS " + UNIT_TABLE_NAME ); + db.execSQL( "DROP TABLE IF EXISTS " + REPORT_TABLE_NAME ); + onCreate(db); + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/db/DefectRepository.java b/app/src/main/java/com/utopiaindustries/qualitychecker/db/DefectRepository.java new file mode 100644 index 0000000..c2d821f --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/db/DefectRepository.java @@ -0,0 +1,82 @@ +package com.utopiaindustries.qualitychecker.db; + +import android.annotation.SuppressLint; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint; +import com.utopiaindustries.qualitychecker.models.InspectionDefect; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class DefectRepository { + + private final DatabaseHelper dbHelper; + private final SQLiteDatabase database; + private final ExecutorService executorService; + + public DefectRepository( Context context ) { + dbHelper = new DatabaseHelper ( context ); + database = dbHelper.getWritableDatabase(); + executorService = Executors.newSingleThreadExecutor(); + } + + + /* + * Insert list of defects in batch + * */ + public void insert( List defects ) { + executorService.execute(() -> { + database.beginTransaction(); + try { + for ( InspectionDefect defect : defects ) { + ContentValues values = new ContentValues(); + values.put(DatabaseHelper.DEFECT_COLUMN_DEFECT, defect.getDefect() ); + values.put(DatabaseHelper.DEFECT_COLUMN_CATEGORY, defect.getCategory() ); + database.insertWithOnConflict(DatabaseHelper.DEFECT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE); + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + close(); + } + }); + } + + @SuppressLint("Range") + public List findAll( ) { + Cursor cursor = database.query( DatabaseHelper.DEFECT_TABLE_NAME, + null, + null, + null, + null, + null, + null); + + List defects = new ArrayList<>(); + if ( cursor != null && cursor.moveToFirst() ) { + do { + InspectionDefect defect = new InspectionDefect(); + defect.setCategory( cursor.getString( cursor.getColumnIndex(DatabaseHelper.DEFECT_COLUMN_CATEGORY ))); + defect.setDefect( cursor.getString( cursor.getColumnIndex(DatabaseHelper.DEFECT_COLUMN_DEFECT) )); + defects.add( defect ); + } while ( cursor.moveToNext() ); + cursor.close(); + } + close(); + return defects; + } + + /* + * Close the database + */ + public void close() { + dbHelper.close(); + executorService.shutdown(); + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/db/DimensionRepository.java b/app/src/main/java/com/utopiaindustries/qualitychecker/db/DimensionRepository.java new file mode 100644 index 0000000..b2f96da --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/db/DimensionRepository.java @@ -0,0 +1,97 @@ +package com.utopiaindustries.qualitychecker.db; + +import android.annotation.SuppressLint; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.utopiaindustries.qualitychecker.models.InspectionDimension; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class DimensionRepository { + + private final DatabaseHelper dbHelper; + private final SQLiteDatabase database; + private final ExecutorService executorService; + + public DimensionRepository( Context context ) { + dbHelper = new DatabaseHelper ( context ); + database = dbHelper.getWritableDatabase(); + executorService = Executors.newSingleThreadExecutor(); + } + + /* + * Insert list of dimension in batch + * */ + public void insert( List dimensions) { + executorService.execute(() -> { + database.beginTransaction(); + try { + for ( InspectionDimension dimension : dimensions ) { + ContentValues values = new ContentValues(); + values.put(DatabaseHelper.DIMENSION_COLUMN_ID, dimension.getId() ); + values.put(DatabaseHelper.DIMENSION_COLUMN_TITLE, dimension.getTitle() ); + values.put(DatabaseHelper.DIMENSION_COLUMN_CATEGORY, dimension.getCategory() ); + database.insertWithOnConflict(DatabaseHelper.INSPECTION_DIMENSION_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE); + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + close(); + } + }); + } + + + @SuppressLint("Range") + public List findByCategory(String category) { + + if( category == null ){ + category = "OTHER"; + } + + String selection = DatabaseHelper.DIMENSION_COLUMN_CATEGORY + "=?"; + String[] selectionArgs = {category}; + + Cursor cursor = database.query(DatabaseHelper.INSPECTION_DIMENSION_TABLE_NAME, + null, + selection, + selectionArgs, + null, + null, + null); + + List dimensions = new ArrayList<>(); + + if ( cursor != null && cursor.moveToFirst() ) { + do { + InspectionDimension dimension = new InspectionDimension(); + dimension.setId(cursor.getLong( cursor.getColumnIndex(DatabaseHelper.DIMENSION_COLUMN_ID ))); + dimension.setTitle(cursor.getString(cursor.getColumnIndex(DatabaseHelper.DIMENSION_COLUMN_TITLE))); + dimension.setCategory(cursor.getString(cursor.getColumnIndex(DatabaseHelper.DIMENSION_COLUMN_CATEGORY))); + dimensions.add( dimension ); + } while ( cursor.moveToNext() ); + cursor.close(); + } + // + if ( dimensions.isEmpty() && !"OTHER".equalsIgnoreCase( category ) ) { + return findByCategory( "OTHER" ); + } + close(); + return dimensions; + } + + /* + * Close the database + */ + public void close() { + dbHelper.close(); + executorService.shutdown(); + } + +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/db/ItemRepository.java b/app/src/main/java/com/utopiaindustries/qualitychecker/db/ItemRepository.java new file mode 100644 index 0000000..c94172f --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/db/ItemRepository.java @@ -0,0 +1,82 @@ +package com.utopiaindustries.qualitychecker.db; + +import android.annotation.SuppressLint; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint; +import com.utopiaindustries.qualitychecker.models.ItemUnit; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ItemRepository { + + private final DatabaseHelper dbHelper; + private final SQLiteDatabase database; + private final ExecutorService executorService; + + public ItemRepository( Context context ) { + dbHelper = new DatabaseHelper ( context ); + database = dbHelper.getWritableDatabase(); + executorService = Executors.newSingleThreadExecutor(); + } + + + /* + * Insert list of unit in batch + * */ + public void insert( List units ) { + executorService.execute(() -> { + database.beginTransaction(); + try { + for ( ItemUnit unit : units ) { + ContentValues values = new ContentValues(); + values.put(DatabaseHelper.UNIT_COLUMN_ID, unit.getId() ); + values.put(DatabaseHelper.UNIT_COLUMN_TITLE, unit.getTitle() ); + database.insertWithOnConflict(DatabaseHelper.UNIT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE ); + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + close(); + } + }); + } + + @SuppressLint("Range") + public List findAll( ) { + Cursor cursor = database.query( DatabaseHelper.UNIT_TABLE_NAME, + null, + null, + null, + null, + null, + null); + + List units = new ArrayList<>(); + if (cursor != null && cursor.moveToFirst()) { + do { + ItemUnit unit = new ItemUnit(); + unit.setId(cursor.getLong( cursor.getColumnIndex(DatabaseHelper.UNIT_COLUMN_ID ))); + unit.setTitle(cursor.getString(cursor.getColumnIndex(DatabaseHelper.UNIT_COLUMN_TITLE) )); + units.add( unit ); + } while ( cursor.moveToNext() ); + cursor.close(); + } + close(); + return units; + } + + /* + * Close the database + */ + public void close() { + dbHelper.close(); + executorService.shutdown(); + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/db/ProductRepository.java b/app/src/main/java/com/utopiaindustries/qualitychecker/db/ProductRepository.java new file mode 100644 index 0000000..7222574 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/db/ProductRepository.java @@ -0,0 +1,181 @@ +package com.utopiaindustries.qualitychecker.db; + +import android.annotation.SuppressLint; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.utopiaindustries.qualitychecker.models.Product; + +import java.util.ArrayList; +import java.util.List; + +public class ProductRepository { + + private final DatabaseHelper dbHelper; + private final SQLiteDatabase database; + private final ExecutorService executorService; + + + public ProductRepository( Context context ) { + dbHelper = new DatabaseHelper ( context ); + database = dbHelper.getWritableDatabase(); + executorService = Executors.newSingleThreadExecutor(); + } + + /* + * Insert list of products in batch + * */ + public void insert( List products) { + executorService.execute(() -> { + database.beginTransaction(); + try { + for (Product product : products) { + ContentValues values = new ContentValues(); + values.put(DatabaseHelper.PRODUCT_COLUMN_ASIN, product.getAsin()); + values.put(DatabaseHelper.PRODUCT_COLUMN_PARENT_ASIN, product.getParentAsin()); + values.put(DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE, product.getMarketplace()); + values.put(DatabaseHelper.PRODUCT_COLUMN_SKU, product.getSku()); + values.put(DatabaseHelper.PRODUCT_COLUMN_TITLE, product.getTitle()); + values.put(DatabaseHelper.PRODUCT_COLUMN_HS_CODE, product.getHsCode()); + values.put(DatabaseHelper.PRODUCT_COLUMN_MODEL_NUMBER, product.getModelNumber()); + values.put(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_BOX, product.getItemPerBox()); + values.put(DatabaseHelper.PRODUCT_COLUMN_SM_COLOR, product.getSmColor()); + values.put(DatabaseHelper.PRODUCT_COLUMN_SM_SIZE, product.getSmSize()); + values.put(DatabaseHelper.PRODUCT_COLUMN_SM_ITEM_NAME, product.getSmItemName()); + values.put(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_PACK, product.getItemPerPack()); + values.put(DatabaseHelper.PRODUCT_COLUMN_INVENTORY, product.getInventory()); + values.put(DatabaseHelper.PRODUCT_COLUMN_CATEGORY, product.getCategory()); + database.insertWithOnConflict(DatabaseHelper.PRODUCT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE); + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + close(); + } + }); + } + + /* + * insert single product + * */ + public void insert(Product product) { + executorService.execute(() -> { + ContentValues values = new ContentValues(); + values.put(DatabaseHelper.PRODUCT_COLUMN_ASIN, product.getAsin()); + values.put(DatabaseHelper.PRODUCT_COLUMN_PARENT_ASIN, product.getParentAsin()); + values.put(DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE, product.getMarketplace()); + values.put(DatabaseHelper.PRODUCT_COLUMN_SKU, product.getSku()); + values.put(DatabaseHelper.PRODUCT_COLUMN_TITLE, product.getTitle()); + values.put(DatabaseHelper.PRODUCT_COLUMN_HS_CODE, product.getHsCode()); + values.put(DatabaseHelper.PRODUCT_COLUMN_MODEL_NUMBER, product.getModelNumber()); + values.put(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_BOX, product.getItemPerBox()); + values.put(DatabaseHelper.PRODUCT_COLUMN_SM_COLOR, product.getSmColor()); + values.put(DatabaseHelper.PRODUCT_COLUMN_SM_SIZE, product.getSmSize()); + values.put(DatabaseHelper.PRODUCT_COLUMN_SM_ITEM_NAME, product.getSmItemName()); + values.put(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_PACK, product.getItemPerPack()); + values.put(DatabaseHelper.PRODUCT_COLUMN_INVENTORY, product.getInventory()); + values.put(DatabaseHelper.PRODUCT_COLUMN_CATEGORY, product.getCategory()); + + database.insertWithOnConflict(DatabaseHelper.PRODUCT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE); + close(); + }); + } + + /* + * Retrieve product by sku + * */ + @SuppressLint("Range") + public List getProductBySku(String sku) { + String selection = DatabaseHelper.PRODUCT_COLUMN_SKU + "=?"; + String[] selectionArgs = {sku}; + + Cursor cursor = database.query(DatabaseHelper.PRODUCT_TABLE_NAME, + null, + selection, + selectionArgs, + null, null, null); + + List products = new ArrayList<>(); + + if (cursor != null && cursor.moveToFirst()) { + do { + Product product = new Product(); + product.setAsin(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ASIN))); + product.setParentAsin(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_PARENT_ASIN))); + product.setMarketplace(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE))); + product.setSku(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SKU))); + product.setTitle(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_TITLE))); + product.setHsCode(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_HS_CODE))); + product.setModelNumber(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_MODEL_NUMBER))); + product.setItemPerBox(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_BOX))); + product.setSmColor(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_COLOR))); + product.setSmSize(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_SIZE))); + product.setSmItemName(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_ITEM_NAME))); + product.setItemPerPack(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_PACK))); + product.setInventory(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_INVENTORY))); + product.setCategory(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_CATEGORY))); + + products.add( product ); + } while ( cursor.moveToNext() ); + cursor.close(); + } + close(); + return products; + } + + /* + * Retrieve products + * */ + @SuppressLint("Range") + public Product getProduct(String asin, String marketplace, String sku) { + String selection = DatabaseHelper.PRODUCT_COLUMN_ASIN + "=? AND " + + DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE + "=? AND " + + DatabaseHelper.PRODUCT_COLUMN_SKU + "=?"; + String[] selectionArgs = {asin, marketplace, sku}; + + Cursor cursor = database.query(DatabaseHelper.PRODUCT_TABLE_NAME, + null, + selection, + selectionArgs, + null, null, null); + + if (cursor != null && cursor.moveToFirst()) { + Product product = new Product(); + product.setAsin( cursor.getString( cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ASIN ) )); + product.setParentAsin( cursor.getString( cursor.getColumnIndex( DatabaseHelper.PRODUCT_COLUMN_PARENT_ASIN ) )); + product.setMarketplace( cursor.getString( cursor.getColumnIndex( DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE ))); + product.setSku(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SKU))); + product.setTitle(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_TITLE))); + product.setHsCode(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_HS_CODE))); + product.setModelNumber(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_MODEL_NUMBER))); + product.setItemPerBox(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_BOX))); + product.setSmColor(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_COLOR))); + product.setSmSize(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_SIZE))); + product.setSmItemName(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_ITEM_NAME))); + product.setItemPerPack(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_PACK))); + product.setInventory(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_INVENTORY))); + product.setCategory(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_CATEGORY))); + + cursor.close(); + close(); + return product; + } + + if (cursor != null) { + cursor.close(); + } + return null; + } + + /* + * Close the database + */ + public void close() { + dbHelper.close(); + executorService.shutdown(); + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/db/ReportRepository.java b/app/src/main/java/com/utopiaindustries/qualitychecker/db/ReportRepository.java new file mode 100644 index 0000000..b20d019 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/db/ReportRepository.java @@ -0,0 +1,129 @@ +package com.utopiaindustries.qualitychecker.db; + +import android.annotation.SuppressLint; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.utopiaindustries.qualitychecker.models.InspectionReportWrapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; + +public class ReportRepository { + + private final DatabaseHelper dbHelper; + private SQLiteDatabase database; + private final ExecutorService executorService; + + public ReportRepository(Context context) { + dbHelper = new DatabaseHelper(context); + executorService = Executors.newSingleThreadExecutor(); + } + + private void openDatabase() { + if (database == null || !database.isOpen()) { + database = dbHelper.getWritableDatabase(); + } + } + + public void insert(InspectionReportWrapper wrapper) { + executeSafely(() -> { + openDatabase(); + database.beginTransaction(); + try { + ContentValues values = new ContentValues(); + values.put(DatabaseHelper.REPORT_COLUMN_CONTENT, wrapper.getContent()); + values.put(DatabaseHelper.REPORT_COLUMN_SYNCED, wrapper.isSynced()); + database.insertWithOnConflict(DatabaseHelper.REPORT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE); + database.setTransactionSuccessful(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + database.endTransaction(); + close(); + } + }); + } + + public void updateSyncStatus(long id) { + executeSafely(() -> { + openDatabase(); + database.beginTransaction(); + try { + ContentValues values = new ContentValues(); + values.put(DatabaseHelper.REPORT_COLUMN_SYNCED, true ); // Set the synced value to true + String whereClause = DatabaseHelper.REPORT_COLUMN_ID + " = ?"; + String[] whereArgs = {String.valueOf(id)}; + database.update(DatabaseHelper.REPORT_TABLE_NAME, values, whereClause, whereArgs); + database.setTransactionSuccessful(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + database.endTransaction(); + close(); + } + }); + } + + @SuppressLint("Range") + public List findAllUnsynced() { + List reports = new ArrayList<>(); + openDatabase(); + String selection = DatabaseHelper.REPORT_COLUMN_SYNCED + " = ?"; + String[] selectionArgs = {"0"}; + + try (Cursor cursor = database.query(DatabaseHelper.REPORT_TABLE_NAME, + null, + selection, + selectionArgs, + null, + null, + null)) { + + if (cursor != null && cursor.moveToFirst()) { + do { + InspectionReportWrapper wrapper = new InspectionReportWrapper(); + wrapper.setId(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.REPORT_COLUMN_ID))); + wrapper.setContent(cursor.getString(cursor.getColumnIndex(DatabaseHelper.REPORT_COLUMN_CONTENT))); + wrapper.setSynced(cursor.getInt(cursor.getColumnIndex(DatabaseHelper.REPORT_COLUMN_SYNCED)) == 1); + reports.add(wrapper); + } while (cursor.moveToNext()); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + close(); + } + return reports; + } + + /* + * Close the database when all operations are complete + */ + public void close() { + if (database != null && database.isOpen()) { + database.close(); + } + } + + /* + * Executes a task safely, ensuring the ExecutorService is still active + */ + private void executeSafely(Runnable task) { + try { + if (!executorService.isShutdown()) { + executorService.submit(task); + } else { + // Handle the situation when the executor is already shut down + System.err.println("Task execution rejected because ExecutorService is shut down"); + } + } catch (RejectedExecutionException e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/Dimension.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/Dimension.java index 46de649..9ba63e8 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/Dimension.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/Dimension.java @@ -1,7 +1,10 @@ package com.utopiaindustries.qualitychecker.models; -public class Dimension { +import java.io.Serializable; +public class Dimension implements Serializable { + + private static final long serialVersionUID = 1L; private String type; private float actual; private float required; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionCheckPoint.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionCheckPoint.java index 885d459..a7995d6 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionCheckPoint.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionCheckPoint.java @@ -1,8 +1,11 @@ package com.utopiaindustries.qualitychecker.models; -public class InspectionCheckPoint { +import java.io.Serializable; +public class InspectionCheckPoint implements Serializable { + + private static final long serialVersionUID = 1L; private long id; private String title; private String category; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDefect.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDefect.java index e119982..d6b9de6 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDefect.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDefect.java @@ -1,7 +1,11 @@ package com.utopiaindustries.qualitychecker.models; -public class InspectionDefect { +import java.io.Serial; +import java.io.Serializable; +public class InspectionDefect implements Serializable { + + private static final long serialVersionUID = 1L; private String category; private String defect; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDimension.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDimension.java index 4bfd5ec..fe6d90f 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDimension.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDimension.java @@ -1,7 +1,10 @@ package com.utopiaindustries.qualitychecker.models; -public class InspectionDimension { +import java.io.Serializable; +public class InspectionDimension implements Serializable { + + private static final long serialVersionUID = 1L; private long id; private String title; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemCheckPoint.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemCheckPoint.java index 58738c9..4851fe9 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemCheckPoint.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemCheckPoint.java @@ -1,11 +1,15 @@ package com.utopiaindustries.qualitychecker.models; +import androidx.annotation.NonNull; + +import java.io.Serializable; import java.util.Arrays; import java.util.List; import java.util.UUID; -public class InspectionItemCheckPoint { +public class InspectionItemCheckPoint implements Serializable { + private static final long serialVersionUID = 1L; private long id; private long inspectionItemId; private String title; @@ -118,6 +122,7 @@ public class InspectionItemCheckPoint { this.quantities = quantities; } + @NonNull @Override public String toString() { return "InspectionItemCheckPoint{" + @@ -126,9 +131,13 @@ public class InspectionItemCheckPoint { ", title='" + title + '\'' + ", checked=" + checked + ", remarks='" + remarks + '\'' + + ", defectSeverites=" + defectSeverites + + ", defectTitles=" + defectTitles + + ", quantities=" + quantities + ", defects=" + defects + ", file=" + Arrays.toString(file) + ", imagePath='" + imagePath + '\'' + + ", uuid=" + uuid + '}'; } diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDefect.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDefect.java index 73a66f6..5ce0d93 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDefect.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDefect.java @@ -1,9 +1,11 @@ package com.utopiaindustries.qualitychecker.models; +import java.io.Serializable; import java.util.Arrays; -public class InspectionItemDefect { +public class InspectionItemDefect implements Serializable { + private static final long serialVersionUID = 1L; private long id; private long cpId; private String title; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDimension.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDimension.java index c18fc26..2e8fd9f 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDimension.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDimension.java @@ -1,8 +1,11 @@ package com.utopiaindustries.qualitychecker.models; -public class InspectionItemDimension { +import java.io.Serializable; +public class InspectionItemDimension implements Serializable { + + private static final long serialVersionUID = 1L; private long id; private long inspectionItemId; private String type; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java index 8888367..7202508 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java @@ -1,9 +1,12 @@ package com.utopiaindustries.qualitychecker.models; import androidx.annotation.NonNull; + +import java.io.Serializable; import java.util.List; -public class InspectionReport { +public class InspectionReport implements Serializable { + private static final long serialVersionUID = 1L; private long id; private boolean fri; @@ -20,6 +23,9 @@ public class InspectionReport { // wrapper List items; + private String filePath; + private long wrapperId; + public InspectionReport(){ this.fri = true; } @@ -120,14 +126,30 @@ public class InspectionReport { this.fri = fri; } - @NonNull + public long getWrapperId() { + return wrapperId; + } + + public void setWrapperId(long wrapperId) { + this.wrapperId = wrapperId; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + @Override public String toString() { return "InspectionReport{" + "id=" + id + + ", fri=" + fri + ", code='" + code + '\'' + ", generatedBy='" + generatedBy + '\'' + - ", generatedAt=" + generatedAt + + ", generatedAt='" + generatedAt + '\'' + ", siteId=" + siteId + ", floorId=" + floorId + ", departmentId=" + departmentId + @@ -135,6 +157,7 @@ public class InspectionReport { ", generalRemarks='" + generalRemarks + '\'' + ", reportResult='" + reportResult + '\'' + ", items=" + items + + ", wrapperId=" + wrapperId + '}'; } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportItem.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportItem.java index 90a1f2f..9d108f2 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportItem.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportItem.java @@ -2,10 +2,12 @@ package com.utopiaindustries.qualitychecker.models; import androidx.annotation.NonNull; +import java.io.Serializable; import java.util.List; -public class InspectionReportItem { +public class InspectionReportItem implements Serializable { + private static final long serialVersionUID = 1L; private long id; private long reportId; private String asin; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportWrapper.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportWrapper.java new file mode 100644 index 0000000..bced2be --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportWrapper.java @@ -0,0 +1,65 @@ +package com.utopiaindustries.qualitychecker.models; + +import java.util.Objects; + +public class InspectionReportWrapper { + + public InspectionReportWrapper() { + } + + public InspectionReportWrapper(long id, String content, boolean synced) { + this.id = id; + this.content = content; + this.synced = synced; + } + + private long id; + private String content; + private boolean synced; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public boolean isSynced() { + return synced; + } + + public void setSynced(boolean synced) { + this.synced = synced; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InspectionReportWrapper that = (InspectionReportWrapper) o; + return id == that.id && synced == that.synced && Objects.equals(content, that.content); + } + + @Override + public int hashCode() { + return Objects.hash(id, content, synced); + } + + @Override + public String toString() { + return "InspectionReportWrapper{" + + "id=" + id + + ", content='" + content + '\'' + + ", synced=" + synced + + '}'; + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/ItemUnit.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/ItemUnit.java index d6e159f..f6f27b8 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/ItemUnit.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/ItemUnit.java @@ -1,7 +1,10 @@ package com.utopiaindustries.qualitychecker.models; -public class ItemUnit { +import java.io.Serializable; + +public class ItemUnit implements Serializable { private long id; + private static final long serialVersionUID = 1L; private String title; public ItemUnit() { diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/Product.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/Product.java index c20d2ea..7bb48ac 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/Product.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/Product.java @@ -1,7 +1,10 @@ package com.utopiaindustries.qualitychecker.models; -public class Product { +import java.io.Serializable; +public class Product implements Serializable { + + private static final long serialVersionUID = 1L; private String asin; private String parentAsin; private String marketplace; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/SaveReportCallback.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/SaveReportCallback.java deleted file mode 100644 index 5a205b9..0000000 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/SaveReportCallback.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.utopiaindustries.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/utopiaindustries/qualitychecker/models/VoiceOfCustomer.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/VoiceOfCustomer.java index cecff4d..63b04c3 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/VoiceOfCustomer.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/VoiceOfCustomer.java @@ -1,6 +1,9 @@ package com.utopiaindustries.qualitychecker.models; -public class VoiceOfCustomer { +import java.io.Serializable; + +public class VoiceOfCustomer implements Serializable { + private static final long serialVersionUID = 1L; private String mskus; private String marketplace; private String itemName; diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveCallback.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveCallback.java new file mode 100644 index 0000000..0801752 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveCallback.java @@ -0,0 +1,6 @@ +package com.utopiaindustries.qualitychecker.models.callback; + +public interface SaveCallback { + void onSuccess(); + void onFailure(Throwable throwable); +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveCheckpointCallback.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveCheckpointCallback.java new file mode 100644 index 0000000..79e592b --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveCheckpointCallback.java @@ -0,0 +1,4 @@ +package com.utopiaindustries.qualitychecker.models.callback; + +public interface SaveCheckpointCallback extends SaveCallback { +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveDefectCallback.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveDefectCallback.java new file mode 100644 index 0000000..7709a2d --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveDefectCallback.java @@ -0,0 +1,4 @@ +package com.utopiaindustries.qualitychecker.models.callback; + +public interface SaveDefectCallback extends SaveCallback{ +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveDimensionCallback.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveDimensionCallback.java new file mode 100644 index 0000000..ddd2e93 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveDimensionCallback.java @@ -0,0 +1,4 @@ +package com.utopiaindustries.qualitychecker.models.callback; + +public interface SaveDimensionCallback extends SaveCallback { +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveItemCallback.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveItemCallback.java new file mode 100644 index 0000000..46414a1 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveItemCallback.java @@ -0,0 +1,4 @@ +package com.utopiaindustries.qualitychecker.models.callback; + +public interface SaveItemCallback extends SaveCallback{ +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveProductCallBack.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveProductCallBack.java new file mode 100644 index 0000000..29c00f2 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveProductCallBack.java @@ -0,0 +1,5 @@ +package com.utopiaindustries.qualitychecker.models.callback; + +public interface SaveProductCallBack extends SaveCallback { + +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveReportCallback.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveReportCallback.java new file mode 100644 index 0000000..efda86c --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/callback/SaveReportCallback.java @@ -0,0 +1,4 @@ +package com.utopiaindustries.qualitychecker.models.callback; + +public interface SaveReportCallback extends SaveCallback{ +} \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/notification/NotificationHelper.java b/app/src/main/java/com/utopiaindustries/qualitychecker/notification/NotificationHelper.java index d8cc071..a04a05f 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/notification/NotificationHelper.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/notification/NotificationHelper.java @@ -13,6 +13,10 @@ public class NotificationHelper { private static final String CHANNEL_ID = "001122"; private static final String CHANNEL_NAME = "QA_App_Channel"; private static final String CHANNEL_DESCRIPTION = "Channel_for_qa_app"; + private static final String PRODUCT_CHANNEL_ID = "6754631"; + private static final String PRODUCT_CHANNEL_NAME= "PRODUCT_NOTIFICATION_CHANNEL"; + public static final String PRODUCT_CHANNEL_DESCRIPTION = "CHANNEL_FOR_PRODUCT"; + public static void showNotification(Context context, String title, String message) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); @@ -34,4 +38,25 @@ public class NotificationHelper { // Show the notification notificationManager.notify(0, builder.build()); } + + public static void showProductNotification(Context context, String title, String message) { + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + + // Create a notification channel for devices running Android Oreo (API 26) and higher + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel(PRODUCT_CHANNEL_ID, PRODUCT_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); + channel.setDescription(PRODUCT_CHANNEL_DESCRIPTION); + notificationManager.createNotificationChannel(channel); + } + + // Build the notification + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, PRODUCT_CHANNEL_ID) + .setSmallIcon(R.drawable.utopia_svg_logo) // Set your notification icon here + .setContentTitle(title) + .setContentText(message) + .setPriority(NotificationCompat.PRIORITY_HIGH ); + + // Show the notification + notificationManager.notify(0, builder.build()); + } } diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/receiver/NetworkReceiver.java b/app/src/main/java/com/utopiaindustries/qualitychecker/receiver/NetworkReceiver.java new file mode 100644 index 0000000..bee8603 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/receiver/NetworkReceiver.java @@ -0,0 +1,32 @@ +package com.utopiaindustries.qualitychecker.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import com.utopiaindustries.qualitychecker.db.ReportRepository; +import com.utopiaindustries.qualitychecker.models.InspectionReport; +import com.utopiaindustries.qualitychecker.models.InspectionReportWrapper; +import com.utopiaindustries.qualitychecker.models.callback.SaveReportCallback; +import com.utopiaindustries.qualitychecker.service.InspectionReportService; +import com.utopiaindustries.qualitychecker.service.NetworkService; +import com.utopiaindustries.qualitychecker.utils.FileUtils; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.ArrayList; +import java.util.List; + +public class NetworkReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting(); + Intent serviceIntent = new Intent( context, NetworkService.class ); + context.startService(serviceIntent); + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/service/InspectionReportService.java b/app/src/main/java/com/utopiaindustries/qualitychecker/service/InspectionReportService.java index a0e37cc..616e0c9 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/service/InspectionReportService.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/service/InspectionReportService.java @@ -1,22 +1,46 @@ package com.utopiaindustries.qualitychecker.service; +import android.content.Context; + import androidx.annotation.NonNull; import com.utopiaindustries.qualitychecker.apiservice.ApiService; import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory; +import com.utopiaindustries.qualitychecker.db.CheckpointRepository; +import com.utopiaindustries.qualitychecker.db.DefectRepository; +import com.utopiaindustries.qualitychecker.db.DimensionRepository; +import com.utopiaindustries.qualitychecker.db.ItemRepository; +import com.utopiaindustries.qualitychecker.db.ProductRepository; +import com.utopiaindustries.qualitychecker.db.ReportRepository; +import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint; import com.utopiaindustries.qualitychecker.models.InspectionDefect; +import com.utopiaindustries.qualitychecker.models.InspectionDimension; import com.utopiaindustries.qualitychecker.models.InspectionItemCheckPoint; import com.utopiaindustries.qualitychecker.models.InspectionItemDefect; import com.utopiaindustries.qualitychecker.models.InspectionReport; -import com.utopiaindustries.qualitychecker.models.SaveReportCallback; +import com.utopiaindustries.qualitychecker.models.InspectionReportWrapper; +import com.utopiaindustries.qualitychecker.models.ItemUnit; +import com.utopiaindustries.qualitychecker.models.Product; +import com.utopiaindustries.qualitychecker.models.callback.SaveCheckpointCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveDefectCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveDimensionCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveItemCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveProductCallBack; +import com.utopiaindustries.qualitychecker.models.callback.SaveReportCallback; import com.utopiaindustries.qualitychecker.store.Store; +import com.utopiaindustries.qualitychecker.utils.FileUtils; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.logging.Handler; import retrofit2.Call; import retrofit2.Callback; @@ -44,7 +68,7 @@ public class InspectionReportService { apiService = ApiServiceFactory.getApiService(); defectTypes = Arrays.asList( "CRITICAL","MINOR","MAJOR" ); dimensionTypes = Arrays.asList( "LENGTH", "WIDTH", "DROP" ); - reportResult = Arrays.asList("PASSED","FAILED"); + reportResult = Arrays.asList("PASSED","FAILED","ON_HOLD"); store = Store.getInstance(); } @@ -86,7 +110,7 @@ public class InspectionReportService { this.reportResult = reportResult; } - private void populateDefectsInBackground(InspectionReport inspectionReport) { + private synchronized void populateDefectsInBackground(InspectionReport inspectionReport) { for (InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints()) { List defectList = getInspectionItemDefects(itemCp); itemCp.setDefects(defectList); @@ -122,49 +146,62 @@ public class InspectionReportService { ); } + private synchronized void saveReportInDb( final Context context, + final InspectionReport inspectionReport, + final SaveReportCallback callback) throws IOException { + try { + // convert into byte array + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream( byteArrayOutputStream ); + objectOutputStream.writeObject( inspectionReport ); + objectOutputStream.flush(); + byte[] bytes = byteArrayOutputStream.toByteArray(); + // write bytes in file + long epochSeconds = System.currentTimeMillis() / 1000; + String fileName = "Report-" + epochSeconds + ".bin"; + String savedPath = FileUtils.writeFile( context, bytes, fileName ); + System.out.println( savedPath ); + new ReportRepository( context ).insert( + new InspectionReportWrapper( 0, savedPath, false ) + ); + callback.onSuccess(); + } catch ( Exception e ){ + callback.onFailure( new Exception( "Failed to Save in DB" ) ); + e.printStackTrace(); + } + } - public void saveReport(InspectionReport inspectionReport , SaveReportCallback callback){ + + public void saveInLocalDb( Context context, + 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() ){ + new Thread(() -> { + populateDefectsInBackground( inspectionReport ); + //post report + try { + saveReportInDb( context, inspectionReport , callback ); + } catch (IOException e) { + throw new RuntimeException(e); + } + }).start(); + } + } + + 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() ){ + new Thread(() -> { populateDefectsInBackground( inspectionReport ); //post report saveReportInBackground( inspectionReport , callback ); }).start(); - - - // populate defects in cp -// for( InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints() ){ -// List defectList = getInspectionItemDefects(itemCp); -// itemCp.setDefects( defectList ); -// } - // post object -// apiService.saveInspectionReport( inspectionReport ).enqueue( -// new Callback>() { -// @Override -// public void onResponse(Call> call, -// Response> response) { -// if ( response.isSuccessful() ) { -// System.out.println( response.body() ); -// if( response.body().get("result").equalsIgnoreCase("success")){ -// callback.onSuccess(); -// } -// else { -// callback.onFailure(new Exception( "Error on submitting report" )); -// } -// } else { -// callback.onFailure(new Exception("API call failed with status code: " + response.code())); -// } -// } -// @Override -// public void onFailure(Call> call, Throwable t) { -// System.out.println( t ); -// callback.onFailure( t ); -// } -// } -// ); } else { callback.onFailure( new Exception("Please Fill the required Fields..") ); } @@ -182,4 +219,181 @@ public class InspectionReportService { } return defectList; } + + + public void fetchAndPopulateProducts( SaveProductCallBack callback, + ProductRepository repository){ + new Thread(() -> { + populateProducts( callback, repository ); + }).start(); + } + + public void fetchAndPopulateDimensions( SaveDimensionCallback callback, + DimensionRepository repository ){ + new Thread(() -> { + populateDimensions( callback, repository ); + }).start(); + } + + public void fetchAndPopulateCheckpoints( SaveCheckpointCallback callback , + CheckpointRepository repository ){ + new Thread(() -> { + populateCheckpoints( callback, repository ); + }).start(); + } + + public void fetchAndPopulateDefects( SaveDefectCallback callback, + DefectRepository repository ){ + new Thread( () -> { + populateDefects( callback, repository ); + }).start(); + } + + public void fetchAndPopulateUnits( SaveItemCallback callback, + ItemRepository repository ){ + new Thread(() -> { + populateUnits( callback, repository ); + }).start(); + } + + + private void populateProducts( SaveProductCallBack callback, + ProductRepository repository ){ + apiService.fetchAllProducts().enqueue( + new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + if (response.isSuccessful()) { + try { + System.out.println( response.body() ); + callback.onSuccess(); + repository.insert( response.body() ); + } catch ( Exception ex ){ + callback.onFailure(new Exception( ex.getMessage() ) ); + } + } else { + callback.onFailure(new Exception("API call failed with status code: " + response.code())); + } + } + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println(t); + callback.onFailure(t); + } + } + ); + } + private void populateDimensions( SaveDimensionCallback callback, + DimensionRepository repository ){ + + apiService.fetchDimensions( ).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + if (response.isSuccessful()) { + try { + System.out.println( response.body() ); + callback.onSuccess(); + repository.insert( response.body() ); + } catch ( Exception ex ){ + callback.onFailure(new Exception( ex.getMessage() ) ); + } + } else { + callback.onFailure(new Exception("API call failed with status code: " + response.code())); + } + + } + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t ); + callback.onFailure( t ); + } + }); + } + + + private void populateCheckpoints( SaveCheckpointCallback callback, + CheckpointRepository repository ){ + + apiService.fetchCheckPoints().enqueue( + new Callback>() { + @Override + public void onResponse( Call> call, + Response> response ) { + if (response.isSuccessful()) { + try { + System.out.println( response.body() ); + callback.onSuccess(); + repository.insert( response.body() ); + } catch ( Exception ex ){ + callback.onFailure(new Exception( ex.getMessage() ) ); + } + } else { + callback.onFailure(new Exception("API call failed with status code: " + response.code())); + } + } + @Override + public void onFailure( Call> call, + Throwable t) { + System.out.println( t ); + callback.onFailure( t ); + } + } + ); + } + + private void populateDefects( SaveDefectCallback callback, + DefectRepository repository ){ + apiService.fetchDefects().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()) { + try { + System.out.println( response.body() ); + callback.onSuccess(); + repository.insert( response.body() ); + } catch ( Exception ex ){ + callback.onFailure(new Exception( ex.getMessage() ) ); + } + } else { + callback.onFailure(new Exception("API call failed with status code: " + response.code())); + } + } + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println( t ); + callback.onFailure( t ); + } + }); + } + + private void populateUnits( SaveItemCallback callback , + ItemRepository repository ){ + apiService.fetchItemUnits().enqueue( + new Callback>() { + @Override + public void onResponse( Call> call, + Response> response) { + if (response.isSuccessful()) { + try { + System.out.println( response.body() ); + callback.onSuccess(); + repository.insert( response.body() ); + } catch ( Exception ex ){ + callback.onFailure(new Exception( ex.getMessage() ) ); + } + } else { + callback.onFailure(new Exception("API call failed with status code: " + response.code())); + } + } + @Override + public void onFailure( Call> call, + Throwable t) { + System.out.println( t ); + callback.onFailure( t ); + } + } + ); + } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/service/NetworkService.java b/app/src/main/java/com/utopiaindustries/qualitychecker/service/NetworkService.java new file mode 100644 index 0000000..a487a8b --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/service/NetworkService.java @@ -0,0 +1,123 @@ +package com.utopiaindustries.qualitychecker.service; + +import android.app.Service; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.util.Log; +import androidx.annotation.Nullable; + +import com.utopiaindustries.qualitychecker.db.ReportRepository; +import com.utopiaindustries.qualitychecker.models.InspectionReport; +import com.utopiaindustries.qualitychecker.models.InspectionReportWrapper; +import com.utopiaindustries.qualitychecker.models.callback.SaveReportCallback; +import com.utopiaindustries.qualitychecker.utils.FileUtils; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.ObjectInputStream; +import java.util.ArrayList; +import java.util.List; + +public class NetworkService extends Service { + + private static final String TAG = "NetworkService"; + + @Override + public void onCreate() { + super.onCreate(); + // Start the connectivity check + startCheckingNetwork(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + // Handle service start logic if needed + return START_STICKY; + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + private void startCheckingNetwork() { + Handler handler = new Handler(); + Runnable runnable = new Runnable() { + @Override + public void run() { + checkNetworkAndPushData(); + handler.postDelayed(this, 1 * 60 * 1000); // Check 5 every minute + } + }; + handler.post(runnable); + } + + private void checkNetworkAndPushData() { + ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + boolean isConnected = activeNetwork != null && activeNetwork.isConnected(); + + if (isConnected) { + Log.i(TAG, "Network is available. Pushing data..."); + // Call your method to push data here + pushDataToInternet(); + } else { + Log.i(TAG, "No network available."); + } + } + + private void pushDataToInternet() { + ReportRepository repository = new ReportRepository( this ); + List reportWrappers = repository.findAllUnsynced(); + InspectionReportService service = InspectionReportService.getInstance(); + try { + List reports = getReports( reportWrappers ); + for ( InspectionReport report : reports ){ + service.saveReport(report, new SaveReportCallback() { + @Override + public void onSuccess() { + // update status + repository.updateSyncStatus( report.getWrapperId() ); + // remove file + FileUtils.deleteFile( report.getFilePath() ); + } + @Override + public void onFailure(Throwable throwable) { + + } + }); + } + } catch ( Exception e ) { + e.printStackTrace(); + } + } + + /* + * map wrapper to reports + * */ + private List getReports(List wrappers ) { + List reports = new ArrayList<>(); + if( ! wrappers.isEmpty() ){ + for( InspectionReportWrapper wrapper : wrappers ){ + try { + // get file from path + byte[] result = FileUtils.readFile( wrapper.getContent() ); + ByteArrayInputStream byteIn = new ByteArrayInputStream( result ); + ObjectInputStream in = new ObjectInputStream(byteIn); + InspectionReport report = ( InspectionReport ) in.readObject(); + report.setWrapperId( wrapper.getId() ); + report.setFilePath( wrapper.getContent() ); + reports.add( report ); + } catch ( Exception e){ + e.printStackTrace(); + } + } + } + return reports; + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/store/Store.java b/app/src/main/java/com/utopiaindustries/qualitychecker/store/Store.java index 17588c2..399da07 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/store/Store.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/store/Store.java @@ -1,7 +1,14 @@ package com.utopiaindustries.qualitychecker.store; +import android.content.Context; +import android.widget.Toast; + import com.utopiaindustries.qualitychecker.apiservice.ApiService; import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory; +import com.utopiaindustries.qualitychecker.db.CheckpointRepository; +import com.utopiaindustries.qualitychecker.db.DefectRepository; +import com.utopiaindustries.qualitychecker.db.ItemRepository; +import com.utopiaindustries.qualitychecker.db.ProductRepository; import com.utopiaindustries.qualitychecker.models.EmployeePhoto; import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint; import com.utopiaindustries.qualitychecker.models.InspectionDefect; @@ -12,6 +19,9 @@ import com.utopiaindustries.qualitychecker.models.InspectionReport; import com.utopiaindustries.qualitychecker.models.InspectionReportItem; import com.utopiaindustries.qualitychecker.models.ItemUnit; import com.utopiaindustries.qualitychecker.models.Product; +import com.utopiaindustries.qualitychecker.models.callback.SaveProductCallBack; +import com.utopiaindustries.qualitychecker.notification.NotificationHelper; +import com.utopiaindustries.qualitychecker.ui.activities.HomeActivity; import java.util.ArrayList; import java.util.Collections; @@ -45,7 +55,7 @@ public class Store { return instance; } - public synchronized void initializeNewReport() { + public synchronized void initializeNewReport( Context context ) { checkPoints = new ArrayList<>(); defects = new ArrayList<>(); dimensions = new ArrayList<>(); @@ -58,85 +68,106 @@ public class Store { 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.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() ); - } - } - ); + CheckpointRepository checkpointRepository = new CheckpointRepository( context ); + checkPoints = checkpointRepository.findAll(); + +// 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() ); +// } +// } +// ); + DefectRepository defectRepository = new DefectRepository( context ); + defects = defectRepository.findAll(); + + List itemCp = new ArrayList<>(); + for( InspectionCheckPoint cp : checkPoints ){ + InspectionItemCheckPoint icp = new InspectionItemCheckPoint(); + icp.setTitle( cp.getTitle() ); + icp.setChecked( false ); + icp.setRemarks(""); + icp.setDefectTitles( new ArrayList<>() ); + icp.setDefectSeverites( new ArrayList<>() ); + icp.setQuantities( new ArrayList<>() ); + itemCp.add( icp ); + } + report.getItems().get( 0 ).setCheckPoints( itemCp ); - 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.setChecked( false ); - icp.setRemarks(""); - icp.setDefectTitles( new ArrayList<>() ); - icp.setDefectSeverites( new ArrayList<>() ); - icp.setQuantities( new ArrayList<>() ); - itemCp.add( icp ); - } - report.getItems().get( 0 ).setCheckPoints( itemCp ); - } - } - @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.setChecked( false ); +// icp.setRemarks(""); +// icp.setDefectTitles( new ArrayList<>() ); +// icp.setDefectSeverites( new ArrayList<>() ); +// icp.setQuantities( new ArrayList<>() ); +// 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.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() ); +// } +// } +// ); + ItemRepository itemRepository = new ItemRepository( context ); + itemUnits = itemRepository.findAll(); } public InspectionReport getReport() { diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/HomeActivity.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/HomeActivity.java index 7c8c9ce..355fef5 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/HomeActivity.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/HomeActivity.java @@ -3,6 +3,7 @@ package com.utopiaindustries.qualitychecker.ui.activities; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.net.ConnectivityManager; @@ -26,12 +27,26 @@ import com.bumptech.glide.Glide; import com.utopiaindustries.qualitychecker.R; import com.utopiaindustries.qualitychecker.apiservice.ApiService; import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory; +import com.utopiaindustries.qualitychecker.db.CheckpointRepository; +import com.utopiaindustries.qualitychecker.db.DefectRepository; +import com.utopiaindustries.qualitychecker.db.DimensionRepository; +import com.utopiaindustries.qualitychecker.db.ItemRepository; +import com.utopiaindustries.qualitychecker.db.ProductRepository; import com.utopiaindustries.qualitychecker.models.EmployeePhoto; import com.utopiaindustries.qualitychecker.models.InspectionReport; +import com.utopiaindustries.qualitychecker.models.callback.SaveCheckpointCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveDefectCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveDimensionCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveItemCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveProductCallBack; +import com.utopiaindustries.qualitychecker.notification.NotificationHelper; +import com.utopiaindustries.qualitychecker.receiver.NetworkReceiver; +import com.utopiaindustries.qualitychecker.service.InspectionReportService; import com.utopiaindustries.qualitychecker.store.Store; import com.utopiaindustries.qualitychecker.ui.adapter.ReportAdapter; import java.util.List; +import java.util.Objects; import retrofit2.Call; import retrofit2.Callback; @@ -39,12 +54,15 @@ import retrofit2.Response; public class HomeActivity extends AppCompatActivity implements View.OnClickListener { - private Button createReportBtn,refreshReportsBtn,logoutBtn; + private Button createReportBtn,refreshReportsBtn,logoutBtn,fetchProductBtn; private RecyclerView recyclerView; private ApiService apiService; private TextView usernameTitle, emptyReportTextView; private ImageView profileImage; private Store store; + private InspectionReportService inspectionReportService; + private NetworkReceiver networkReceiver; + private boolean isReceiverRegistered = false; @SuppressLint("SourceLockedOrientationActivity") @Override @@ -65,9 +83,11 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe // initialize views store = Store.getInstance(); apiService = ApiServiceFactory.getApiService(); + inspectionReportService = InspectionReportService.getInstance(); createReportBtn = findViewById( R.id.create_report_btn ); refreshReportsBtn = findViewById( R.id.refresh_btn ); logoutBtn = findViewById( R.id.logout_btn ); + fetchProductBtn = findViewById( R.id.fetch_product_btn ); recyclerView = findViewById( R.id.reports_recyclerview ); usernameTitle = findViewById( R.id.username_title ); profileImage = findViewById( R.id.profile_image ); @@ -76,6 +96,7 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe refreshReportsBtn.setOnClickListener( this ); createReportBtn.setOnClickListener( this ); logoutBtn.setOnClickListener( this ); + fetchProductBtn.setOnClickListener( this ); recyclerView.setLayoutManager( new LinearLayoutManager( this ) ); @@ -131,12 +152,23 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe refreshReportData(); updateProfileImage(); } + if( id == R.id.fetch_product_btn ){ + if( isNetworkConnected() ) { + fetchAndPopulateProductData(); + fetchAndPopulateDimensionsData(); + fetchAndPopulateCheckpointData(); + fetchAndPopulateDefectsData(); + fetchAndPopulateUnitsData(); + } else { + Toast.makeText( this, "network not available", Toast.LENGTH_LONG ).show(); + } + } } private void updateProfileImage(){ SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); String username = sharedPreferences.getString("username", null ); - System.out.println( ); if( username != null ){ apiService.fetchEmployeePhoto( username ).enqueue( new Callback() { @@ -145,6 +177,8 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe System.out.println( response.body() ); if( response.isSuccessful() && response.body() != null ){ System.out.println( response.body() ); + editor.putString("name" , response.body().getName() ); + editor.apply(); usernameTitle.setText( response.body().getName() ); store.setEmployeePhoto( response.body() ); Glide.with( getBaseContext() ) @@ -156,12 +190,154 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe @Override public void onFailure(Call call, Throwable t) { System.out.println( t.getMessage() ); + String name = sharedPreferences.getString("name", null); + usernameTitle.setText( name ); } } ); } } + + + /* + * fetch and update product map + * */ + private void fetchAndPopulateProductData(){ + + NotificationHelper.showProductNotification( + this, + "Utopia QA App", + "Fetching Product Details."); + inspectionReportService.fetchAndPopulateProducts( new SaveProductCallBack() { + @Override + public void onSuccess() { + Toast.makeText( HomeActivity.this, "Products successfully synced", Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Products successfully synced"); + } + + @Override + public void onFailure(Throwable throwable) { + Toast.makeText( HomeActivity.this, "Error in Products syncing " + throwable.getMessage(), Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Error in Products syncing" ); + } + }, new ProductRepository( this ) ); + } + + private void fetchAndPopulateDimensionsData(){ + + NotificationHelper.showProductNotification( this, + "Utopia QA App", + "Fetching Dimensions Details."); + inspectionReportService.fetchAndPopulateDimensions( new SaveDimensionCallback() { + @Override + public void onSuccess() { + Toast.makeText( HomeActivity.this, "Dimensions successfully synced", Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Dimensions successfully synced"); + } + + @Override + public void onFailure(Throwable throwable) { + Toast.makeText( HomeActivity.this, "Error in Dimensions syncing " + throwable.getMessage(), Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Error in Dimensions syncing" ); + } + }, new DimensionRepository( this ) ); + } + + private void fetchAndPopulateCheckpointData(){ + + NotificationHelper.showProductNotification( + this, + "Utopia QA App", + "Fetching Checkpoints Details."); + inspectionReportService.fetchAndPopulateCheckpoints( new SaveCheckpointCallback() { + @Override + public void onSuccess() { + Toast.makeText( HomeActivity.this, "Checkpoints successfully synced", Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( HomeActivity.this, + "Utopia QA App", + "Checkpoints successfully synced"); + } + + @Override + public void onFailure(Throwable throwable) { + Toast.makeText( HomeActivity.this, "Error in Checkpoints syncing " + throwable.getMessage(), Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Error in Checkpoints syncing" ); + } + }, new CheckpointRepository( this ) ); + } + + private void fetchAndPopulateDefectsData(){ + + NotificationHelper.showProductNotification( + this, + "Utopia QA App", + "Fetching Defects Details."); + inspectionReportService.fetchAndPopulateDefects( new SaveDefectCallback() { + @Override + public void onSuccess() { + Toast.makeText( HomeActivity.this, "Defects successfully synced", Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Defects successfully synced"); + } + + @Override + public void onFailure(Throwable throwable) { + Toast.makeText( HomeActivity.this, "Error in Defects syncing " + throwable.getMessage(), Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Error in Defects syncing" ); + } + }, new DefectRepository( this ) ); + } + + private void fetchAndPopulateUnitsData(){ + + NotificationHelper.showProductNotification( + this, + "Utopia QA App", + "Fetching Units Details."); + inspectionReportService.fetchAndPopulateUnits( new SaveItemCallback() { + @Override + public void onSuccess() { + Toast.makeText( HomeActivity.this, "Units successfully synced", Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Units successfully synced"); + } + + @Override + public void onFailure(Throwable throwable) { + Toast.makeText( HomeActivity.this, "Error in Units syncing " + throwable.getMessage(), Toast.LENGTH_LONG ).show(); + NotificationHelper.showProductNotification( + HomeActivity.this, + "Utopia QA App", + "Error in Units syncing" ); + } + }, new ItemRepository( this ) ); + } + + + private boolean isNetworkConnected() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); @@ -173,4 +349,24 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe super.onResume(); refreshReportData(); } + + @Override + protected void onStart() { + super.onStart(); + if (networkReceiver == null) { + networkReceiver = new NetworkReceiver(); + } + IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); + registerReceiver(networkReceiver, filter); + isReceiverRegistered = true; // Mark the receiver as registered + } + + @Override + protected void onStop() { + super.onStop(); + if (isReceiverRegistered) { + unregisterReceiver(networkReceiver); + isReceiverRegistered = false; // Mark the receiver as unregistered + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/LoginActivity.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/LoginActivity.java index 9e85ba1..c4673b5 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/LoginActivity.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/LoginActivity.java @@ -111,28 +111,33 @@ public class LoginActivity extends AppCompatActivity { String username = sharedPreferences.getString("username", null); String password = sharedPreferences.getString("password", null); - - reportService.isUserAuthenticated(username, - password, - new String[]{"ROLE_UIM_QA_APP_ACCESS_YES"}, - 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: "); - } - }); + if( username != null && ! username.trim().isEmpty() && password != null && !password.trim().isEmpty() ){ + Intent intent = new Intent(LoginActivity.this, HomeActivity.class); + startActivity(intent); + // close login screen + LoginActivity.this.finish(); + } +// reportService.isUserAuthenticated(username, +// password, +// new String[]{"ROLE_UIM_QA_APP_ACCESS_YES"}, +// 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() { diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/MainActivity.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/MainActivity.java index 0f85c22..f06d743 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/MainActivity.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/MainActivity.java @@ -32,16 +32,13 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe 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); + store = Store.getInstance(); + store.initializeNewReport( getApplicationContext() ); setContentView(R.layout.activity_main); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); @@ -49,9 +46,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe return insets; }); setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); - - // initializing fields navController = Navigation.findNavController( this, R.id.nav_host_fragment ); + // initializing fields updateUsername(); } private void updateUsername() { diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/CheckPointAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/CheckPointAdapter.java index cfe3751..2ffb041 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/CheckPointAdapter.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/CheckPointAdapter.java @@ -76,11 +76,13 @@ public class CheckPointAdapter extends 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); + if( parent.getItemAtPosition(position) != null ){ + 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) { diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/DefectsAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/DefectsAdapter.java index 291c632..299a4a0 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/DefectsAdapter.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/DefectsAdapter.java @@ -7,11 +7,13 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.EditText; import android.widget.ImageButton; import android.widget.Spinner; import androidx.annotation.NonNull; +import androidx.appcompat.widget.SearchView; import androidx.recyclerview.widget.RecyclerView; import com.utopiaindustries.qualitychecker.R; @@ -37,6 +39,7 @@ public class DefectsAdapter extends RecyclerView.Adapter defectList = filteredDefects.stream().map(InspectionDefect::getDefect).collect(Collectors.toList()); + ArrayAdapter defectSpinnerAdapter = new ArrayAdapter<>( holder.defectSpinner.getContext(), android.R.layout.simple_spinner_item, defectList ); - defectSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); +// defectSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); holder.defectSpinner.setAdapter(defectSpinnerAdapter); + // Make the dropdown appear when clicking the AutoCompleteTextView + holder.defectSpinner.setOnClickListener(view -> holder.defectSpinner.showDropDown()); String defaultSelectedDefect = defect; int defaultSelectedDefectPosition = defectList.indexOf(defaultSelectedDefect); - holder.defectSpinner.setSelection(defaultSelectedDefectPosition); + holder.defectSpinner.setText(defaultSelectedDefect); } private void populateQuantity( DefectViewHolder holder ){ @@ -107,17 +113,25 @@ public class DefectsAdapter extends RecyclerView.Adapter parent) { } }); - holder.defectSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - String selectedItem = parent.getItemAtPosition(position).toString(); - checkPoint.getDefectTitles().set( holder.getAdapterPosition(), selectedItem) ; - } - @Override - public void onNothingSelected(AdapterView parent) { + holder.defectSpinner.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + String selectedItem = parent.getItemAtPosition(position).toString(); + checkPoint.getDefectTitles().set( holder.getAdapterPosition(), selectedItem) ; } }); +// holder.defectSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { +// @Override +// public void onItemSelected(AdapterView parent, View view, int position, long id) { +// String selectedItem = parent.getItemAtPosition(position).toString(); +// checkPoint.getDefectTitles().set( holder.getAdapterPosition(), selectedItem) ; +// } +// @Override +// public void onNothingSelected(AdapterView parent) { +// +// } +// }); holder.quantity.addTextChangedListener(new TextWatcher() { @Override @@ -166,7 +180,8 @@ public class DefectsAdapter extends RecyclerView.Adapter { if( isChecked ){ @@ -284,43 +290,58 @@ public class FirstStepFragment extends Fragment implements View.OnClickListener } if( v.getId() == R.id.search_sku_btn ){ if( sku.getText() != null ){ + // setting the product details 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(); - } - } + List products = new ProductRepository( getContext() ).getProductBySku( skuStr ); + Product product = products.stream().findFirst().orElse( new Product() ); + store.getReport().getItems().get(0).setSku( skuStr ); + store.getReport().getItems().get(0).setAsin( product.getAsin() ); + populateItem( products ); + store.setProducts( products ); - @Override - public void onFailure(Call> call, Throwable t) { - System.out.println( t.getMessage() ); - } - } - ); - apiService.fetchDimensions( skuStr ).enqueue( - new Callback>() { - @Override - public void onResponse(Call> call, Response> response) { - if( response.isSuccessful() && response.body() != null ){ - store.setDimensionList( response.body() ); - } - } - @Override - public void onFailure(Call> call, Throwable t) { - System.out.println( t.getMessage() ); - } - } - ); +// 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() ); +// } +// } +// ); +// apiService.fetchDimensions( ).enqueue( +// new Callback>() { +// @Override +// public void onResponse(Call> call, Response> response) { +// if( response.isSuccessful() && response.body() != null ){ +// store.setDimensionList( response.body() ); +// } +// } +// +// @Override +// public void onFailure(Call> call, Throwable t) { +// System.out.println( t.getMessage() ); +// } +// } +// ); + if( product.getCategory() != null ){ + List dimensions = new DimensionRepository( getContext() ).findByCategory( + product.getCategory() + ); + store.setDimensionList( dimensions ); + } } } if( v.getId() == R.id.scan_sku_btn ){ @@ -378,7 +399,6 @@ public class FirstStepFragment extends Fragment implements View.OnClickListener String boxCartonText = String.valueOf( ( product.getInventory() / product.getItemPerBox() ) ); @SuppressLint("DefaultLocale") 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 ); @@ -407,63 +427,73 @@ public class FirstStepFragment extends Fragment implements View.OnClickListener private void populateSize( List products ){ List sizes = Collections.singletonList("[Size]"); if( ! products.isEmpty() ){ - sizes = products.stream().map( Product::getSmSize ).distinct().collect(Collectors.toList() ); + sizes = products.stream().map( Product::getSmSize ).distinct().filter(Objects::nonNull).collect(Collectors.toList() ); + } + if( !sizes.isEmpty() ){ + ArrayAdapter adapter = new ArrayAdapter<>( Objects.requireNonNull(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 ); } - ArrayAdapter adapter = new ArrayAdapter<>( Objects.requireNonNull(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() ); + colors = products.stream().map( Product::getSmColor ).distinct().filter(Objects::nonNull).collect(Collectors.toList() ); + } + if( !colors.isEmpty() ){ + + ArrayAdapter adapter = new ArrayAdapter<>( Objects.requireNonNull(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 ); } - ArrayAdapter adapter = new ArrayAdapter<>( Objects.requireNonNull(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()) ; + titles = products.stream().map( Product::getTitle ).distinct().filter(Objects::nonNull).collect(Collectors.toList()) ; + } + if( !titles.isEmpty() ){ + 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 ); } - 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()) ; + modelNumbers = products.stream().map( Product::getModelNumber ).distinct().filter(Objects::nonNull).collect(Collectors.toList() ) ; } - ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, modelNumbers.toArray(new String[0] )); - modelNumber.setAdapter( adapter ); + if( !modelNumbers.isEmpty() ){ + 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 ); + 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() ); + marketplaces = products.stream().map( Product::getMarketplace ).distinct().filter(Objects::nonNull).collect(Collectors.toList() ); + } + if( ! marketplaces.isEmpty()){ + 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 ); } - 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 ); } @@ -494,23 +524,11 @@ public class FirstStepFragment extends Fragment implements View.OnClickListener 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(); - } - } - ); + store.getReport().getItems().get(0).setSku( result ); + sku.setText( result ); } } @@ -562,4 +580,12 @@ public class FirstStepFragment extends Fragment implements View.OnClickListener AlertDialog dialog = builder.create(); dialog.show(); } + + private void updateProfileViews( ) throws NullPointerException{ + SharedPreferences sharedPreferences = getActivity().getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + profileName.setText( sharedPreferences.getString("name", null ) ); + Glide.with( getContext() ) + .load( store.getProfileImage( ) ) + .into( profileImage ); + } } diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/SecondStepFragment.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/SecondStepFragment.java index 04cf487..22cd913 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/SecondStepFragment.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/SecondStepFragment.java @@ -5,6 +5,7 @@ import static android.app.Activity.RESULT_OK; import android.Manifest; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -17,6 +18,7 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -43,6 +45,7 @@ import com.utopiaindustries.qualitychecker.ui.adapter.CheckPointAdapter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Future; @@ -104,12 +107,7 @@ public class SecondStepFragment extends Fragment } } - profileName.setText( store.getEmployeePhoto().getName() ); - Glide.with( getContext() ) - .load( store.getProfileImage( ) ) - .into( profileImage ); - - adapter = new CheckPointAdapter( store.getReport().getItems().get( 0 ).getCheckPoints(), + adapter = new CheckPointAdapter( store.getReport().getItems().get( 0 ).getCheckPoints(), store.getCheckPoints(), store.getDefects(), inspectionReportService.getDefectTypes(), @@ -118,6 +116,7 @@ public class SecondStepFragment extends Fragment // set on click listener leftFab.setOnClickListener( this ); rightFab.setOnClickListener( this ); + updateProfileViews(); return view; } @@ -128,7 +127,7 @@ public class SecondStepFragment extends Fragment 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 ); + checkIsRecyclerViewIsCompletelyScrolled( recyclerView ); } } @@ -141,7 +140,7 @@ public class SecondStepFragment extends Fragment String imagePath = selectedImageUri.getPath(); store.getReport().getItems().get(0).getCheckPoints().get(requestCode).setImagePath(imagePath); - imageProcessor.compressImageFromUriAsync(getContext(), selectedImageUri, 200, compressedData -> { + imageProcessor.compressImageFromUriAsync( getContext(), selectedImageUri, 200, compressedData -> { if (compressedData != null) { store.getReport().getItems().get(0).getCheckPoints().get(requestCode).setFile(compressedData); } else { @@ -152,55 +151,28 @@ public class SecondStepFragment extends Fragment } catch ( Exception e ){ e.printStackTrace(); } -// store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setFile( -// compressImageToMaxSize( getBytesFromUri( getContext(), selectedImageUri ), 200 ) - // ); } } -// 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; -// } -// -// public byte[] compressImageToMaxSize(byte[] imageData, -// int maxSizeKB) { -// int quality = 100; // Start with highest quality -// byte[] compressedBytes = compressImage(imageData, quality); -// // Loop to reduce quality until the image is within the max size -// while (compressedBytes.length > maxSizeKB * 1024 && quality > 0) { -// quality -= 5; -// compressedBytes = compressImage(imageData, quality); -// } -// -// return compressedBytes; -// } -// -// private byte[] compressImage(byte[] imageData, -// int quality) { -// if( imageData != null && imageData.length > 0 ) { -// Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length); -// ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); -// bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream); -// return outputStream.toByteArray(); -// } -// return null; -// } + private void checkIsRecyclerViewIsCompletelyScrolled( RecyclerView recyclerView ){ + if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) { + LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); + int lastVisibleItemPosition = layoutManager.findLastCompletelyVisibleItemPosition(); + int totalItemCount = layoutManager.getItemCount(); + + if (lastVisibleItemPosition == totalItemCount - 1) { + navController.navigate( R.id.action_secondStepFragment_to_thirdStepFragment ); + } else { + Toast.makeText( getContext(), "Please Scroll at the bottom to continue", Toast.LENGTH_SHORT ).show(); + } + } + } + + private void updateProfileViews( ) throws NullPointerException{ + SharedPreferences sharedPreferences = getActivity().getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + profileName.setText( sharedPreferences.getString("name", null ) ); + Glide.with( getContext() ) + .load( store.getProfileImage( ) ) + .into( profileImage ); + } } diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ThirdStepFragment.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ThirdStepFragment.java index 5fa5e2a..4985255 100644 --- a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ThirdStepFragment.java +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ThirdStepFragment.java @@ -1,7 +1,11 @@ package com.utopiaindustries.qualitychecker.ui.fragments; import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; @@ -34,7 +38,7 @@ import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory; import com.utopiaindustries.qualitychecker.models.InspectionItemCheckPoint; import com.utopiaindustries.qualitychecker.models.InspectionItemDimension; import com.utopiaindustries.qualitychecker.models.InspectionReport; -import com.utopiaindustries.qualitychecker.models.SaveReportCallback; +import com.utopiaindustries.qualitychecker.models.callback.SaveReportCallback; import com.utopiaindustries.qualitychecker.models.VoiceOfCustomer; import com.utopiaindustries.qualitychecker.notification.NotificationHelper; import com.utopiaindustries.qualitychecker.service.InspectionReportService; @@ -79,6 +83,7 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener initializeViews( view ); populateViews(); setOnClickListeners(); + updateProfileViews(); vocRecyclerView.setLayoutManager( new LinearLayoutManager( getContext() ) ); itemDimensionsRecyclerView.setLayoutManager( new LinearLayoutManager( getContext() ) ); @@ -150,30 +155,36 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener builder.setView( dialogView ) .setTitle("So you want to save report?") .setPositiveButton( "Save",(dialog, which) -> { - progressBar.setVisibility( View.VISIBLE ); - NotificationHelper.showNotification( Objects.requireNonNull(getContext()), + progressBar.setVisibility(View.VISIBLE); + NotificationHelper.showNotification(Objects.requireNonNull(getContext()), "Utopia QA App", - "Report is uploading keep patience..."); - inspectionReportService.saveReport(store.getReport(), new SaveReportCallback() { - @Override - public void onSuccess() { - Toast.makeText( getContext(), "Report saved Successfully", Toast.LENGTH_LONG ).show(); - progressBar.setVisibility( View.INVISIBLE ); - Objects.requireNonNull( getActivity() ).finish(); - NotificationHelper.showNotification( Objects.requireNonNull(getContext()), - "Utopia QA App", - "Report is uploaded successfully"); + "Report is saving keep patience..."); + inspectionReportService.saveInLocalDb( getContext(), store.getReport(), new SaveReportCallback() { + @Override + public void onSuccess() { + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(() -> { + Toast.makeText(getContext(), "Report saved Successfully", Toast.LENGTH_LONG).show(); + progressBar.setVisibility(View.INVISIBLE); + Objects.requireNonNull(getActivity()).finish(); + NotificationHelper.showNotification(Objects.requireNonNull(getContext()), + "Utopia QA App", + "Report is successfully saved"); + }); + } - } - @Override - public void onFailure(Throwable throwable) { - Toast.makeText( getContext(), throwable.getMessage(), Toast.LENGTH_LONG ).show(); - progressBar.setVisibility( View.INVISIBLE ); - NotificationHelper.showNotification( Objects.requireNonNull(getContext()), - "Utopia QA App", - "Error in uploading report"); - } - }); + @Override + public void onFailure(Throwable throwable) { + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(() -> { + Toast.makeText(getContext(), throwable.getMessage(), Toast.LENGTH_LONG).show(); + progressBar.setVisibility(View.INVISIBLE); + NotificationHelper.showNotification(Objects.requireNonNull(getContext()), + "Utopia QA App", + "Error in saving report"); + }); + } + }); }) .setNegativeButton("Cancel", (dialog, which) -> { // Handle Cancel button click @@ -202,7 +213,7 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener builder.setView(dialogView) .setTitle("Select Dimensions") .setPositiveButton( "Save",(dialog, which) -> { - calculateDimensions(); + calculateDimensions(); dialog.dismiss(); } ) .setNegativeButton("Cancel", (dialog, which) -> { @@ -236,12 +247,6 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener @SuppressLint("DefaultLocale") private void populateViews(){ - - profileName.setText( store.getEmployeePhoto().getName() ); - Glide.with( Objects.requireNonNull(getContext() )) - .load( store.getProfileImage( ) ) - .into( profileImage ); - generalRemarks.setText( store.getReport().getGeneralRemarks() ); ArrayAdapter adapter = new ArrayAdapter<>( getContext(), @@ -280,6 +285,7 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener for (InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints()) { for( int i = 0 ; i< itemCp.getDefectSeverites().size() ; i++ ){ String status = itemCp.getDefectSeverites().get( i ); + System.out.println( status); float quantity = itemCp.getQuantities().get(i); if( status.equalsIgnoreCase("minor") ){ minor += (int) quantity; @@ -301,21 +307,21 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener private void calculateDimensions(){ List dimensions = store.getDimensions(); - List newDimensions = new ArrayList<>(); + System.out.println( dimensions ); + // List newDimensions = new ArrayList<>(); try { - if(! dimensions.isEmpty() ){ +// if(! dimensions.isEmpty() ){ // calculations for averaging - Map> typeToDimensionsMap = - dimensions.stream().collect(Collectors.groupingBy( InspectionItemDimension::getType) ); +// Map> typeToDimensionsMap = +// dimensions.stream().collect(Collectors.groupingBy( InspectionItemDimension::getType) ); - for( Map.Entry> entry : typeToDimensionsMap.entrySet() ){ - InspectionItemDimension newDimen = getInspectionItemDimension( entry ); - newDimensions.add( newDimen ); - } - store.getReport().getItems().get(0).setDimensions( newDimensions ); - ItemDimensionAdapter adapter = new ItemDimensionAdapter( store.getReport().getItems().get(0).getDimensions() ); +// for( Map.Entry> entry : typeToDimensionsMap.entrySet() ){ +// InspectionItemDimension newDimen = getInspectionItemDimension( entry ); +// newDimensions.add( newDimen ); +// } + store.getReport().getItems().get(0).setDimensions( dimensions ); + ItemDimensionAdapter adapter = new ItemDimensionAdapter( dimensions ); itemDimensionsRecyclerView.setAdapter( adapter ); - } } catch ( NullPointerException ex ){ Toast.makeText( getContext() , "Please fill the required Fields", Toast.LENGTH_LONG ).show(); } @@ -370,4 +376,12 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener backBtn.setOnClickListener( this ); openDimensionDialog.setOnClickListener( this); } + + private void updateProfileViews( ) throws NullPointerException{ + SharedPreferences sharedPreferences = getActivity().getSharedPreferences("login_prefs", Context.MODE_PRIVATE); + profileName.setText( sharedPreferences.getString("name", null ) ); + Glide.with( getContext() ) + .load( store.getProfileImage( ) ) + .into( profileImage ); + } } diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/utils/FileUtils.java b/app/src/main/java/com/utopiaindustries/qualitychecker/utils/FileUtils.java new file mode 100644 index 0000000..5fad4f3 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitychecker/utils/FileUtils.java @@ -0,0 +1,66 @@ +package com.utopiaindustries.qualitychecker.utils; + +import android.content.Context; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; + + +public class FileUtils { + public static String writeFile( Context context , + byte[] content, + String fileName ){ + FileOutputStream fos = null; + try { + // Get the file path in the internal storage + File file = new File( context.getFilesDir(), fileName); + // Open the file output stream + fos = new FileOutputStream(file); + fos.write( content ); + fos.flush(); + return file.getAbsolutePath(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (fos != null) { + try { + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return ""; + } + + public static byte[] readFile(String filePath) throws IOException { + File file = new File(filePath); + try (FileInputStream fis = new FileInputStream(file); + ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = fis.read(buffer)) != -1) { + baos.write(buffer, 0, bytesRead); + } + return baos.toByteArray(); + } + } + + public static void deleteFile(String filePath) { + File file = new File(filePath); + if (file.exists()) { + if (file.delete()) { + System.out.println("File deleted successfully"); + } else { + System.out.println("Failed to delete the file"); + } + } else { + System.out.println("File does not exist"); + } + } +} diff --git a/app/src/main/res/drawable/hold_bg.xml b/app/src/main/res/drawable/hold_bg.xml new file mode 100644 index 0000000..42355b0 --- /dev/null +++ b/app/src/main/res/drawable/hold_bg.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/ic_down.xml b/app/src/main/res/drawable/ic_down.xml new file mode 100644 index 0000000..8ff2205 --- /dev/null +++ b/app/src/main/res/drawable/ic_down.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index 6682206..b6c7bad 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -48,7 +48,7 @@ android:id="@+id/username_title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Ameen ur Rehman" + android:text="" android:textColor="#000000" android:textStyle="bold|italic" app:layout_constraintBottom_toBottomOf="parent" @@ -143,5 +143,14 @@ android:layout_toStartOf="@id/refresh_btn" android:text="Logout" /> +