diff --git a/app/src/androidTest/java/com/utopiaindustries/qualitychecker/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/utopiaindustries/qualitychecker/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..a3d96f1
--- /dev/null
+++ b/app/src/androidTest/java/com/utopiaindustries/qualitychecker/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.utopiaindustries.qualitychecker;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.utopiaindustries.qualitychecker", appContext.getPackageName());
+ }
+}
\ 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
new file mode 100644
index 0000000..d260407
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/ApiService.java
@@ -0,0 +1,84 @@
+package com.utopiaindustries.qualitychecker.apiservice;
+
+import com.utopiaindustries.qualitychecker.models.EmployeePhoto;
+import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint;
+import com.utopiaindustries.qualitychecker.models.InspectionDefect;
+import com.utopiaindustries.qualitychecker.models.InspectionDimension;
+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.VoiceOfCustomer;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.http.Body;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+import retrofit2.http.Path;
+import retrofit2.http.Query;
+
+public interface ApiService {
+
+ @GET("rest/uic/inspection-report")
+ Call> fetchAllReports(
+ @Query("username") String username
+ );
+
+ @GET("rest/uic/inspection-report/{id}")
+ Call fetchReport(
+ @Path("id") long id
+ );
+
+ @POST("rest/authentication/authenticate-user")
+ Call isUserAuthenticated(
+ @Query("username") String username,
+ @Query("password") String password,
+ @Query("roles") String[] roles
+ );
+
+ @POST("rest/uic/inspection-report")
+ Call saveInspectionReport(
+ @Body InspectionReport inspectionReport
+ );
+
+ @GET("rest/uic/cosmos-products/find-by-sku")
+ Call> fetchProductBySku(
+ @Query("sku") String sku
+ );
+
+ @GET("rest/uic/inspection-report/checkpoints")
+ Call> fetchCheckPoints();
+
+ @GET( "rest/uic/inspection-report/defects" )
+ Call> fetchDefects();
+
+ @GET( "rest/uic/inspection-report/dimensions" )
+ Call> fetchDimensions(
+ @Query("sku") String sku
+ );
+
+ @GET( "rest/hrms/employees/attendance")
+ Call fetchEmployeePhoto(
+ @Query("username") String username
+ );
+
+ @GET("rest/cosmos/amazon-voc")
+ Call> fetchVocs(
+ @Query("asin") String asin
+ );
+
+ @GET( "rest/uic/cosmos-products/find-by-fnsku")
+ Call fetchByFnsku(
+ @Query("fnsku") String fnsku
+ );
+
+ @GET( "rest/uic/inspection-report/inspection-items-logs" )
+ Call> fetchItemsLogs(
+ @Query("sku") String sku
+ );
+
+ @GET( "rest/uic/items/units" )
+ Call> fetchItemUnits();
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/ApiServiceFactory.java b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/ApiServiceFactory.java
new file mode 100644
index 0000000..e9d60a9
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/ApiServiceFactory.java
@@ -0,0 +1,14 @@
+package com.utopiaindustries.qualitychecker.apiservice;
+
+import retrofit2.Retrofit;
+
+public class ApiServiceFactory {
+ private static ApiService apiService;
+ public synchronized static ApiService getApiService() {
+ if ( apiService == null ) {
+ Retrofit retrofit = RetrofitClient.getClient();
+ apiService = retrofit.create( ApiService.class );
+ }
+ return apiService;
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/BooleanTypeAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/BooleanTypeAdapter.java
new file mode 100644
index 0000000..c2a61a1
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/BooleanTypeAdapter.java
@@ -0,0 +1,27 @@
+package com.utopiaindustries.qualitychecker.apiservice;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+import java.io.IOException;
+
+public class BooleanTypeAdapter extends TypeAdapter {
+ @Override
+ public Boolean read(JsonReader in) throws IOException {
+ JsonToken token = in.peek();
+ if (token == JsonToken.BOOLEAN) {
+ return in.nextBoolean();
+ } else if (token == JsonToken.STRING) {
+ String value = in.nextString();
+ return Boolean.parseBoolean(value);
+ }
+ return null;
+ }
+
+ @Override
+ public void write(JsonWriter out, Boolean value) throws IOException {
+ out.value(value);
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/RetrofitClient.java b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/RetrofitClient.java
new file mode 100644
index 0000000..8341c9e
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/apiservice/RetrofitClient.java
@@ -0,0 +1,28 @@
+package com.utopiaindustries.qualitychecker.apiservice;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+public class RetrofitClient {
+
+ private final static String BASE_URL = "http://192.168.91.16:8080/uind/";
+ private static Retrofit retrofit;
+
+ public synchronized static Retrofit getClient() {
+
+ Gson gson = new GsonBuilder()
+ .registerTypeAdapter(Boolean.class, new BooleanTypeAdapter())
+ .create();
+
+ if ( retrofit == null ) {
+ retrofit = new Retrofit.Builder()
+ .baseUrl( BASE_URL )
+ .addConverterFactory( GsonConverterFactory.create( gson ) )
+ .build();
+ }
+ return retrofit;
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/Dimension.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/Dimension.java
new file mode 100644
index 0000000..46de649
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/Dimension.java
@@ -0,0 +1,63 @@
+package com.utopiaindustries.qualitychecker.models;
+
+public class Dimension {
+
+ private String type;
+ private float actual;
+ private float required;
+ private float difference;
+ private String unit;
+
+ public Dimension(){
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public float getActual() {
+ return actual;
+ }
+
+ public void setActual(float actual) {
+ this.actual = actual;
+ }
+
+ public float getRequired() {
+ return required;
+ }
+
+ public void setRequired(float required) {
+ this.required = required;
+ }
+
+ public float getDifference() {
+ return difference;
+ }
+
+ public void setDifference(float difference) {
+ this.difference = difference;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+ @Override
+ public String toString() {
+ return "Dimension{" +
+ "type='" + type + '\'' +
+ ", actual=" + actual +
+ ", required=" + required +
+ ", difference=" + difference +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/EmployeePhoto.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/EmployeePhoto.java
new file mode 100644
index 0000000..52572ba
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/EmployeePhoto.java
@@ -0,0 +1,59 @@
+package com.utopiaindustries.qualitychecker.models;
+
+
+public class EmployeePhoto {
+ private long id;
+ private long employeeId;
+ private String photoBlob;
+ private String name;
+
+ public EmployeePhoto() {
+ }
+
+ public EmployeePhoto( long employeeId, String photoBlob ) {
+ this.employeeId = employeeId;
+ this.photoBlob = photoBlob;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId( long id ) {
+ this.id = id;
+ }
+
+ public long getEmployeeId() {
+ return employeeId;
+ }
+
+ public void setEmployeeId( long employeeId ) {
+ this.employeeId = employeeId;
+ }
+
+ public String getPhotoBlob() {
+ return photoBlob;
+ }
+
+ public void setPhotoBlob( String photoBlob ) {
+ this.photoBlob = photoBlob;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "EmployeePhoto{" +
+ "id=" + id +
+ ", employeeId=" + employeeId +
+ ", photoBlob='" + photoBlob + '\'' +
+ ", name='" + name + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionCheckPoint.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionCheckPoint.java
new file mode 100644
index 0000000..885d459
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionCheckPoint.java
@@ -0,0 +1,42 @@
+package com.utopiaindustries.qualitychecker.models;
+
+
+public class InspectionCheckPoint {
+
+ private long id;
+ private String title;
+ private String category;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ @Override
+ public String toString() {
+ return "InspectionCheckPoint{" +
+ "id=" + id +
+ ", title='" + title + '\'' +
+ ", category='" + category + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDefect.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDefect.java
new file mode 100644
index 0000000..e119982
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDefect.java
@@ -0,0 +1,31 @@
+package com.utopiaindustries.qualitychecker.models;
+
+public class InspectionDefect {
+
+ private String category;
+ private String defect;
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getDefect() {
+ return defect;
+ }
+
+ public void setDefect(String defect) {
+ this.defect = defect;
+ }
+
+ @Override
+ public String toString() {
+ return "InspectionDefect{" +
+ "category='" + category + '\'' +
+ ", defect='" + defect + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDimension.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDimension.java
new file mode 100644
index 0000000..4bfd5ec
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionDimension.java
@@ -0,0 +1,42 @@
+package com.utopiaindustries.qualitychecker.models;
+
+public class InspectionDimension {
+
+ private long id;
+ private String title;
+
+ private String category;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ @Override
+ public String toString() {
+ return "InspectionDimension{" +
+ "id=" + id +
+ ", title='" + title + '\'' +
+ ", category='" + category + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemCheckPoint.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemCheckPoint.java
new file mode 100644
index 0000000..7cdfeed
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemCheckPoint.java
@@ -0,0 +1,111 @@
+package com.utopiaindustries.qualitychecker.models;
+
+import java.util.Arrays;
+
+public class InspectionItemCheckPoint {
+
+ private long id;
+ private long inspectionItemId;
+ private String title;
+ private boolean checked;
+ private String remarks;
+ // wrapper
+ private String defectSeverity;
+ private InspectionItemDefect defect;
+ private byte[] file;
+ private String imagePath;
+
+ private String defectTitle;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public boolean getChecked() {
+ return checked;
+ }
+
+ public void setChecked(boolean checked) {
+ this.checked = checked;
+ }
+
+ public String getRemarks() {
+ return remarks;
+ }
+
+ public void setRemarks(String remarks) {
+ this.remarks = remarks;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getInspectionItemId() {
+ return inspectionItemId;
+ }
+
+ public void setInspectionItemId(long inspectionItemId) {
+ this.inspectionItemId = inspectionItemId;
+ }
+
+ public byte[] getFile() {
+ return file;
+ }
+
+ public void setFile(byte[] file) {
+ this.file = file;
+ }
+
+ public String getDefectSeverity() {
+ return defectSeverity;
+ }
+
+ public void setDefectSeverity(String defectSeverity) {
+ this.defectSeverity = defectSeverity;
+ }
+
+ public void setDefect(InspectionItemDefect defect) {
+ this.defect = defect;
+ }
+
+ public String getDefectTitle() {
+ return defectTitle;
+ }
+
+ public void setDefectTitle(String defectTitle) {
+ this.defectTitle = defectTitle;
+ }
+
+ public String getImagePath() {
+ return imagePath;
+ }
+
+ public void setImagePath(String imagePath) {
+ this.imagePath = imagePath;
+ }
+
+ @Override
+ public String toString() {
+ return "InspectionItemCheckPoint{" +
+ "id=" + id +
+ ", inspectionItemId=" + inspectionItemId +
+ ", title='" + title + '\'' +
+ ", checked=" + checked +
+ ", remarks='" + remarks + '\'' +
+ ", defectSeverity='" + defectSeverity + '\'' +
+ ", defect=" + defect +
+ ", file=" + Arrays.toString(file) +
+ ", imagePath='" + imagePath + '\'' +
+ ", defectTitle='" + defectTitle + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDefect.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDefect.java
new file mode 100644
index 0000000..cba5ba0
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDefect.java
@@ -0,0 +1,64 @@
+package com.utopiaindustries.qualitychecker.models;
+
+import java.util.Arrays;
+
+public class InspectionItemDefect {
+
+ private long id;
+ private long cpId;
+ private String title;
+ private String defectSeverity;
+ // wrapper
+ private byte[] file;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getCpId() {
+ return cpId;
+ }
+
+ public void setCpId(long cpId) {
+ this.cpId = cpId;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDefectSeverity() {
+ return defectSeverity;
+ }
+
+ public void setDefectSeverity(String defectSeverity) {
+ this.defectSeverity = defectSeverity;
+ }
+
+ public byte[] getFile() {
+ return file;
+ }
+
+ public void setFile(byte[] file) {
+ this.file = file;
+ }
+
+
+ @Override
+ public String toString() {
+ return "InspectionItemDefect{" +
+ "id=" + id +
+ ", cpId=" + cpId +
+ ", title='" + title + '\'' +
+ ", file=" + Arrays.toString(file) +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDimension.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDimension.java
new file mode 100644
index 0000000..c18fc26
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionItemDimension.java
@@ -0,0 +1,92 @@
+package com.utopiaindustries.qualitychecker.models;
+
+
+public class InspectionItemDimension {
+
+ private long id;
+ private long inspectionItemId;
+ private String type;
+ private float actual;
+ private float required;
+ private float difference;
+ private String unit;
+
+ public InspectionItemDimension() {
+ }
+ public InspectionItemDimension(String type, float actual, float required, float difference, String unit) {
+ this.type = type;
+ this.actual = actual;
+ this.required = required;
+ this.difference = difference;
+ this.unit = unit;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getInspectionItemId() {
+ return inspectionItemId;
+ }
+
+ public void setInspectionItemId(long inspectionItemId) {
+ this.inspectionItemId = inspectionItemId;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public float getActual() {
+ return actual;
+ }
+
+ public void setActual(float actual) {
+ this.actual = actual;
+ }
+
+ public float getRequired() {
+ return required;
+ }
+
+ public void setRequired(float required) {
+ this.required = required;
+ }
+
+ public float getDifference() {
+ return difference;
+ }
+
+ public void setDifference(float difference) {
+ this.difference = difference;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+ @Override
+ public String toString() {
+ return "InspectionItemDimension{" +
+ "id=" + id +
+ ", inspectionItemId=" + inspectionItemId +
+ ", type='" + type + '\'' +
+ ", actual=" + actual +
+ ", required=" + required +
+ ", difference=" + difference +
+ ", unit='" + unit + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java
new file mode 100644
index 0000000..8888367
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReport.java
@@ -0,0 +1,140 @@
+package com.utopiaindustries.qualitychecker.models;
+
+import androidx.annotation.NonNull;
+import java.util.List;
+
+public class InspectionReport {
+
+ private long id;
+ private boolean fri;
+ private String code;
+ private String generatedBy;
+ private String generatedAt;
+ private long siteId;
+ private long floorId;
+ private long departmentId;
+ private long functionId;
+ private String generalRemarks;
+ private String reportResult;
+
+ // wrapper
+ List items;
+
+ public InspectionReport(){
+ this.fri = true;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getGeneratedBy() {
+ return generatedBy;
+ }
+
+ public void setGeneratedBy(String generatedBy) {
+ this.generatedBy = generatedBy;
+ }
+
+ public String getGeneratedAt() {
+ return generatedAt;
+ }
+
+ public void setGeneratedAt(String generatedAt) {
+ this.generatedAt = generatedAt;
+ }
+
+ public long getSiteId() {
+ return siteId;
+ }
+
+ public void setSiteId(long siteId) {
+ this.siteId = siteId;
+ }
+
+ public long getFloorId() {
+ return floorId;
+ }
+
+ public void setFloorId(long floorId) {
+ this.floorId = floorId;
+ }
+
+ public long getDepartmentId() {
+ return departmentId;
+ }
+
+ public void setDepartmentId(long departmentId) {
+ this.departmentId = departmentId;
+ }
+
+ public long getFunctionId() {
+ return functionId;
+ }
+
+ public void setFunctionId(long functionId) {
+ this.functionId = functionId;
+ }
+
+ public String getGeneralRemarks() {
+ return generalRemarks;
+ }
+
+ public void setGeneralRemarks(String generalRemarks) {
+ this.generalRemarks = generalRemarks;
+ }
+
+ public String getReportResult() {
+ return reportResult;
+ }
+
+ public void setReportResult(String reportResult) {
+ this.reportResult = reportResult;
+ }
+
+ public List getItems() {
+ return items;
+ }
+
+ public void setItems(List items) {
+ this.items = items;
+ }
+
+ public boolean getFri() {
+ return fri;
+ }
+
+ public void setFri(boolean fri) {
+ this.fri = fri;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "InspectionReport{" +
+ "id=" + id +
+ ", code='" + code + '\'' +
+ ", generatedBy='" + generatedBy + '\'' +
+ ", generatedAt=" + generatedAt +
+ ", siteId=" + siteId +
+ ", floorId=" + floorId +
+ ", departmentId=" + departmentId +
+ ", functionId=" + functionId +
+ ", generalRemarks='" + generalRemarks + '\'' +
+ ", reportResult='" + reportResult + '\'' +
+ ", items=" + items +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportItem.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportItem.java
new file mode 100644
index 0000000..90a1f2f
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/InspectionReportItem.java
@@ -0,0 +1,267 @@
+package com.utopiaindustries.qualitychecker.models;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
+public class InspectionReportItem {
+
+ private long id;
+ private long reportId;
+ private String asin;
+ private String parentAsin;
+ private String marketplace;
+ private String sku;
+ private String title;
+ private String hsCode;
+ private String modelNumber;
+ private long itemPerBox;
+ private String smColor;
+ private String smSize;
+ private String smItemName;
+ private String orderNumber;
+ private String article;
+ private float totalPresentPieces;
+ private float totalPresentPacks;
+ private float totalPresentCartons;
+ // sqrt( totalPresentCartons )
+ private float cartonsSelected;
+ private float packsSelected;
+ private float piecesSelected;
+ private String packingDetails;
+ private String sampleSize;
+ private String dateAdded;
+ // wrapper
+ private List checkPoints;
+ private List dimensions;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getReportId() {
+ return reportId;
+ }
+
+ public void setReportId(long reportId) {
+ this.reportId = reportId;
+ }
+
+ public String getAsin() {
+ return asin;
+ }
+
+ public void setAsin(String asin) {
+ this.asin = asin;
+ }
+
+ public String getParentAsin() {
+ return parentAsin;
+ }
+
+ public void setParentAsin(String parentAsin) {
+ this.parentAsin = parentAsin;
+ }
+
+ public String getMarketplace() {
+ return marketplace;
+ }
+
+ public void setMarketplace(String marketplace) {
+ this.marketplace = marketplace;
+ }
+
+ public String getSku() {
+ return sku;
+ }
+
+ public void setSku(String sku) {
+ this.sku = sku;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getHsCode() {
+ return hsCode;
+ }
+
+ public void setHsCode(String hsCode) {
+ this.hsCode = hsCode;
+ }
+
+ public String getModelNumber() {
+ return modelNumber;
+ }
+
+ public void setModelNumber(String modelNumber) {
+ this.modelNumber = modelNumber;
+ }
+
+ public long getItemPerBox() {
+ return itemPerBox;
+ }
+
+ public void setItemPerBox(long itemPerBox) {
+ this.itemPerBox = itemPerBox;
+ }
+
+ public String getSmColor() {
+ return smColor;
+ }
+
+ public void setSmColor(String smColor) {
+ this.smColor = smColor;
+ }
+
+ public String getSmSize() {
+ return smSize;
+ }
+
+ public void setSmSize(String smSize) {
+ this.smSize = smSize;
+ }
+
+ public String getSmItemName() {
+ return smItemName;
+ }
+
+ public void setSmItemName(String smItemName) {
+ this.smItemName = smItemName;
+ }
+
+ public List getCheckPoints() {
+ return checkPoints;
+ }
+
+ public void setCheckPoints(List checkPoints) {
+ this.checkPoints = checkPoints;
+ }
+
+ public List getDimensions() {
+ return dimensions;
+ }
+
+ public void setDimensions(List dimensions) {
+ this.dimensions = dimensions;
+ }
+
+ public String getOrderNumber() {
+ return orderNumber;
+ }
+
+ public void setOrderNumber(String orderNumber) {
+ this.orderNumber = orderNumber;
+ }
+
+ public String getArticle() {
+ return article;
+ }
+
+ public void setArticle(String article) {
+ this.article = article;
+ }
+
+ public float getTotalPresentPieces() {
+ return totalPresentPieces;
+ }
+
+ public void setTotalPresentPieces(float totalPresentPieces) {
+ this.totalPresentPieces = totalPresentPieces;
+ }
+
+ public float getTotalPresentPacks() {
+ return totalPresentPacks;
+ }
+
+ public void setTotalPresentPacks(float totalPresentPacks) {
+ this.totalPresentPacks = totalPresentPacks;
+ }
+
+ public float getTotalPresentCartons() {
+ return totalPresentCartons;
+ }
+
+ public void setTotalPresentCartons(float totalPresentCartons) {
+ this.totalPresentCartons = totalPresentCartons;
+ }
+
+ public float getCartonsSelected() {
+ return cartonsSelected;
+ }
+
+ public void setCartonsSelected(float cartonsSelected) {
+ this.cartonsSelected = cartonsSelected;
+ }
+
+ public float getPacksSelected() {
+ return packsSelected;
+ }
+
+ public void setPacksSelected(float packsSelected) {
+ this.packsSelected = packsSelected;
+ }
+
+ public String getPackingDetails() {
+ return packingDetails;
+ }
+
+ public void setPackingDetails(String packingDetails) {
+ this.packingDetails = packingDetails;
+ }
+
+ public float getPiecesSelected() {
+ return piecesSelected;
+ }
+
+ public void setPiecesSelected(float piecesSelected) {
+ this.piecesSelected = piecesSelected;
+ }
+
+ public String getSampleSize() {
+ return sampleSize;
+ }
+
+ public void setSampleSize(String sampleSize) {
+ this.sampleSize = sampleSize;
+ }
+
+ public String getDateAdded() {
+ return dateAdded;
+ }
+
+ public void setDateAdded(String dateAdded) {
+ this.dateAdded = dateAdded;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "InspectionAuditReportItem{" +
+ "id=" + id +
+ ", reportId=" + reportId +
+ ", asin='" + asin + '\'' +
+ ", parentAsin='" + parentAsin + '\'' +
+ ", marketplace='" + marketplace + '\'' +
+ ", sku='" + sku + '\'' +
+ ", title='" + title + '\'' +
+ ", hsCode='" + hsCode + '\'' +
+ ", modelNumber='" + modelNumber + '\'' +
+ ", itemPerBox=" + itemPerBox +
+ ", smColor='" + smColor + '\'' +
+ ", smSize='" + smSize + '\'' +
+ ", smItemName='" + smItemName + '\'' +
+ ", checkPoints=" + checkPoints +
+ ", dimensions=" + dimensions +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/ItemUnit.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/ItemUnit.java
new file mode 100644
index 0000000..d6e159f
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/ItemUnit.java
@@ -0,0 +1,37 @@
+package com.utopiaindustries.qualitychecker.models;
+
+public class ItemUnit {
+ private long id;
+ private String title;
+
+ public ItemUnit() {
+ }
+
+ public ItemUnit( String title ) {
+ this.title = title;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId( long id ) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle( String title ) {
+ this.title = title;
+ }
+
+ @Override
+ public String toString() {
+ return "ItemUnit{" +
+ "id=" + id +
+ ", title='" + title + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/Product.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/Product.java
new file mode 100644
index 0000000..c20d2ea
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/Product.java
@@ -0,0 +1,151 @@
+package com.utopiaindustries.qualitychecker.models;
+
+public class Product {
+
+ private String asin;
+ private String parentAsin;
+ private String marketplace;
+ private String sku;
+ private String title;
+ private String hsCode;
+ private String modelNumber;
+ private long itemPerBox;
+ private String smColor;
+ private String smSize;
+ private String smItemName;
+ private long itemPerPack;
+ private long inventory;
+ private String category;
+
+ public String getAsin() {
+ return asin;
+ }
+
+ public void setAsin(String asin) {
+ this.asin = asin;
+ }
+
+ public String getParentAsin() {
+ return parentAsin;
+ }
+
+ public void setParentAsin(String parentAsin) {
+ this.parentAsin = parentAsin;
+ }
+
+ public String getMarketplace() {
+ return marketplace;
+ }
+
+ public void setMarketplace(String marketplace) {
+ this.marketplace = marketplace;
+ }
+
+ public String getSku() {
+ return sku;
+ }
+
+ public void setSku(String sku) {
+ this.sku = sku;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getHsCode() {
+ return hsCode;
+ }
+
+ public void setHsCode(String hsCode) {
+ this.hsCode = hsCode;
+ }
+
+ public String getModelNumber() {
+ return modelNumber;
+ }
+
+ public void setModelNumber(String modelNumber) {
+ this.modelNumber = modelNumber;
+ }
+
+ public long getItemPerBox() {
+ return itemPerBox;
+ }
+
+ public void setItemPerBox(long itemPerBox) {
+ this.itemPerBox = itemPerBox;
+ }
+
+ public String getSmColor() {
+ return smColor;
+ }
+
+ public void setSmColor(String smColor) {
+ this.smColor = smColor;
+ }
+
+ public String getSmSize() {
+ return smSize;
+ }
+
+ public void setSmSize(String smSize) {
+ this.smSize = smSize;
+ }
+
+ public String getSmItemName() {
+ return smItemName;
+ }
+
+ public void setSmItemName(String smItemName) {
+ this.smItemName = smItemName;
+ }
+
+ public long getItemPerPack() {
+ return itemPerPack;
+ }
+
+ public void setItemPerPack(long itemPerPack) {
+ this.itemPerPack = itemPerPack;
+ }
+
+ public long getInventory() {
+ return inventory;
+ }
+
+ public void setInventory(long inventory) {
+ this.inventory = inventory;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ @Override
+ public String toString() {
+ return "Product{" +
+ "asin='" + asin + '\'' +
+ ", parentAsin='" + parentAsin + '\'' +
+ ", marketplace='" + marketplace + '\'' +
+ ", sku='" + sku + '\'' +
+ ", title='" + title + '\'' +
+ ", hsCode='" + hsCode + '\'' +
+ ", modelNumber='" + modelNumber + '\'' +
+ ", itemPerBox=" + itemPerBox +
+ ", smColor='" + smColor + '\'' +
+ ", smSize='" + smSize + '\'' +
+ ", smItemName='" + smItemName + '\'' +
+ ", itemPerPack=" + itemPerPack +
+ ", inventory=" + inventory +
+ ", category='" + category + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/models/SaveReportCallback.java b/app/src/main/java/com/utopiaindustries/qualitychecker/models/SaveReportCallback.java
new file mode 100644
index 0000000..5a205b9
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/SaveReportCallback.java
@@ -0,0 +1,6 @@
+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
new file mode 100644
index 0000000..5bd4531
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/models/VoiceOfCustomer.java
@@ -0,0 +1,80 @@
+package com.utopiaindustries.qualitychecker.models;
+
+public class VoiceOfCustomer {
+ private String mskus;
+ private String marketplace;
+ private String itemName;
+ private String fnsku;
+ private String pcxHealth;
+ private String imageUrl;
+ private String asin;
+
+ public String getFnsku() {
+ return fnsku;
+ }
+
+ public void setFnsku(String fnsku) {
+ this.fnsku = fnsku;
+ }
+
+ public String getPcxHealth() {
+ return pcxHealth;
+ }
+
+ public void setPcxHealth(String pcxHealth) {
+ this.pcxHealth = pcxHealth;
+ }
+
+ public String getMarketplace() {
+ return marketplace;
+ }
+
+ public void setMarketplace(String marketplace) {
+ this.marketplace = marketplace;
+ }
+
+ public String getAsin() {
+ return asin;
+ }
+
+ public void setAsin(String asin) {
+ this.asin = asin;
+ }
+
+ public String getImageUrl() {
+ return imageUrl;
+ }
+
+ public void setImageUrl(String imageUrl) {
+ this.imageUrl = imageUrl;
+ }
+
+ public String getMskus() {
+ return mskus;
+ }
+
+ public void setMskus(String mskus) {
+ this.mskus = mskus;
+ }
+
+
+ public String getItemName() {
+ return itemName;
+ }
+
+ public void setItemName(String itemName) {
+ this.itemName = itemName;
+ }
+
+
+ @Override
+ public String toString() {
+ return "VoiceOfCustomer{" +
+ "mskus='" + mskus + '\'' +
+ ", marketplace='" + marketplace + '\'' +
+ ", itemName='" + itemName + '\'' +
+ ", fnsku='" + fnsku + '\'' +
+ ", pcxHealth='" + pcxHealth + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/service/InspectionReportService.java b/app/src/main/java/com/utopiaindustries/qualitychecker/service/InspectionReportService.java
new file mode 100644
index 0000000..541a0bb
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/service/InspectionReportService.java
@@ -0,0 +1,118 @@
+package com.utopiaindustries.qualitychecker.service;
+
+import androidx.annotation.NonNull;
+
+import com.utopiaindustries.qualitychecker.apiservice.ApiService;
+import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory;
+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.store.Store;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class InspectionReportService {
+
+ private static InspectionReportService instance;
+ private ApiService apiService;
+ private List defectTypes;
+ private List dimensionTypes;
+ private List reportResult;
+ private Store store;
+
+ // singleton instance
+ public synchronized static InspectionReportService getInstance(){
+ if( instance == null ){
+ instance = new InspectionReportService();
+ }
+ return instance;
+ }
+
+ // initialize api service
+ {
+ apiService = ApiServiceFactory.getApiService();
+ defectTypes = Arrays.asList( "CRITICAL","MINOR","MAJOR" );
+ dimensionTypes = Arrays.asList( "LENGTH", "WIDTH", "DROP" );
+ reportResult = Arrays.asList("PASSED","FAILED");
+ store = Store.getInstance();
+ }
+
+ public void isUserAuthenticated( String username,
+ String password,
+ String[] roles,
+ Callback callback){
+
+
+ apiService.isUserAuthenticated(username, password, roles).enqueue(
+ new Callback() {
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
+ if (response.isSuccessful()) {
+ callback.onResponse(call, response);
+ } else {
+ // Handle error
+ callback.onFailure(call, new Throwable("Failed to authenticate user"));
+ }
+ }
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ // Handle failure
+ callback.onFailure(call, t);
+ }
+ });
+ }
+
+ public List getDefectTypes(){
+ return defectTypes;
+ }
+ public List getDimensionTypes(){return dimensionTypes;}
+
+ public List getReportResult() {
+ return reportResult;
+ }
+
+ public void setReportResult(List reportResult) {
+ this.reportResult = reportResult;
+ }
+
+ public void saveReport(InspectionReport inspectionReport , SaveReportCallback callback){
+
+ if( Objects.nonNull( inspectionReport ) && inspectionReport.getItems().get(0).getSku() != null && inspectionReport.getItems() != null &&
+ ! inspectionReport.getItems().isEmpty() &&
+ ! inspectionReport.getItems().get(0).getCheckPoints().isEmpty() ){
+ // populate defects in cp
+ for( InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints() ){
+ InspectionItemDefect defect = new InspectionItemDefect();
+ defect.setDefectSeverity(itemCp.getDefectSeverity());
+ defect.setTitle( itemCp.getDefectTitle() );
+ itemCp.setDefect( defect );
+ }
+ // post object
+ apiService.saveInspectionReport( inspectionReport ).enqueue(
+ new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()) {
+ callback.onSuccess();
+ } else {
+ callback.onFailure(new Exception("API call failed with status code: " + response.code()));
+ }
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ callback.onFailure( t );
+ }
+ }
+ );
+ } else {
+ callback.onFailure( new Exception("Please Fill the required Fields..") );
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/store/Store.java b/app/src/main/java/com/utopiaindustries/qualitychecker/store/Store.java
new file mode 100644
index 0000000..a7fa2ad
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/store/Store.java
@@ -0,0 +1,212 @@
+package com.utopiaindustries.qualitychecker.store;
+
+import com.utopiaindustries.qualitychecker.apiservice.ApiService;
+import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory;
+import com.utopiaindustries.qualitychecker.models.EmployeePhoto;
+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.InspectionItemDimension;
+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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class Store {
+
+ private static Store instance;
+ private InspectionReport report;
+ private ApiService apiService;
+ private List checkPoints;
+ private List defects;
+ private List dimensionList;
+ private List dimensions;
+ private List products;
+ private EmployeePhoto employeePhoto;
+ private List itemUnits;
+
+ private Store(){
+ }
+
+ public static synchronized Store getInstance(){
+ if( instance == null ){
+ instance = new Store();
+ }
+ return instance;
+ }
+
+ public synchronized void initializeNewReport() {
+ checkPoints = new ArrayList<>();
+ defects = new ArrayList<>();
+ dimensions = new ArrayList<>();
+ products = new ArrayList<>();
+ itemUnits = new ArrayList<>();
+ dimensionList = new ArrayList<>();
+ apiService = ApiServiceFactory.getApiService();
+ report = new InspectionReport();
+ InspectionReportItem item = new InspectionReportItem();
+ item.setDimensions( new ArrayList<>() );
+ report.setItems(Collections.singletonList( item ));
+
+ apiService.fetchCheckPoints().enqueue(
+ new Callback>() {
+ @Override
+ public void onResponse( Call> call,
+ Response> response) {
+ if( response.isSuccessful() && response.body() != null ){
+ checkPoints = response.body() ;
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+
+ apiService.fetchDefects().enqueue(
+ new Callback>() {
+ @Override
+ public void onResponse( Call> call,
+ Response> response) {
+ if( response.isSuccessful() && response.body() != null ){
+ defects = response.body();
+ }
+ }
+ @Override
+ public void onFailure( Call> call, Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+
+
+ apiService.fetchCheckPoints().enqueue(
+ new Callback>() {
+ @Override
+ public void onResponse(Call> call,
+ Response> response) {
+
+ if( response.isSuccessful() && response.body() != null ){
+ List itemCp = new ArrayList<>();
+ for( InspectionCheckPoint cp : response.body() ){
+ InspectionItemCheckPoint icp = new InspectionItemCheckPoint();
+ icp.setTitle( cp.getTitle() );
+ icp.setDefectSeverity("MINOR");
+ icp.setChecked( false );
+ icp.setRemarks("");
+ itemCp.add( icp );
+ }
+ report.getItems().get( 0 ).setCheckPoints( itemCp );
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+
+ apiService.fetchItemUnits().enqueue(
+ new Callback>() {
+ @Override
+ public void onResponse(Call> call,
+ Response> response) {
+ if( response.isSuccessful() && response.body() != null ){
+ System.out.println( response.body() );
+ itemUnits = response.body();
+ }
+ }
+
+ @Override
+ public void onFailure(Call> call,
+ Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+ }
+
+ public InspectionReport getReport() {
+ return report;
+ }
+
+ public void setReport(InspectionReport report) {
+ this.report = report;
+ }
+
+ public List getCheckPoints() {
+ return checkPoints;
+ }
+
+ public List getDefects() {
+ return defects;
+ }
+
+ public List getDimensions() {
+ return dimensions;
+ }
+
+ public void setDimensions(List dimensions) {
+ this.dimensions = dimensions;
+ }
+
+ public List getProducts() {
+ return products;
+ }
+
+ public void setProducts(List products) {
+ this.products = products;
+ }
+
+ public EmployeePhoto getEmployeePhoto() {
+ return employeePhoto;
+ }
+
+ public void setEmployeePhoto(EmployeePhoto employeePhoto) {
+ this.employeePhoto = employeePhoto;
+ }
+
+ public List getItemUnits() {
+ return itemUnits.stream().map( ItemUnit::getTitle ).collect(Collectors.toList());
+ }
+
+ public void setItemUnits(List itemUnits) {
+ this.itemUnits = itemUnits;
+ }
+
+ public String getProfileImage( ) {
+ if( employeePhoto != null ){
+ return "https://portal.utopiaindustries.pk/uind/employee-photo/" + employeePhoto.getEmployeeId() +".jpeg";
+ }
+ return "";
+ }
+
+ public List getDimensionList() {
+ return dimensionList.stream().map( InspectionDimension::getTitle ).collect(Collectors.toList());
+ }
+
+ public void setDimensionList(List dimensionList) {
+ this.dimensionList = dimensionList;
+ }
+
+ @Override
+ public String toString() {
+ return "Store{" +
+ "report=" + report +
+ ", apiService=" + apiService +
+ ", checkPoints=" + checkPoints +
+ ", defects=" + defects +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/HomeActivity.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/HomeActivity.java
new file mode 100644
index 0000000..0c110d0
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/HomeActivity.java
@@ -0,0 +1,171 @@
+package com.utopiaindustries.qualitychecker.ui.activities;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.activity.EdgeToEdge;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.apiservice.ApiService;
+import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory;
+import com.utopiaindustries.qualitychecker.models.EmployeePhoto;
+import com.utopiaindustries.qualitychecker.models.InspectionReport;
+import com.utopiaindustries.qualitychecker.store.Store;
+import com.utopiaindustries.qualitychecker.ui.adapter.ReportAdapter;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class HomeActivity extends AppCompatActivity implements View.OnClickListener {
+
+ private Button createReportBtn,refreshReportsBtn,logoutBtn;
+ private RecyclerView recyclerView;
+ private ApiService apiService;
+ private TextView usernameTitle;
+ private ImageView profileImage;
+ private Store store;
+
+ @SuppressLint("SourceLockedOrientationActivity")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ EdgeToEdge.enable(this);
+ if( ! isNetworkConnected() ){
+ Toast.makeText( this, "No Internet Connection", Toast.LENGTH_LONG ).show();
+ }
+ setContentView(R.layout.activity_home);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+ setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT );
+
+ // initialize views
+ store = Store.getInstance();
+ apiService = ApiServiceFactory.getApiService();
+ createReportBtn = findViewById( R.id.create_report_btn );
+ refreshReportsBtn = findViewById( R.id.refresh_btn );
+ logoutBtn = findViewById( R.id.logout_btn );
+ recyclerView = findViewById( R.id.reports_recyclerview );
+ usernameTitle = findViewById( R.id.username_title );
+ profileImage = findViewById( R.id.profile_image );
+
+ refreshReportsBtn.setOnClickListener( this );
+ createReportBtn.setOnClickListener( this );
+ logoutBtn.setOnClickListener( this );
+
+ recyclerView.setLayoutManager( new LinearLayoutManager( this ) );
+
+ updateProfileImage();
+ refreshReportData();
+ }
+
+ private void refreshReportData(){
+ SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE);
+ String username = sharedPreferences.getString("username", null );
+ apiService.fetchAllReports( username ).enqueue(
+ new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if( response.isSuccessful() && response.body() != null ){
+ System.out.println( response.body() );
+ ReportAdapter adapter = new ReportAdapter( response.body() );
+ recyclerView.setAdapter( adapter );
+ } else {
+ System.out.println("Error");
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if( id == R.id.create_report_btn ){
+ Intent intent = new Intent( this, MainActivity.class );
+ startActivity( intent );
+ }
+ if( id == R.id.logout_btn ){
+ SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putString("username", null );
+ editor.putString("password", null );
+ editor.apply();
+ Intent intent = new Intent( HomeActivity.this, LoginActivity.class );
+ startActivity( intent );
+ finish();
+ }
+ if( id == R.id.refresh_btn ){
+ refreshReportData();
+ updateProfileImage();
+ }
+ }
+
+ private void updateProfileImage(){
+ SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE);
+ String username = sharedPreferences.getString("username", null );
+ System.out.println( );
+ if( username != null ){
+ apiService.fetchEmployeePhoto( username ).enqueue(
+ new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ System.out.println( response.body() );
+ if( response.isSuccessful() && response.body() != null ){
+ System.out.println( response.body() );
+ usernameTitle.setText( response.body().getName() );
+ store.setEmployeePhoto( response.body() );
+ Glide.with( getBaseContext() )
+ .load( store.getProfileImage( ) )
+ .into( profileImage );
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+
+ }
+ }
+ private boolean isNetworkConnected() {
+ ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
+ return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ refreshReportData();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/LoginActivity.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/LoginActivity.java
new file mode 100644
index 0000000..70c7804
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/LoginActivity.java
@@ -0,0 +1,142 @@
+package com.utopiaindustries.qualitychecker.ui.activities;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+import androidx.activity.EdgeToEdge;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.service.InspectionReportService;
+import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.textfield.TextInputEditText;
+
+import java.util.Objects;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class LoginActivity extends AppCompatActivity {
+
+ private TextInputEditText username,password;
+ private ProgressBar progressBar;
+ private Button loginButton;
+ private InspectionReportService reportService;
+
+ @SuppressLint("SourceLockedOrientationActivity")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ EdgeToEdge.enable(this);
+ if( ! isNetworkConnected() ){
+ Toast.makeText( this, "No Internet Connection", Toast.LENGTH_LONG ).show();
+ }
+ reportService = InspectionReportService.getInstance();
+ isUserAlreadyLoginAndAuthorize();
+ setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT );
+ setContentView(R.layout.activity_login);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+
+ username = findViewById( R.id.username );
+ password = findViewById( R.id.password );
+ loginButton = findViewById( R.id.login_btn );
+ progressBar = findViewById( R.id.progressBar );
+
+ SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+
+ loginButton.setOnClickListener(v -> {
+ try {
+ progressBar.setVisibility( View.VISIBLE );
+ String usernameStr = Objects.requireNonNull( username.getText() ).toString().trim();
+ String passwordStr = Objects.requireNonNull( password.getText() ).toString().trim();
+ // check both are valid
+ if( ! usernameStr.isEmpty() && ! passwordStr.isEmpty() ) {
+ reportService.isUserAuthenticated(usernameStr, passwordStr, new String[]{"ROLE_UIM_QA_APP_ACCESS_YES"}, new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if( response.isSuccessful() && response.body() != null && response.body() ){
+ editor.putString("username", usernameStr );
+ editor.putString("password", passwordStr );
+ editor.apply();
+ progressBar.setVisibility( View.INVISIBLE );
+ Intent intent = new Intent( LoginActivity.this, HomeActivity.class );
+ startActivity( intent );
+ // close login screen
+ LoginActivity.this.finish();
+ } else {
+ progressBar.setVisibility( View.INVISIBLE );
+ Snackbar.make( v, "Invalid Credential or Access not Authorized", Snackbar.LENGTH_LONG ).show();
+ }
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ progressBar.setVisibility( View.INVISIBLE );
+ Snackbar.make( v, "Something went wrong", Snackbar.LENGTH_LONG ).show();
+ }
+ });
+ }
+ else {
+ Snackbar.make( v, "Please Enter Your Credentials!!", Snackbar.LENGTH_LONG ).show();
+ progressBar.setVisibility( View.INVISIBLE );
+ }
+ } catch ( NullPointerException exception ){
+ Snackbar.make( v, Objects.requireNonNull( exception.getMessage() ), Snackbar.LENGTH_LONG ).show();
+ }
+ });
+ }
+
+ private void isUserAlreadyLoginAndAuthorize() {
+ SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE);
+
+ String username = sharedPreferences.getString("username", null);
+ String password = sharedPreferences.getString("password", null);
+
+ reportService.isUserAuthenticated(username,
+ password,
+ new String[]{"ROLE_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() {
+ ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
+ return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/MainActivity.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/MainActivity.java
new file mode 100644
index 0000000..0f85c22
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/activities/MainActivity.java
@@ -0,0 +1,104 @@
+package com.utopiaindustries.qualitychecker.ui.activities;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Toast;
+
+import androidx.activity.EdgeToEdge;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.navigation.fragment.NavHostFragment;
+
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.store.Store;
+import com.utopiaindustries.qualitychecker.ui.fragments.FirstStepFragment;
+import com.utopiaindustries.qualitychecker.ui.fragments.SecondStepFragment;
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+
+public class MainActivity extends AppCompatActivity implements View.OnClickListener {
+
+ private NavController navController;
+ private Store store;
+
+ {
+ store = Store.getInstance();
+ store.initializeNewReport();
+ }
+
+ @SuppressLint("SourceLockedOrientationActivity")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ EdgeToEdge.enable(this);
+ setContentView(R.layout.activity_main);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+ setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT );
+
+ // initializing fields
+ navController = Navigation.findNavController( this, R.id.nav_host_fragment );
+ updateUsername();
+ }
+ private void updateUsername() {
+ if ( store.getReport() != null ) {
+ SharedPreferences sharedPreferences = getSharedPreferences("login_prefs", Context.MODE_PRIVATE);
+ String username = sharedPreferences.getString("username", null);
+ store.getReport().setGeneratedBy(username);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ System.out.println( navController.getCurrentDestination().getId() );
+ navigate("","",R.id.action_firstStepFragment_to_secondStepFragment );
+ }
+
+ private void navigate(String fromFragment,
+ String toFragment,
+ int toId ){
+ System.out.println( navController.getCurrentDestination().getId() );
+ navController.navigate( toId );
+ }
+
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
+ if (result != null) {
+ if (result.getContents() == null) {
+ Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ FirstStepFragment firstStepFragment = ( FirstStepFragment) getCurrentVisibleFragment();
+ firstStepFragment.onBarcodeScanResult( result.getContents() );
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ SecondStepFragment secondStepFragment = ( SecondStepFragment) getCurrentVisibleFragment();
+ secondStepFragment.onImagePickerResult( requestCode, resultCode, data );
+ }
+ }
+
+ private Fragment getCurrentVisibleFragment() {
+ NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().getPrimaryNavigationFragment();
+ assert navHostFragment != null;
+ FragmentManager fragmentManager = navHostFragment.getChildFragmentManager();
+ return fragmentManager.getPrimaryNavigationFragment();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/CheckPointAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/CheckPointAdapter.java
new file mode 100644
index 0000000..227357f
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/CheckPointAdapter.java
@@ -0,0 +1,248 @@
+package com.utopiaindustries.qualitychecker.ui.adapter;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint;
+import com.utopiaindustries.qualitychecker.models.InspectionDefect;
+import com.utopiaindustries.qualitychecker.models.InspectionItemCheckPoint;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class CheckPointAdapter extends
+ RecyclerView.Adapter {
+
+ private final List checkPointList;
+ private final List checkPoints;
+ private final List defects;
+ private final List defectTypes;
+ private final Context context;
+ public CheckPointAdapter( List checkPointList,
+ List checkPoints,
+ List defects,
+ List defectTypes,
+ Context context ) {
+
+ this.checkPointList = checkPointList;
+ this.checkPoints = checkPoints;
+ this.defects = defects;
+ this.defectTypes = defectTypes;
+ this.context = context;
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from( parent.getContext() )
+ .inflate(R.layout.check_point, parent, false);
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ InspectionItemCheckPoint checkPoint = checkPointList.get( position );
+ holder.bind(checkPoints, defects, defectTypes, checkPoint);
+ // spinner on change
+ {
+ holder.checkpointSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ String selectedItem = parent.getItemAtPosition(position).toString();
+ InspectionCheckPoint cp = checkPoints.stream().filter(check -> check.getTitle().equalsIgnoreCase(selectedItem))
+ .findFirst().orElse(new InspectionCheckPoint());
+ holder.populateDefects(cp, defects, checkPoint);
+ checkPoint.setTitle(selectedItem);
+ }
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ }
+ });
+
+ holder.defectsSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ String selectedItem = parent.getItemAtPosition(position).toString();
+ checkPoint.setDefectTitle(selectedItem);
+ }
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ }
+ });
+
+ holder.defectTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ String selectedItem = parent.getItemAtPosition(position).toString();
+ checkPoint.setDefectSeverity(selectedItem);
+ }
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+
+ }
+ });
+ }
+ // checkboxes on change
+ {
+ holder.okCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if (isChecked) {
+ holder.linearLayout.setVisibility(View.INVISIBLE);
+ }
+ checkPoint.setChecked ( false );
+ holder.noCheckBox.setChecked( !isChecked );
+ });
+
+ holder.noCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if (isChecked) {
+ holder.linearLayout.setVisibility(View.VISIBLE);
+ }
+ checkPoint.setChecked( true );
+ holder.okCheckBox.setChecked( !isChecked );
+ });
+ }
+ // remarks on change
+ {
+ holder.remarks.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ checkPoint.setRemarks( s.toString() );
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
+ });
+ }
+
+ holder.imagePicker.setOnClickListener( v -> {
+ Intent intent = new Intent( Intent.ACTION_GET_CONTENT );
+ intent.addCategory( Intent.CATEGORY_OPENABLE );
+ intent.setType( "image/*" );
+ ( ( Activity ) context ).startActivityForResult( intent, position );
+ });
+
+ holder.deleteImage.setOnClickListener( v -> {
+ checkPoint.setFile( null );
+ checkPoint.setImagePath( "" );
+ holder.imagePreview.setImageDrawable( null );
+ notifyItemChanged( position );
+ });
+ }
+
+
+ @Override
+ public int getItemCount() {
+ return checkPointList.size();
+ }
+
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ private final Spinner checkpointSpinner, defectsSpinner, defectTypeSpinner;
+ private final CheckBox okCheckBox, noCheckBox;
+ private final EditText remarks;
+ private final ImageButton imagePicker,deleteImage;
+ private final LinearLayout linearLayout;
+ private final TextView selectedImage;
+ private final ImageView imagePreview;
+
+ public ViewHolder( @NonNull View itemView) {
+ super(itemView);
+ checkpointSpinner = itemView.findViewById(R.id.check_point_spinner);
+ okCheckBox = itemView.findViewById(R.id.check_point_ok);
+ noCheckBox = itemView.findViewById(R.id.check_point_no);
+ remarks = itemView.findViewById(R.id.check_point_remarks);
+ imagePicker = itemView.findViewById(R.id.image_picker );
+ selectedImage = itemView.findViewById( R.id.selected_image );
+ defectsSpinner = itemView.findViewById(R.id.defect_spinner);
+ defectTypeSpinner = itemView.findViewById(R.id.defect_type_spinner);
+ linearLayout = itemView.findViewById(R.id.defect_layout);
+ deleteImage = itemView.findViewById( R.id.delete_image );
+ imagePreview = itemView.findViewById( R.id.preview_image );
+ }
+ public void bind(List checkPoints,
+ List defects,
+ List defectTypeOptions,
+ InspectionItemCheckPoint data ) {
+ List checkPointsList = checkPoints.stream().map(InspectionCheckPoint::getTitle).collect(Collectors.toList());
+
+ // Populate checklist Spinner dropdown
+ ArrayAdapter spinnerAdapter = new ArrayAdapter<>(checkpointSpinner.getContext(),
+ android.R.layout.simple_spinner_item, checkPointsList);
+ spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ checkpointSpinner.setAdapter(spinnerAdapter);
+
+ // Populate defect type Spinner dropdown
+ ArrayAdapter defectTypeSpinnerAdapter = new ArrayAdapter<>(defectTypeSpinner.getContext(),
+ android.R.layout.simple_spinner_item, defectTypeOptions);
+ defectTypeSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ defectTypeSpinner.setAdapter(defectTypeSpinnerAdapter);
+
+ // Pre populate
+ String defaultSelectedItem = data.getTitle();
+ int defaultPosition = checkPointsList.indexOf(defaultSelectedItem);
+ checkpointSpinner.setSelection(defaultPosition);
+
+ String defaultSelectedDefectType = data.getDefectSeverity();
+ int defaultSelectedDefectTypePosition = defectTypeOptions.indexOf(defaultSelectedDefectType);
+ defectTypeSpinner.setSelection(defaultSelectedDefectTypePosition);
+
+ remarks.setText( data.getRemarks() );
+ okCheckBox.setChecked( data.getChecked() );
+ noCheckBox.setChecked( ! data.getChecked());
+
+ if( data.getChecked()){
+ linearLayout.setVisibility(View.INVISIBLE);
+ } else {
+ linearLayout.setVisibility(View.VISIBLE);
+ }
+
+ selectedImage.setText( data.getImagePath() );
+ if( data.getFile() != null ){
+ Bitmap bitmap = BitmapFactory.decodeByteArray( data.getFile(), 0 , data.getFile().length );
+ imagePreview.setImageBitmap( bitmap );
+ }
+ }
+ private void populateDefects(InspectionCheckPoint cp, List defects, InspectionItemCheckPoint data) {
+
+ List filteredDefects = defects.stream()
+ .filter(d -> d.getCategory().equalsIgnoreCase(cp.getCategory()))
+ .collect(Collectors.toList());
+ List defectList = filteredDefects.stream().map(InspectionDefect::getDefect).collect(Collectors.toList());
+ // Populate defect Spinner dropdown
+ ArrayAdapter defectSpinnerAdapter = new ArrayAdapter<>(defectsSpinner.getContext(),
+ android.R.layout.simple_spinner_item, defectList);
+ defectSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ defectsSpinner.setAdapter(defectSpinnerAdapter);
+
+ String defaultDefectSelectedItem = data.getDefectTitle();
+ int defaultSelectedDefectPosition = defectList.indexOf(defaultDefectSelectedItem);
+ defectsSpinner.setSelection(defaultSelectedDefectPosition);
+ }
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/DimensionAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/DimensionAdapter.java
new file mode 100644
index 0000000..db44904
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/DimensionAdapter.java
@@ -0,0 +1,187 @@
+package com.utopiaindustries.qualitychecker.ui.adapter;
+
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.Spinner;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.models.InspectionItemDimension;
+
+import java.util.List;
+
+public class DimensionAdapter extends
+ RecyclerView.Adapter{
+
+ private final List dimensions;
+ private final List dimensionTypes;
+ private final List dimensionUnits;
+ public DimensionAdapter(List dimensions, List dimensionTypes, List dimensionUnits) {
+ this.dimensions = dimensions;
+ this.dimensionTypes = dimensionTypes;
+ this.dimensionUnits = dimensionUnits;
+ }
+
+ @NonNull
+ @Override
+ public DimensionAdapter.DimensionAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.dimension_item , parent, false);
+ return new DimensionAdapterViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull DimensionAdapterViewHolder holder, int position) {
+ InspectionItemDimension item = dimensions.get( position );
+ holder.bind( item , dimensionTypes , dimensionUnits ) ;
+ holder.deleteItemBtn.setOnClickListener( v ->{
+ removeItem( holder.getAdapterPosition() );
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return dimensions.size();
+ }
+
+ public void removeItem(int position) {
+ if( position >= 0 && position < dimensions.size() ){
+ dimensions.remove(position);
+ notifyItemRemoved(position);
+ }
+ }
+
+
+ public static class DimensionAdapterViewHolder extends RecyclerView.ViewHolder {
+
+ private final Spinner dimensionTypeSpinner,dimensionUnitSpinner;
+ private final EditText requiredEditText,actualEditText,differenceEditText;
+ private final ImageButton deleteItemBtn;
+
+ public DimensionAdapterViewHolder(@NonNull View itemView) {
+ super(itemView);
+ dimensionTypeSpinner = itemView.findViewById( R.id.dimension_type_spinner );
+ dimensionUnitSpinner = itemView.findViewById( R.id.dimension_unit_spinner );
+ requiredEditText = itemView.findViewById( R.id.required );
+ actualEditText = itemView.findViewById( R.id.actual );
+ differenceEditText = itemView.findViewById( R.id.difference );
+ deleteItemBtn = itemView.findViewById( R.id.dimension_item_delete );
+ }
+
+ public void bind( InspectionItemDimension dimension ,
+ List dimensionTypes,
+ List dimensionUnits ){
+
+ // Populate dimension type Spinner dropdown
+ ArrayAdapter spinnerAdapter = new ArrayAdapter<>(dimensionTypeSpinner.getContext(),
+ android.R.layout.simple_spinner_item, dimensionTypes );
+ spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ dimensionTypeSpinner.setAdapter(spinnerAdapter);
+
+ String defaultSelection = dimension.getType();
+ int defaultSelectedPosition = dimensionTypes.indexOf(defaultSelection);
+ dimensionTypeSpinner.setSelection(defaultSelectedPosition);
+
+ // Populate dimension unit Spinner dropdown
+ ArrayAdapter unitSpinnerAdapter = new ArrayAdapter<>(dimensionUnitSpinner.getContext(),
+ android.R.layout.simple_spinner_item, dimensionUnits );
+ unitSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ dimensionUnitSpinner.setAdapter(unitSpinnerAdapter);
+
+ String defaultUnitSelection = dimension.getUnit();
+ int defaultItemSelectedPosition = dimensionUnits.indexOf(defaultUnitSelection);
+ dimensionUnitSpinner.setSelection(defaultItemSelectedPosition);
+
+
+ requiredEditText.setText( String.valueOf( dimension.getRequired() ));
+ actualEditText.setText( String.valueOf( dimension.getActual() ));
+ differenceEditText.setText( String.valueOf( dimension.getDifference() ));
+
+ // Spinner listener
+ {
+ dimensionTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ String selectedItem = parent.getItemAtPosition(position).toString();
+ dimension.setType( selectedItem );
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ }
+ });
+ }
+ // unit spinner
+ {
+ dimensionUnitSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ String selectedItem = parent.getItemAtPosition(position).toString();
+ dimension.setUnit( selectedItem );
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ }
+ });
+ }
+
+ // edit text listeners
+ {
+ requiredEditText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ try {
+ dimension.setRequired( Float.parseFloat( s.toString() ) );
+ float difference = dimension.getActual() - dimension.getRequired();
+ differenceEditText.setText( String.valueOf( difference ));
+ dimension.setDifference( difference );
+ } catch ( Exception e ){
+ differenceEditText.setText( "0" );
+ dimension.setDifference( 0 );
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+ });
+
+ actualEditText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ try {
+ dimension.setActual( Float.parseFloat( s.toString() ) );
+ float difference = dimension.getActual() - dimension.getRequired();
+ differenceEditText.setText( String.valueOf( difference ));
+ dimension.setDifference( difference );
+ } catch ( Exception e ){
+ differenceEditText.setText( "0" );
+ dimension.setDifference( 0 );
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ItemDimensionAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ItemDimensionAdapter.java
new file mode 100644
index 0000000..1d96bc9
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ItemDimensionAdapter.java
@@ -0,0 +1,62 @@
+package com.utopiaindustries.qualitychecker.ui.adapter;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.models.InspectionItemDimension;
+
+import java.util.List;
+
+public class ItemDimensionAdapter extends
+ RecyclerView.Adapter {
+
+ private final List dimensions;
+
+ public ItemDimensionAdapter( List dimensions ){
+ this.dimensions = dimensions;
+ }
+ @NonNull
+ @Override
+ public ItemDiemsionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_dimension , parent, false);
+ return new ItemDiemsionViewHolder( view );
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ItemDiemsionViewHolder holder, int position) {
+ InspectionItemDimension dimension = dimensions.get( position );
+ holder.bind( dimension );
+ }
+
+ @Override
+ public int getItemCount() {
+ return dimensions.size();
+ }
+
+ public static class ItemDiemsionViewHolder extends RecyclerView.ViewHolder{
+
+ private final EditText dimensionType,dimensionUnit,dimensionRequired,dimensionActual,dimensionDifference;
+
+ public ItemDiemsionViewHolder(@NonNull View itemView) {
+ super(itemView);
+ dimensionType = itemView.findViewById( R.id.dimension_type );
+ dimensionUnit = itemView.findViewById( R.id.dimension_unit );
+ dimensionRequired = itemView.findViewById( R.id.dimension_required );
+ dimensionActual = itemView.findViewById( R.id.dimension_actual );
+ dimensionDifference = itemView.findViewById( R.id.dimension_difference );
+ }
+ public void bind( InspectionItemDimension dimension ){
+ dimensionType.setText( dimension.getType() );
+ dimensionUnit.setText( dimension.getUnit() );
+ dimensionRequired.setText( String.valueOf( dimension.getRequired() ));
+ dimensionActual.setText( String.valueOf( dimension.getActual() ) );
+ dimensionDifference.setText( String.valueOf( dimension.getDifference() ));
+ }
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ItemHistoryAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ItemHistoryAdapter.java
new file mode 100644
index 0000000..8ac5e4f
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ItemHistoryAdapter.java
@@ -0,0 +1,84 @@
+package com.utopiaindustries.qualitychecker.ui.adapter;
+
+import android.annotation.SuppressLint;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.models.InspectionReportItem;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+public class ItemHistoryAdapter extends
+ RecyclerView.Adapter {
+
+ private final List items;
+
+ public ItemHistoryAdapter(List items) {
+ this.items = items;
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_history_item, parent, false);
+ return new ViewHolder( view );
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ InspectionReportItem item = items.get( position );
+ try {
+ holder.bind( item );
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+
+ private final TextView itemSku,itemAsin,itemDate,itemCartons,itemPacks,itemPieces;
+
+ public ViewHolder(@NonNull View itemView) {
+ super(itemView);
+ itemSku = itemView.findViewById( R.id.item_history_sku );
+ itemAsin = itemView.findViewById( R.id.item_history_asin );
+ itemDate = itemView.findViewById( R.id.item_history_date );
+ itemCartons = itemView.findViewById( R.id.item_history_cartons );
+ itemPacks = itemView.findViewById( R.id.item_history_packs );
+ itemPieces = itemView.findViewById( R.id.item_history_pieces );
+ }
+
+ @SuppressLint("DefaultLocale")
+ public void bind(InspectionReportItem item ) throws ParseException {
+ SimpleDateFormat jsonDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
+ SimpleDateFormat displayDateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm a", Locale.getDefault());
+ itemSku.setText( item.getSku() );
+ itemAsin.setText( item.getAsin() );
+ if( item.getDateAdded() != null ){
+ Date date = jsonDateFormat.parse( item.getDateAdded() );
+ String formattedDateTime = displayDateFormat.format( date );
+ itemDate.setText( formattedDateTime );
+ } else {
+ itemDate.setText("");
+ }
+ itemCartons.setText( String.format("Cartons : %f", item.getCartonsSelected() ) );
+ itemPacks.setText( String.format("Packs : %f", item.getPacksSelected() ) );
+ itemPieces.setText( String.format("Pieces : %f", item.getPiecesSelected() ) );
+ }
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ReportAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ReportAdapter.java
new file mode 100644
index 0000000..acbfe56
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/ReportAdapter.java
@@ -0,0 +1,81 @@
+package com.utopiaindustries.qualitychecker.ui.adapter;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.models.InspectionReport;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+public class ReportAdapter extends
+ RecyclerView.Adapter{
+ private final List reports;
+
+ public ReportAdapter(List reports) {
+ this.reports = reports;
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from( parent.getContext() ).inflate(R.layout.report_item , parent, false);
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ try {
+ holder.bindDate( reports.get( position ) );
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return reports.size();
+ }
+
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ private final TextView codeTv,createdByTv, remarksTv,dateTv,status;
+ private final SimpleDateFormat jsonDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
+ private final SimpleDateFormat displayDateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm a", Locale.getDefault());
+
+ public ViewHolder(@NonNull View itemView) {
+ super(itemView);
+ codeTv = itemView.findViewById( R.id.code );
+ createdByTv = itemView.findViewById( R.id.created_by );
+ remarksTv = itemView.findViewById( R.id.remarks );
+ dateTv = itemView.findViewById( R.id.date );
+ status = itemView.findViewById( R.id.status );
+ }
+
+ public void bindDate( InspectionReport report ) throws ParseException {
+ codeTv.setText( report.getCode() );
+ createdByTv.setText( report.getGeneratedBy() );
+ remarksTv.setText( report.getGeneralRemarks() );
+
+ Date date = jsonDateFormat.parse( report.getGeneratedAt() );
+ // Format the date in 12-hour format
+ String formattedDateTime = displayDateFormat.format( date );
+ dateTv.setText( formattedDateTime );
+ if( report.getReportResult().equalsIgnoreCase("FAILED") ){
+ status.setBackgroundResource( R.drawable.failed_bg );
+ }
+ if( report.getReportResult().equalsIgnoreCase("Passed") ){
+ status.setBackgroundResource( R.drawable.passed_bg );
+ }
+ status.setText( report.getReportResult() );
+ }
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/VocAdapter.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/VocAdapter.java
new file mode 100644
index 0000000..4402837
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/adapter/VocAdapter.java
@@ -0,0 +1,79 @@
+package com.utopiaindustries.qualitychecker.ui.adapter;
+
+import static com.utopiaindustries.qualitychecker.ui.adapter.VocAdapter.*;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.models.VoiceOfCustomer;
+
+import java.util.List;
+
+public class VocAdapter extends
+ RecyclerView.Adapter {
+
+ private final List vocs;
+ private final Context context;
+
+ public VocAdapter (List vocs, Context context) {
+ this.vocs = vocs;
+ this.context = context;
+ }
+
+ @NonNull
+ @Override
+ public VocViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.voc_item, parent, false);
+ return new VocViewHolder( view , context);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull VocViewHolder holder, int position) {
+ VoiceOfCustomer voc = vocs.get( position );
+ holder.bind( voc );
+ }
+
+ @Override
+ public int getItemCount() {
+ return vocs.size();
+ }
+
+ public static class VocViewHolder extends RecyclerView.ViewHolder {
+
+ private final TextView asin, fnsku,health,item,markeplace;
+ private final ImageView imageView;
+ private final Context context;
+
+ public VocViewHolder(@NonNull View itemView, Context context) {
+ super(itemView);
+ this.context = context;
+ asin = itemView.findViewById( R.id.asin );
+ fnsku = itemView.findViewById( R.id.fnsku );
+ health = itemView.findViewById( R.id.health );
+ item = itemView.findViewById( R.id.item );
+ markeplace = itemView.findViewById( R.id.marketplace );
+ imageView = itemView.findViewById( R.id.voc_item_imageview );
+ }
+
+ public void bind( VoiceOfCustomer voc ){
+ asin.setText( voc.getAsin() );
+ fnsku.setText( voc.getFnsku() );
+ health.setText( voc.getPcxHealth() );
+ item .setText( voc.getItemName() );
+ markeplace.setText( voc.getMarketplace() );
+ Glide.with( context )
+ .load( voc.getImageUrl() )
+ .into( imageView );
+
+ }
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/FirstStepFragment.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/FirstStepFragment.java
new file mode 100644
index 0000000..20b06e9
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/FirstStepFragment.java
@@ -0,0 +1,565 @@
+package com.utopiaindustries.qualitychecker.ui.fragments;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.apiservice.ApiService;
+import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory;
+import com.utopiaindustries.qualitychecker.models.InspectionDimension;
+import com.utopiaindustries.qualitychecker.models.InspectionReportItem;
+import com.utopiaindustries.qualitychecker.models.Product;
+import com.utopiaindustries.qualitychecker.store.Store;
+import com.utopiaindustries.qualitychecker.ui.adapter.ItemHistoryAdapter;
+import com.google.android.material.snackbar.Snackbar;
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.journeyapps.barcodescanner.CaptureActivity;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class FirstStepFragment extends Fragment implements View.OnClickListener {
+
+ private NavController navController;
+ private Button leftFab,rightFab,showHistoryBtn;
+ private EditText sku,boxCarton,itemPerBox,pieces,packagingDetails,boxCartonSelected,itemPerBoxSelected,piecesSelected;
+ private Spinner markerplace,modelNumber,title,color,size;
+ private CheckBox fri,refri;
+ private ImageButton searchSku,scanBtn;
+ private TextView profileName;
+ private ImageView profileImage;
+ private ApiService apiService;
+ private Store store;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_first_step , container, false );
+ initializeViews( view );
+ apiService = ApiServiceFactory.getApiService();
+ store = Store.getInstance();
+ // set on click listener
+ leftFab.setOnClickListener( this );
+ rightFab.setOnClickListener( this );
+ searchSku.setOnClickListener( this );
+ scanBtn.setOnClickListener( this );
+ showHistoryBtn.setOnClickListener( this );
+ populateItem( store.getProducts() );
+ prePopulateData( store.getProducts() );
+
+
+ profileName.setText( store.getEmployeePhoto().getName() !=null ? store.getEmployeePhoto().getName() : "" );
+ Glide.with( getContext() )
+ .load( store.getProfileImage( ) )
+ .into( profileImage );
+
+ fri.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if( isChecked ){
+ store.getReport().setFri( true );
+ refri.setChecked( false );
+ } else {
+ store.getReport().setFri( false );
+ refri.setChecked( true );
+ }
+ });
+
+ refri.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if( isChecked ){
+ store.getReport().setFri( false );
+ fri.setChecked( false );
+ } else {
+ store.getReport().setFri( true );
+ fri.setChecked( true );
+ }
+ });
+ // marketplace
+ markerplace.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ if( parent.getItemAtPosition( position ) != null ){
+ String marketplaceOption = parent.getItemAtPosition( position ).toString();
+ store.getReport().getItems().get(0).setMarketplace( marketplaceOption );
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ store.getReport().getItems().get(0).setMarketplace("");
+ }
+ });
+
+ // title
+ title.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ if( parent.getItemAtPosition( position ) != null ){
+ String titleOption = parent.getItemAtPosition( position ).toString();
+ store.getReport().getItems().get(0).setTitle( titleOption );
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ store.getReport().getItems().get(0).setTitle("");
+ }
+ });
+
+ // model
+ modelNumber.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ if( parent.getItemAtPosition( position ) != null ){
+ String modelOption = parent.getItemAtPosition( position ).toString();
+ store.getReport().getItems().get(0).setModelNumber( modelOption );
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ store.getReport().getItems().get(0).setModelNumber("");
+ }
+ });
+
+ // color
+ color.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ if( parent.getItemAtPosition( position ) != null ){
+ String colorOption = parent.getItemAtPosition( position ).toString();
+ store.getReport().getItems().get(0).setSmColor( colorOption );
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ store.getReport().getItems().get(0).setSmColor("");
+ }
+ });
+
+ // size
+ size.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ if( parent.getItemAtPosition( position ) != null ){
+ String sizeOption = parent.getItemAtPosition( position ).toString();
+ store.getReport().getItems().get(0).setSmSize( sizeOption );
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ store.getReport().getItems().get(0).setSmSize("");
+ }
+ });
+
+ boxCartonSelected.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ try {
+ store.getReport().getItems().get(0).setCartonsSelected( Long.parseLong( s.toString() ) );
+ } catch ( Exception e ){
+ store.getReport().getItems().get(0).setCartonsSelected( 0 );
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
+ });
+
+ itemPerBoxSelected.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ try {
+ store.getReport().getItems().get(0).setPacksSelected( Long.parseLong( s.toString() ) );
+ } catch ( Exception e ){
+ store.getReport().getItems().get(0).setPacksSelected( 0 );
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
+ });
+
+ piecesSelected.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ try {
+ store.getReport().getItems().get(0).setPiecesSelected( Long.parseLong( s.toString() ) );
+ } catch ( Exception e ){
+ store.getReport().getItems().get(0).setPiecesSelected( 0 );
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
+ });
+
+// generalRemarks.addTextChangedListener(new TextWatcher() {
+// @Override
+// public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+//
+// }
+//
+// @Override
+// public void onTextChanged(CharSequence s, int start, int before, int count) {
+// try {
+// store.getReport().setGeneralRemarks( s.toString() );
+// } catch ( Exception e ){
+// store.getReport().setGeneralRemarks( "");
+// }
+// }
+//
+// @Override
+// public void afterTextChanged(Editable s) {
+//
+// }
+// });
+
+ return view;
+ }
+
+ @Override
+ public void onClick(View v) {
+ navController = Navigation.findNavController( requireView() );
+ if( v.getId() == R.id.button_left_frag_1 ){
+ if( getActivity() != null ){
+ getActivity().finish();
+ }
+ }
+ if( v.getId() == R.id.button_right_frag_1 ){
+ navController.navigate( R.id.action_firstStepFragment_to_secondStepFragment );
+ }
+ if( v.getId() == R.id.search_sku_btn ){
+ if( sku.getText() != null ){
+ String skuStr = sku.getText().toString().trim();
+ apiService.fetchProductBySku( skuStr ).enqueue(
+ new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if( response.isSuccessful() && response.body() != null ){
+ Product product = response.body().stream().findFirst().orElse(new Product());
+ store.getReport().getItems().get(0).setSku( skuStr );
+ store.getReport().getItems().get(0).setAsin( product.getAsin() );
+ populateItem( response.body() );
+ store.setProducts( response.body() );
+ } else {
+ Snackbar.make(v, "Error in response", Snackbar.LENGTH_LONG ).show();
+ }
+ }
+
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+ 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() );
+ }
+ }
+ );
+ }
+ }
+ if( v.getId() == R.id.scan_sku_btn ){
+ IntentIntegrator integrator = new IntentIntegrator( getActivity() );
+ integrator.setCaptureActivity(CaptureActivity.class);
+ integrator.setOrientationLocked( true );
+ integrator.setBarcodeImageEnabled( true );
+ integrator.initiateScan();
+ }
+ if( v.getId() == R.id.button_show_history ){
+ openItemHistoryDialog();
+ }
+ }
+
+ private void prePopulateData( List products ){
+ fri.setChecked( store.getReport().getFri() );
+ refri.setChecked( ! store.getReport().getFri() );
+ // sku
+ sku.setText( store.getReport().getItems().get(0).getSku() );
+ System.out.println( products );
+ System.out.println( store.getReport().getItems().get(0) );
+
+ if( ! products.isEmpty() ){
+ List modelNumbers = products.stream().map( Product::getModelNumber ).distinct().collect(Collectors.toList()) ;
+
+ String defaultModelSelection = store.getReport().getItems().get(0).getModelNumber();
+ int defaultModelSelectionIndex = modelNumbers.indexOf( defaultModelSelection );
+ modelNumber.setSelection( defaultModelSelectionIndex );
+ }
+
+ if( ! products.isEmpty() ){
+ List titles = products.stream().map( Product::getTitle ).distinct().collect(Collectors.toList()) ;
+ String defaultTitleSelection = store.getReport().getItems().get(0).getTitle();
+ int defaultTitleSelectionIndex = titles.indexOf( defaultTitleSelection );
+ title.setSelection( defaultTitleSelectionIndex );
+ }
+
+ }
+
+ private void populateItem( List products ){
+ populateMarketplaces( products );
+ populateMmodelNumber(products );
+ populateTitle( products );
+ populateColor( products );
+ populateSize( products );
+ populateItemPresentedDetails( products );
+ }
+
+ private void populateItemPresentedDetails( List products ){
+ try{
+ if( ! products.isEmpty() ){
+ Product product = products.get( 0 );
+ String inventory = String.valueOf( product.getInventory() );
+ String itemPerBoxText = String.valueOf( product.getInventory() * product.getItemPerPack() );
+ String boxCartonText = String.valueOf( ( product.getInventory() / product.getItemPerBox() ) );
+
+ @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 );
+ packagingDetails.setText( packagingDetailsText );
+
+ boxCartonSelected.setText( String.valueOf( store.getReport().getItems().get(0).getCartonsSelected() ));
+ itemPerBoxSelected.setText( String.valueOf( store.getReport().getItems().get(0).getPacksSelected() ) );
+ piecesSelected.setText( String.valueOf( store.getReport().getItems().get(0).getPiecesSelected() ) );
+ // generalRemarks.setText( store.getReport().getItems().get(0).getSampleSize() );
+
+ store.getReport().getItems().get(0).setTotalPresentPieces( Long.parseLong( inventory ) );
+ store.getReport().getItems().get(0).setTotalPresentPacks( Long.parseLong( itemPerBoxText ) );
+ store.getReport().getItems().get(0).setTotalPresentCartons( Long.parseLong( boxCartonText ) );
+ store.getReport().getItems().get(0).setPackingDetails( packagingDetailsText );
+
+ }
+ } catch ( Exception e){
+ itemPerBox.setText( "0" );
+ pieces.setText( "0" );
+ boxCarton.setText( "0" );
+ packagingDetails.setText( "" );
+ }
+ }
+
+
+ private void populateSize( List products ){
+ List sizes = Collections.singletonList("[Size]");
+ if( ! products.isEmpty() ){
+ sizes = products.stream().map( Product::getSmSize ).distinct().collect(Collectors.toList() );
+ }
+ ArrayAdapter adapter = new ArrayAdapter<>( 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() );
+ }
+ 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()) ;
+ }
+ ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, titles.toArray( new String[0] ));
+ title.setAdapter( adapter );
+ //
+ String titleOption = (String) title.getSelectedItem();
+ store.getReport().getItems().get(0).setTitle( titleOption );
+ }
+
+
+ private void populateMmodelNumber( List products ){
+ List modelNumbers = Collections.singletonList("[Model Number]");
+ if( ! products.isEmpty() ){
+ modelNumbers = products.stream().map( Product::getModelNumber ).distinct().collect(Collectors.toList()) ;
+ }
+ ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, modelNumbers.toArray(new String[0] ));
+ modelNumber.setAdapter( adapter );
+
+ String modelOption = (String) modelNumber.getSelectedItem();
+ store.getReport().getItems().get(0).setMarketplace( modelOption );
+ }
+
+ private void populateMarketplaces( List products ){
+ List marketplaces = Collections.singletonList("[ Marketplace ]");
+ if( ! products.isEmpty() ){
+ marketplaces = products.stream().map( Product::getMarketplace ).distinct().collect(Collectors.toList() );
+ }
+ ArrayAdapter adapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_dropdown_item, marketplaces.toArray(new String[0] ));
+ markerplace.setAdapter( adapter );
+ //
+ String marketplaceOption = (String) markerplace.getSelectedItem();
+ store.getReport().getItems().get(0).setMarketplace( marketplaceOption );
+ }
+
+
+ /*
+ * initialize views
+ * */
+ private void initializeViews( View view ){
+ leftFab = view.findViewById( R.id.button_left_frag_1 );
+ rightFab = view.findViewById( R.id.button_right_frag_1 );
+ markerplace = view.findViewById( R.id.marketplace );
+ sku = view.findViewById( R.id.sku );
+ modelNumber = view.findViewById( R.id.model_number );
+ title = view.findViewById( R.id.title );
+ color = view.findViewById( R.id.color );
+ size = view.findViewById( R.id.size );
+ boxCarton = view.findViewById( R.id. box_carton );
+ itemPerBox = view.findViewById( R.id.item_per_box );
+ pieces = view.findViewById( R.id.pieces );
+ packagingDetails = view.findViewById( R.id.packaging );
+ boxCartonSelected = view.findViewById( R.id.box_carton_selected );
+ itemPerBoxSelected = view.findViewById( R.id.item_per_box_selected );
+ piecesSelected = view.findViewById( R.id.pieces_selected );
+ fri = view.findViewById( R.id.fri );
+ refri = view.findViewById( R.id.refri );
+ searchSku = view.findViewById( R.id.search_sku_btn );
+ profileName= view.findViewById( R.id.first_step_name );
+ profileImage = view.findViewById( R.id.first_step_profile_image );
+ scanBtn = view.findViewById( R.id.scan_sku_btn );
+ showHistoryBtn = view.findViewById( R.id.button_show_history );
+ }
+ public void onBarcodeScanResult( String result ){
+ if( result != null && ! result.isEmpty() ){
+ apiService.fetchByFnsku( result ).enqueue(
+ new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if( response.isSuccessful() && response.body() != null ){
+ store.getReport().getItems().get(0).setSku( response.body().getSku() );
+ sku.setText( response.body().getSku() );
+ }
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ Toast.makeText( getContext(), t.getMessage().toString(), Toast.LENGTH_LONG ).show();
+ }
+ }
+ );
+ }
+ }
+
+ private void openItemHistoryDialog() {
+ LayoutInflater inflater = LayoutInflater.from( getContext() );
+ View dialogView = inflater.inflate( R.layout.item_history, null);
+ // recycler view
+ RecyclerView itemHistoryRecyclerView = dialogView.findViewById( R.id.item_history_recyclerview );
+ LinearLayoutManager layoutManager = new LinearLayoutManager( getContext() );
+ itemHistoryRecyclerView.setLayoutManager( layoutManager );
+ AlertDialog.Builder builder = new AlertDialog.Builder( Objects.requireNonNull(getContext()) );
+
+ // set adapter
+ ItemHistoryAdapter itemHistoryAdapter = new ItemHistoryAdapter( new ArrayList<>());
+ itemHistoryRecyclerView.setAdapter( itemHistoryAdapter );
+
+ builder.setView(dialogView)
+ .setTitle("Item History")
+ .setPositiveButton( "OK",(dialog, which) -> {
+ dialog.dismiss();
+ } )
+ .setNegativeButton("Cancel", (dialog, which) -> {
+ // Handle Cancel button click
+ dialog.dismiss();
+ });
+ if( store.getReport().getItems().get(0).getSku() != null ){
+ apiService.fetchItemsLogs( store.getReport().getItems().get(0).getSku() ).enqueue(
+ new Callback>() {
+ @SuppressLint("NotifyDataSetChanged")
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if( response.isSuccessful() && response.body() != null ){
+ // set adapter
+ System.out.println( response.body() );
+ ItemHistoryAdapter itemHistoryAdapter = new ItemHistoryAdapter( response.body() );
+ itemHistoryRecyclerView.setAdapter( itemHistoryAdapter );
+ itemHistoryAdapter.notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+ }
+ // Show the dialog
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ForthStepFragment.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ForthStepFragment.java
new file mode 100644
index 0000000..4cab955
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ForthStepFragment.java
@@ -0,0 +1,43 @@
+package com.utopiaindustries.qualitychecker.ui.fragments;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+
+import com.utopiaindustries.qualitychecker.R;
+
+public class ForthStepFragment extends Fragment implements View.OnClickListener {
+
+
+ private NavController navController;
+ private Button leftFab,rightFab;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_forth_step , container, false );
+ leftFab = view.findViewById( R.id.button_left_frag_4 );
+ rightFab = view.findViewById( R.id.button_right_frag_4 );
+
+ // set on click listener
+ leftFab.setOnClickListener( this );
+ rightFab.setOnClickListener( this );
+ return view;
+ }
+
+ @Override
+ public void onClick(View v) {
+ navController = Navigation.findNavController( requireView() );
+ if( v.getId() == R.id.button_left_frag_4 ){
+ navController.navigate( R.id.action_forthStepFragment_to_thirdStepFragment );
+ }
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/SecondStepFragment.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/SecondStepFragment.java
new file mode 100644
index 0000000..7aabb77
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/SecondStepFragment.java
@@ -0,0 +1,166 @@
+package com.utopiaindustries.qualitychecker.ui.fragments;
+
+import static android.app.Activity.RESULT_OK;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.apiservice.ApiService;
+import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory;
+import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint;
+import com.utopiaindustries.qualitychecker.models.InspectionDefect;
+import com.utopiaindustries.qualitychecker.service.InspectionReportService;
+import com.utopiaindustries.qualitychecker.store.Store;
+import com.utopiaindustries.qualitychecker.ui.adapter.CheckPointAdapter;
+
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class SecondStepFragment extends Fragment
+ implements View.OnClickListener {
+
+ private NavController navController;
+ private Button leftFab,rightFab;
+ private RecyclerView recyclerView;
+ private CheckPointAdapter adapter;
+ private ApiService apiService;
+ private TextView profileName;
+ private ImageView profileImage;
+ private List checkPoints;
+ private List defects;
+ private InspectionReportService inspectionReportService;
+ private Store store;
+ private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 100;
+ private static final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 101;
+
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_second_step , container, false );
+
+ apiService = ApiServiceFactory.getApiService();
+ store = Store.getInstance();
+ inspectionReportService = InspectionReportService.getInstance();
+ checkPoints = new ArrayList<>();
+ defects = new ArrayList<>();
+ leftFab = view.findViewById( R.id.button_left_frag_2 );
+ rightFab = view.findViewById( R.id.button_right_frag_2 );
+ recyclerView = view.findViewById( R.id.check_point_recycler_view );
+ profileName = view.findViewById( R.id.second_profile_name );
+ profileImage = view.findViewById( R.id.second_step_profile_image );
+ recyclerView.setLayoutManager( new LinearLayoutManager( getContext() ) );
+
+ // PERMISSIONS
+ {
+ // Check if permission is not granted
+ if ( ContextCompat.checkSelfPermission( getContext(), Manifest.permission.READ_EXTERNAL_STORAGE )
+ != PackageManager.PERMISSION_GRANTED) {
+
+ // Permission is not granted, request it
+ ActivityCompat.requestPermissions( getActivity(),
+ new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
+ MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
+ }
+
+ if (ContextCompat.checkSelfPermission( getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ != PackageManager.PERMISSION_GRANTED) {
+
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
+ }
+ }
+
+ profileName.setText( store.getEmployeePhoto().getName() );
+ Glide.with( getContext() )
+ .load( store.getProfileImage( ) )
+ .into( profileImage );
+
+ adapter = new CheckPointAdapter( store.getReport().getItems().get( 0 ).getCheckPoints(),
+ store.getCheckPoints(),
+ store.getDefects(),
+ inspectionReportService.getDefectTypes(),
+ getContext());
+ recyclerView.setAdapter( adapter );
+ // set on click listener
+ leftFab.setOnClickListener( this );
+ rightFab.setOnClickListener( this );
+ return view;
+ }
+
+ @Override
+ public void onClick(View v) {
+ navController = Navigation.findNavController( requireView() );
+ if( v.getId() == R.id.button_left_frag_2 ){
+ navController.navigate( R.id.action_secondStepFragment_to_firstStepFragment );
+ }
+ if( v.getId() == R.id.button_right_frag_2 ){
+ navController.navigate( R.id.action_secondStepFragment_to_thirdStepFragment );
+ }
+ }
+
+ public void onImagePickerResult(int requestCode, int resultCode, Intent data) {
+ if ( resultCode == RESULT_OK && data != null ) {
+ try {
+ Uri selectedImageUri = data.getData();
+ assert selectedImageUri != null;
+ String imagePath = selectedImageUri.getPath();
+ store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setImagePath( imagePath );
+ store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setFile( getBytesFromUri( getContext(), selectedImageUri ) );
+ adapter.notifyItemChanged( requestCode );
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private byte[] getBytesFromUri(Context context, Uri uri) {
+ if( uri != null ) {
+ try {
+ InputStream inputStream = context.getContentResolver().openInputStream(uri);
+ if (inputStream != null) {
+ ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int len;
+ while ((len = inputStream.read(buffer)) != -1) {
+ byteBuffer.write(buffer, 0, len);
+ }
+ inputStream.close();
+ return byteBuffer.toByteArray();
+ }
+ } catch (IOException e) {
+ System.out.println(e.getMessage());
+ return null;
+ }
+ }
+ return null;
+ }
+}
diff --git a/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ThirdStepFragment.java b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ThirdStepFragment.java
new file mode 100644
index 0000000..4129a1d
--- /dev/null
+++ b/app/src/main/java/com/utopiaindustries/qualitychecker/ui/fragments/ThirdStepFragment.java
@@ -0,0 +1,307 @@
+package com.utopiaindustries.qualitychecker.ui.fragments;
+
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.utopiaindustries.qualitychecker.R;
+import com.utopiaindustries.qualitychecker.apiservice.ApiService;
+import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory;
+import com.utopiaindustries.qualitychecker.models.InspectionItemDimension;
+import com.utopiaindustries.qualitychecker.models.SaveReportCallback;
+import com.utopiaindustries.qualitychecker.models.VoiceOfCustomer;
+import com.utopiaindustries.qualitychecker.service.InspectionReportService;
+import com.utopiaindustries.qualitychecker.store.Store;
+import com.utopiaindustries.qualitychecker.ui.adapter.DimensionAdapter;
+import com.utopiaindustries.qualitychecker.ui.adapter.ItemDimensionAdapter;
+import com.utopiaindustries.qualitychecker.ui.adapter.VocAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class ThirdStepFragment extends Fragment implements View.OnClickListener {
+ private NavController navController;
+ private Button backBtn,nextBtn,openDimensionDialog;
+ private TextView profileName;
+ private ImageView profileImage;
+ private InspectionReportService inspectionReportService;
+ private RecyclerView vocRecyclerView,itemDimensionsRecyclerView;
+ private Store store;
+ private Spinner resultSpinner;
+ private ApiService apiService;
+ private EditText generalRemarks;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_third_step , container, false );
+
+ inspectionReportService = InspectionReportService.getInstance();
+ store = Store.getInstance();
+ apiService = ApiServiceFactory.getApiService();
+
+ initializeViews( view );
+ populateViews();
+ setOnClickListeners();
+ vocRecyclerView.setLayoutManager( new LinearLayoutManager( getContext() ) );
+ itemDimensionsRecyclerView.setLayoutManager( new LinearLayoutManager( getContext() ) );
+
+ String asin = store.getReport().getItems().get(0).getAsin();
+ apiService.fetchVocs( asin ).enqueue(
+ new Callback>() {
+ @Override
+ public void onResponse(Call> call,
+ Response> response) {
+ if( response.isSuccessful() && response.body() != null ){
+ VocAdapter adapter = new VocAdapter( response.body(), getContext() );
+ vocRecyclerView.setAdapter( adapter );
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println( t.getMessage() );
+ }
+ }
+ );
+
+ ItemDimensionAdapter adapter = new ItemDimensionAdapter( store.getReport().getItems().get(0).getDimensions() );
+ itemDimensionsRecyclerView.setAdapter( adapter );
+
+ generalRemarks.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ try {
+ store.getReport().setGeneralRemarks( s.toString() );
+ } catch ( Exception e ){
+ store.getReport().setGeneralRemarks( "");
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
+ });
+ return view;
+ }
+
+ @Override
+ public void onClick(View v) {
+ navController = Navigation.findNavController( requireView() );
+ if( v.getId() == R.id.button_left_frag_3 ){
+ navController.navigate( R.id.action_thirdStepFragment_to_secondStepFragment );
+ }
+ if( v.getId() == R.id.button_right_frag_3 ){
+ saveReportDialog();
+ }
+ if( v.getId() == R.id.button_open_dimension ){
+ openDimensionDialog();
+ }
+ }
+
+ private void saveReportDialog(){
+ AlertDialog.Builder builder = new AlertDialog.Builder( getContext() );
+ builder.setTitle("So you want to save report?")
+ .setPositiveButton( "Save",(dialog, which) -> {
+ inspectionReportService.saveReport(store.getReport(), new SaveReportCallback() {
+ @Override
+ public void onSuccess() {
+ Toast.makeText( getContext(), "Report saved Successfully", Toast.LENGTH_LONG ).show();
+ Objects.requireNonNull( getActivity() ).finish();
+ }
+ @Override
+ public void onFailure(Throwable throwable) {
+ Toast.makeText( getContext(), throwable.getMessage(), Toast.LENGTH_LONG ).show();
+ }
+ });
+ })
+ .setNegativeButton("Cancel", (dialog, which) -> {
+ // Handle Cancel button click
+ dialog.dismiss();
+ });
+ // Show the dialog
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ }
+
+ private void openDimensionDialog() {
+ LayoutInflater inflater = LayoutInflater.from( getContext() );
+ View dialogView = inflater.inflate( R.layout.dimension_dialog, null);
+ // recycler view
+ RecyclerView dimensionRecyclerView = dialogView.findViewById( R.id.dimension_recycler_view );
+ LinearLayoutManager layoutManager = new LinearLayoutManager( getContext() );
+ dimensionRecyclerView.setLayoutManager( layoutManager );
+ // set adapter
+ DimensionAdapter dimensionAdapter = new DimensionAdapter( store.getDimensions(),
+ store.getDimensionList(),
+ store.getItemUnits() );
+ dimensionRecyclerView.setAdapter( dimensionAdapter );
+ AlertDialog.Builder builder = new AlertDialog.Builder( Objects.requireNonNull( getContext() ));
+ builder.setView(dialogView)
+ .setTitle("Select Dimensions")
+ .setPositiveButton( "Save",(dialog, which) -> {
+ calculateDimensions();
+ dialog.dismiss();
+ } )
+ .setNegativeButton("Cancel", (dialog, which) -> {
+ // Handle Cancel button click
+ dialog.dismiss();
+ });
+
+ Button addItemBtn = dialogView.findViewById( R.id.add_dimension_item );
+ addItemBtn.setOnClickListener(v -> {
+ int position = store.getDimensions().size();
+ store.getDimensions().add( new InspectionItemDimension() );
+ dimensionAdapter.notifyItemInserted( position );
+ dimensionRecyclerView.smoothScrollToPosition( position );
+
+ });
+
+ // Show the dialog
+ AlertDialog dialog = builder.create();
+
+ WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+ layoutParams.copyFrom( dialog.getWindow().getAttributes() );
+ layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
+ dialog.getWindow().setAttributes(layoutParams);
+
+ dialog.show();
+ // After show, clear the flags and set the soft input mode
+ Objects.requireNonNull(dialog.getWindow()).clearFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM );
+ dialog.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE );
+
+ }
+
+ private void populateViews(){
+
+ profileName.setText( store.getEmployeePhoto().getName() );
+ Glide.with( Objects.requireNonNull(getContext() ))
+ .load( store.getProfileImage( ) )
+ .into( profileImage );
+
+ generalRemarks.setText( store.getReport().getGeneralRemarks() );
+
+ ArrayAdapter adapter = new ArrayAdapter<>( getContext(),
+ android.R.layout.simple_spinner_item,
+ inspectionReportService.getReportResult() );
+ resultSpinner.setAdapter( adapter );
+
+ String defaultSelection = store.getReport().getReportResult();
+ int defaultIndexResultIndex = inspectionReportService.getReportResult().indexOf( defaultSelection );
+ resultSpinner.setSelection( defaultIndexResultIndex );
+
+ resultSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ String result = parent.getItemAtPosition( position ).toString();
+ store.getReport().setReportResult( result );
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+
+ }
+ });
+ }
+
+ private void calculateDimensions(){
+ List dimensions = store.getDimensions();
+ List newDimensions = new ArrayList<>();
+ try {
+ // calculations for averaging
+ 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() );
+ itemDimensionsRecyclerView.setAdapter( adapter );
+ } catch ( NullPointerException ex ){
+ Toast.makeText( getContext() , "Please fill the required Fields", Toast.LENGTH_LONG ).show();
+ }
+ }
+
+ @NonNull
+ private static InspectionItemDimension getInspectionItemDimension( Map.Entry> entry ) {
+ float required = 0f;
+ float actual = 0f;
+ float difference = 0f;
+ String unit = null;
+ float size = entry.getValue().size();
+
+ for( InspectionItemDimension dimen : entry.getValue() ){
+ required += dimen.getRequired();
+ actual += dimen.getActual();
+ difference += dimen.getDifference();
+ if( unit == null ){
+ unit = dimen.getUnit();
+ }
+ }
+ // average
+ required /= size;
+ actual /= size;
+ difference /= size;
+
+ return new InspectionItemDimension(
+ entry.getKey(),
+ actual,
+ required,
+ difference,
+ unit
+ );
+ }
+
+ private void initializeViews( View view ){
+ backBtn = view.findViewById( R.id.button_left_frag_3 );
+ nextBtn = view.findViewById( R.id.button_right_frag_3 );
+ openDimensionDialog = view.findViewById( R.id.button_open_dimension );
+ profileImage = view.findViewById( R.id.third_step_profile_image );
+ profileName = view.findViewById( R.id.third_profile_name );
+ vocRecyclerView = view.findViewById( R.id.voc_recyclerview );
+ resultSpinner = view.findViewById( R.id.result_spinner );
+ generalRemarks = view.findViewById( R.id.general_remarks );
+ itemDimensionsRecyclerView = view.findViewById( R.id.item_dimensions_recyclerview );
+ }
+ private void setOnClickListeners(){
+ nextBtn.setOnClickListener( this );
+ backBtn.setOnClickListener( this );
+ openDimensionDialog.setOnClickListener( this);
+ }
+}
diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml
index f11feca..4b3ab79 100644
--- a/app/src/main/res/layout/activity_home.xml
+++ b/app/src/main/res/layout/activity_home.xml
@@ -58,19 +58,6 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.022" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 927a869..58db389 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,13 +1,4 @@
-
-
-
-
-
-
-
-
-
-
android:layout_gravity="bottom"
android:background="@android:color/white">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/test/java/com/utopiaindustries/qualitychecker/ExampleUnitTest.java b/app/src/test/java/com/utopiaindustries/qualitychecker/ExampleUnitTest.java
new file mode 100644
index 0000000..c0ed763
--- /dev/null
+++ b/app/src/test/java/com/utopiaindustries/qualitychecker/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.utopiaindustries.qualitychecker;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file