diff --git a/app/build.gradle b/app/build.gradle
index fbe29d5..42f64ef 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,8 @@ android {
applicationId "com.utopiaindustries.qualitychecker"
minSdk 24
targetSdk 34
- versionCode 3
- versionName "1.2"
+ versionCode 5
+ versionName "1.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 38a9d46..f2df0f5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -61,17 +61,17 @@
-
+ android:exported="false" />-->
-
-
+ -->
{
openDatabase();
database.beginTransaction();
@@ -49,6 +51,14 @@ public class ReportRepository {
values.put(DatabaseHelper.REPORT_COLUMN_SYNCED, wrapper.isSynced());
database.insertWithOnConflict(DatabaseHelper.REPORT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
database.setTransactionSuccessful();
+
+ // Count total rows after insert
+ /*Cursor cursor = database.rawQuery("SELECT COUNT(*) FROM " + DatabaseHelper.REPORT_TABLE_NAME, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ int count = cursor.getInt(0);
+ Log.e("Total Rows Inserted", String.valueOf(count));
+ cursor.close();
+ }*/
} catch (Exception e) {
e.printStackTrace();
} finally {
@@ -58,6 +68,29 @@ public class ReportRepository {
});
}
+ public List getAllSavedPaths() {
+ List paths = new ArrayList<>();
+ openDatabase();
+ Cursor cursor = null;
+ try {
+ cursor = database.query(
+ DatabaseHelper.REPORT_TABLE_NAME,
+ new String[]{DatabaseHelper.REPORT_COLUMN_CONTENT},
+ null, null, null, null, null
+ );
+ if (cursor != null && cursor.moveToFirst()) {
+ do {
+ paths.add(cursor.getString(0));
+ } while (cursor.moveToNext());
+ }
+ } finally {
+ if (cursor != null) cursor.close();
+ close();
+ }
+ return paths;
+ }
+
+
public void insertOrReplaceUser(InspectionReportWrapper wrapper) {
executeSafely(() -> {
openDatabase();
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 f8aaf4b..0ef2c9d 100644
--- a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java
@@ -3,6 +3,7 @@ package com.utopiaindustries.qualitychecker.models;
import androidx.annotation.NonNull;
import java.io.Serializable;
+import java.time.LocalDate;
import java.util.List;
public class InspectionReport implements Serializable {
@@ -23,6 +24,7 @@ public class InspectionReport implements Serializable {
private String productionRepresentative;
private String qcRepresentative;
private String floor;
+ private String auditDate;
// wrapper
@@ -179,7 +181,13 @@ public class InspectionReport implements Serializable {
this.filePath = filePath;
}
+ public String getAuditDate() {
+ return auditDate;
+ }
+ public void setAuditDate(String auditDate) {
+ this.auditDate = auditDate;
+ }
@Override
public String toString() {
@@ -201,6 +209,7 @@ public class InspectionReport implements Serializable {
", floor='" + floor + '\'' +
", items=" + items +
", filePath='" + filePath + '\'' +
+ ", auditDate='" + auditDate + '\'' +
", wrapperId=" + wrapperId +
'}';
}
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 a5a3bf9..2de7d56 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
@@ -43,17 +43,21 @@ import com.utopiaindustries.qualitychecker.db.InspectionCheckpointSkuRepository;
import com.utopiaindustries.qualitychecker.db.InspectionLabelRepository;
import com.utopiaindustries.qualitychecker.db.ItemRepository;
import com.utopiaindustries.qualitychecker.db.ProductRepository;
+import com.utopiaindustries.qualitychecker.db.ReportRepository;
import com.utopiaindustries.qualitychecker.models.EmployeePhoto;
import com.utopiaindustries.qualitychecker.models.InspectionReport;
+import com.utopiaindustries.qualitychecker.models.InspectionReportWrapper;
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.SaveInspectionLabelCallBack;
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.notification.NotificationHelper;
import com.utopiaindustries.qualitychecker.receiver.NetworkReceiver;
import com.utopiaindustries.qualitychecker.service.InspectionReportService;
+import com.utopiaindustries.qualitychecker.service.NetworkService;
import com.utopiaindustries.qualitychecker.store.Store;
import com.utopiaindustries.qualitychecker.ui.activities.fragments.ReportsFragment;
import com.utopiaindustries.qualitychecker.ui.adapter.PagerAdapter;
@@ -63,6 +67,9 @@ import com.utopiaindustries.qualitychecker.utils.FileUtils;
import com.utopiaindustries.qualitychecker.utils.PropertyReader;
import com.utopiaindustries.qualitychecker.utils.Release;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
@@ -73,7 +80,7 @@ import retrofit2.Response;
public class HomeActivity extends AppCompatActivity implements View.OnClickListener {
- private Button createReportBtn,refreshReportsBtn,logoutBtn,fetchProductBtn, appUpdateBtn;
+ private Button createReportBtn,refreshReportsBtn,logoutBtn,fetchProductBtn, appUpdateBtn, reportsUploadBtn;
//private RecyclerView recyclerView;
private ApiService apiService;
private TextView usernameTitle;//, emptyReportTextView;
@@ -115,6 +122,7 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe
logoutBtn = findViewById( R.id.logout_btn );
fetchProductBtn = findViewById( R.id.fetch_product_btn );
appUpdateBtn = findViewById(R.id.app_update_btn);
+ reportsUploadBtn = findViewById(R.id.reports_upload_btn);
progressBar = findViewById(R.id.progressBar);
//recyclerView = findViewById( R.id.reports_recyclerview );
usernameTitle = findViewById( R.id.username_title );
@@ -138,6 +146,7 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe
logoutBtn.setOnClickListener( this );
fetchProductBtn.setOnClickListener( this );
appUpdateBtn.setOnClickListener( this );
+ reportsUploadBtn.setOnClickListener( this );
//recyclerView.setLayoutManager( new LinearLayoutManager( this ) );
@@ -228,6 +237,17 @@ public class HomeActivity extends AppCompatActivity implements View.OnClickListe
}
}
+
+ if ( id == R.id.reports_upload_btn) {
+
+ if (!FileUtils.isNetworkConnected(this)) {
+ Toast.makeText(this, "No Internet Connection Available", Toast.LENGTH_LONG).show();
+ }
+ else {
+ pushDataToInternet();
+ }
+
+ }
}
private int generateRandomNumber(int min, int max) {
@@ -480,21 +500,21 @@ private int generateRandomNumber(int min, int max) {
@Override
protected void onStart() {
super.onStart();
- if (networkReceiver == null) {
+ /*if (networkReceiver == null) {
networkReceiver = new NetworkReceiver();
}
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkReceiver, filter);
- isReceiverRegistered = true; // Mark the receiver as registered
+ isReceiverRegistered = true; */ // Mark the receiver as registered
}
@Override
protected void onStop() {
super.onStop();
- if (isReceiverRegistered) {
+ /*if (isReceiverRegistered) {
unregisterReceiver(networkReceiver);
isReceiverRegistered = false; // Mark the receiver as unregistered
- }
+ }*/
}
/**
@@ -555,4 +575,90 @@ private int generateRandomNumber(int min, int max) {
}
} );
}
+
+ @SuppressLint("DefaultLocale")
+ private void pushDataToInternet() {
+ ReportRepository repository = new ReportRepository( this );
+ List reportWrappers = repository.findAllUnsynced();
+ InspectionReportService service = InspectionReportService.getInstance();
+ try {
+ List reports = getReports( reportWrappers );
+ int size = reports.size();
+ if( size > 0 ) {
+ Toast.makeText(this, "Uploading Reports. Please wait", Toast.LENGTH_LONG).show();
+ reportsUploadBtn.setEnabled(false);
+ final int[] uploadedCount = {0};
+
+ 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() );
+
+ uploadedCount[0]++;
+
+ NotificationHelper.showNotification(
+ HomeActivity.this,
+ "Report Uploading",
+ "Uploaded " + uploadedCount[0] + " of " + size + " reports");
+
+ //Log.e("Reports-size: ",""+reports.size());
+ if (uploadedCount[0] == size) {
+ Toast.makeText(HomeActivity.this, "All reports uploaded successfully", Toast.LENGTH_SHORT).show();
+ reportsUploadBtn.setEnabled(true);
+ }
+ }
+ @Override
+ public void onFailure(Throwable throwable) {
+ uploadedCount[0]++;
+ // Even on failure, increment the counter to avoid locking the button forever
+
+ NotificationHelper.showNotification(
+ HomeActivity.this,
+ "Report Uploading",
+ "Uploaded " + uploadedCount[0] + " of " + size + " reports (with some errors)");
+
+
+ if (uploadedCount[0] == size) {
+ reportsUploadBtn.setEnabled(true);
+ Toast.makeText(HomeActivity.this, "Finished uploading with some errors", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+ }
+ }
+ else {
+ Toast.makeText(this, "No Reports to upload", Toast.LENGTH_SHORT).show();
+ }
+ } 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 | OutOfMemoryError e){
+ e.printStackTrace();
+ }
+ }
+ }
+ return reports;
+ }
}
\ No newline at end of file
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 183d060..b887f76 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
@@ -5,6 +5,7 @@ import static android.app.Activity.RESULT_OK;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
+import android.app.DatePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -25,6 +26,7 @@ import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
+import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
@@ -67,9 +69,13 @@ import com.utopiaindustries.qualitychecker.utils.FileUtils;
import com.utopiaindustries.qualitychecker.utils.ImageUriHolder;
import java.io.File;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
@@ -104,6 +110,11 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener
ArrayList sectionArrayList = new ArrayList<>();
private EditText etHandFeelNotOk, etHandFeelOk, etHandFeelPercent;
+ private ImageView imgCalendar;
+ private TextView txtDate;
+ private int year, month, day;
+ private Calendar calendar;
+ private LocalDate localDate;
@Nullable
@Override
@@ -302,9 +313,36 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener
}
});
+ imgCalendar.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showDatePickerDialog(getActivity());
+ }
+ });
+
return view;
}
+ private void showDatePickerDialog(Context context) {
+ DatePickerDialog datePickerDialog = new DatePickerDialog(
+ context,
+ new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
+ // Month is 0-indexed, so we add 1
+ Calendar selectedCalendar = Calendar.getInstance();
+ selectedCalendar.set(year, monthOfYear, dayOfMonth);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy", Locale.getDefault());
+ String selectedDate = dateFormat.format(selectedCalendar.getTime());
+ txtDate.setText(selectedDate);
+ store.getReport().setAuditDate(selectedDate);
+ }
+ },
+ year, month, day
+ );
+ datePickerDialog.show();
+ }
+
public void onImagePickerResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST) {
Uri selectedImageUri = ImageUriHolder.getInstance().getImageUri();
@@ -633,6 +671,7 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener
sectionSpinner.setSelection(index);
etHandFeelNotOk.setText(String.valueOf(store.getReport().getItems().get(0).getHandFeelNotOkay()));
+ txtDate.setText(store.getReport().getAuditDate());
}
}
@@ -714,6 +753,14 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener
txtMinor = view.findViewById(R.id.txt_minor);
etFloor = view.findViewById(R.id.et_floor);
+ calendar = Calendar.getInstance();
+ year = calendar.get(Calendar.YEAR);
+ month = calendar.get(Calendar.MONTH);
+ day = calendar.get(Calendar.DAY_OF_MONTH);
+
+ imgCalendar = view.findViewById(R.id.img_calendar);
+ txtDate = view.findViewById(R.id.txt_date);
+
etHandFeelNotOk = view.findViewById(R.id.et_hand_feel_not_ok);
etHandFeelOk = view.findViewById(R.id.et_hand_feel_ok);
etHandFeelPercent = view.findViewById(R.id.et_not_ok_percent);
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/utils/FileUtils.java b/app/src/main/java/com/utopiaindustries/qualitychecker/utils/FileUtils.java
index c1fded8..1382ee9 100644
--- a/app/src/main/java/com/utopiaindustries/qualitychecker/utils/FileUtils.java
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/utils/FileUtils.java
@@ -207,6 +207,20 @@ public class FileUtils {
}).start();
}
+ public static byte[] readFileToByteArray(String path) throws IOException {
+ File file = new File(path);
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = fis.read(buffer)) != -1) {
+ bos.write(buffer, 0, bytesRead);
+ }
+ fis.close();
+ return bos.toByteArray();
+ }
+
+
/**
* is null or empty
*/
diff --git a/app/src/main/res/drawable/icon_calendar.xml b/app/src/main/res/drawable/icon_calendar.xml
new file mode 100644
index 0000000..0f090ec
--- /dev/null
+++ b/app/src/main/res/drawable/icon_calendar.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 2305fc7..9fd6f0e 100644
--- a/app/src/main/res/layout/activity_home.xml
+++ b/app/src/main/res/layout/activity_home.xml
@@ -90,10 +90,10 @@
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:tabMaxWidth="0dp"
+ android:layout_below="@+id/layout_heading"
app:tabGravity="fill"
- app:tabMode="fixed"
- android:layout_below="@+id/layout_heading" />
+ app:tabMaxWidth="0dp"
+ app:tabMode="fixed" />
+
+
-
+
+
+
+
+
+
+
+
+
+
+