Compare commits

..

5 Commits

Author SHA1 Message Date
mohamedkaif356
e9f7513c85 Check negative absorbance 2023-07-20 18:14:12 +05:30
mohamedkaif356
229f79fe24 API call fixed 2023-07-19 16:49:33 +05:30
mohamedkaif356
2bd9f79795 Molbio Data upload error fix 2023-07-18 17:58:27 +05:30
mohamedkaif356
e97d533998 Molbio Data upload 2023-07-18 17:15:01 +05:30
jithu
b461fa0710 api 2023-07-17 17:40:45 +05:30
20 changed files with 367 additions and 147 deletions

View File

@@ -14,7 +14,7 @@ android {
namespace 'in.sminnovations.hpostesting' namespace 'in.sminnovations.hpostesting'
defaultConfig { defaultConfig {
applicationId "in.sminnovations.hpostesting" applicationId "in.sminnovations.hpostesting.prod"
minSdk 21 minSdk 21
targetSdk 33 targetSdk 33
versionCode 2 versionCode 2

View File

@@ -1,46 +0,0 @@
package com.example.hpostesting.data
import android.util.Log
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.util.MyUtils
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class FileUploader {
private val TAG = "FileUploader"
val repository = DatabaseRepository()
suspend fun start() {
val listOfFiles = repository.getAllFromPendingQueue()
for (each in listOfFiles){
// Checking internet connectivity & mobile as same or not
if (MyUtils.isInternetConnected() && each.mobileId == DataHolder.mobileUniqueId) {
Log.d(TAG, "uploading file ${each.pendingId}")
GlobalScope.launch {
val response = repository.uploadFileToStorage(each.patientId, each.filePath)
when (response) {
is Response.Success -> {
Log.d(TAG, "File Uploaded ${each.pendingId}")
repository.removeFromPendingQueue(each.pendingId)
}
is Response.Error -> {
Log.d(TAG, response.exception.toString())
}
}
}.join()
} else {
return
}
}
return
}
}

View File

@@ -0,0 +1,8 @@
package com.example.hpostesting.data
sealed class Result<out T : Any> {
data class Success<out T : Any>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
class Loading<T : Any> : Result<T>()
}

View File

@@ -0,0 +1,31 @@
package com.example.hpostesting.data.api
import com.example.hpostesting.data.model.patient.MolbioLogin
import com.example.hpostesting.data.model.patient.UploadResponse
import com.google.gson.JsonObject
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
interface MolbioApi {
@Headers("Content-Type: application/json")
@POST("devices/login")
suspend fun login(@Body jsonObject: JsonObject): MolbioLogin
@Multipart
@PUT("results/upload")
fun uploadPdf(@Header("Authorization") auth:String, @Part file: MultipartBody.Part, @Part("DeviceId") name: RequestBody): Call<JsonObject>
@Multipart
@PUT("results/upload")
suspend fun uploadNewPdf(@Header("Authorization") auth:String,@Part("") count:RequestBody,@Part("") userId:RequestBody,@Part file_csv: MultipartBody.Part,@Part file_log:MultipartBody.Part,@Part("DeviceId") name:RequestBody): UploadResponse
}

View File

@@ -38,4 +38,8 @@ object Constants {
) )
const val password = "SMI@12345" const val password = "SMI@12345"
const val BASE_URL = "https://datacollection.micropcr.com/v1/"
const val TOKEN = "molbioToken"
} }

View File

@@ -0,0 +1,5 @@
package com.example.hpostesting.data.model.patient
data class MolbioLogin(
val token: String
)

View File

@@ -0,0 +1,5 @@
package com.example.hpostesting.data.model.patient
data class UploadResponse(
val success: Boolean
)

View File

@@ -23,7 +23,8 @@ data class UserData(
var csvPath: String = "", var csvPath: String = "",
var reportPath: String = "", var reportPath: String = "",
var result: TestRightResultType? = null, var result: TestRightResultType? = null,
var resultRatio: Double? = null var resultRatio: Double? = null,
var uploadFlag: Boolean? = false
) { ) {
enum class Gender { enum class Gender {
MALE, MALE,

View File

@@ -1,21 +1,63 @@
package com.example.hpostesting.data.repository package com.example.hpostesting.data.repository
import android.net.Uri import android.net.Uri
import com.example.hpostesting.data.api.MolbioApi
import com.example.hpostesting.data.model.PendingUploads import com.example.hpostesting.data.model.PendingUploads
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.MolbioLogin
import com.example.hpostesting.data.model.patient.UploadResponse
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.ktx.storage import com.google.firebase.storage.ktx.storage
import com.google.gson.JsonObject
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File import java.io.File
import java.net.ConnectException
import java.net.SocketTimeoutException
import javax.inject.Inject
import javax.inject.Singleton
class DatabaseRepository : Repository {
class NetworkException(message: String, cause: Throwable) : Exception(message, cause)
@Singleton
class DatabaseRepository @Inject constructor(
private val molbioApi: MolbioApi
) : Repository {
private val db: FirebaseFirestore = Firebase.firestore private val db: FirebaseFirestore = Firebase.firestore
private val storage = Firebase.storage private val storage = Firebase.storage
private suspend fun <T : Any> safeApiCall(apiCall: suspend () -> T): com.example.hpostesting.data.Result<T> {
return try {
val response = apiCall.invoke()
com.example.hpostesting.data.Result.Success(response)
} catch (e: SocketTimeoutException) {
com.example.hpostesting.data.Result.Error(NetworkException("Network timeout", e))
} catch (e: ConnectException) {
com.example.hpostesting.data.Result.Error(
NetworkException(
"Network connection failed",
e
)
)
} catch (e: Exception) {
com.example.hpostesting.data.Result.Error(e)
}
}
suspend fun login(jsonObject: JsonObject): com.example.hpostesting.data.Result<MolbioLogin> {
return safeApiCall { molbioApi.login(jsonObject) }
}
suspend fun uploadPdf(token:String,count:RequestBody,userId:RequestBody,file_csv:MultipartBody.Part,log_csv:MultipartBody.Part,deviceId:RequestBody): com.example.hpostesting.data.Result<UploadResponse> {
return safeApiCall { molbioApi.uploadNewPdf(token,count,userId,file_csv,log_csv,deviceId) }
}
suspend fun addTestToDatabase(data: UserData): Response<String> { suspend fun addTestToDatabase(data: UserData): Response<String> {
return try { return try {
val userdata = db.collection("patientData").whereEqualTo("_id", data._id).get().await() val userdata = db.collection("patientData").whereEqualTo("_id", data._id).get().await()

View File

@@ -0,0 +1,55 @@
package com.example.hpostesting.domain
import android.app.job.JobParameters
import android.app.job.JobService
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.lifecycle.ViewModelProvider
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class MyJobScheduler : JobService(){
@Inject
lateinit var sharedPreference: SharedPreferences
private lateinit var viewModel: TestRightViewModel
override fun onCreate() {
super.onCreate()
viewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(application)
.create(TestRightViewModel::class.java)
}
override fun onStartJob(p0: JobParameters?): Boolean {
Log.d("jober","job started")
sharedPreference = this.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
viewModel.networkStatusLiveData.observeForever {
if (it) {
fetchInternalDataAndUpload()
}
}
return false
}
private fun fetchInternalDataAndUpload() {
val token = sharedPreference.getString(Constants.TOKEN,"")
viewModel.allUserData.observeForever {userList ->
userList.forEach {user ->
if (user.uploadFlag == false) {
viewModel.bulkUploadResultToDatabase(user, token)
}
}
}
}
override fun onStopJob(p0: JobParameters?): Boolean {
Log.d("jober_stop","Job stopped")
return false
}
}

View File

@@ -2,11 +2,14 @@ package com.example.hpostesting.domain.di
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.ViewModelProvider
import androidx.room.Room import androidx.room.Room
import com.example.hpostesting.data.api.MolbioApi
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.MyDatabase import com.example.hpostesting.data.dao.MyDatabase
import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.datasource.LocalFileDataSource import com.example.hpostesting.data.datasource.LocalFileDataSource
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.data.repository.LocalFileRepository import com.example.hpostesting.data.repository.LocalFileRepository
import com.example.hpostesting.domain.SaveRawData import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest import com.example.hpostesting.domain.SaveRawDataTest
@@ -15,6 +18,8 @@ import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
@@ -57,7 +62,28 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideDatabaseRepository(): DatabaseRepository { fun provideRetrofit(): Retrofit =
return DatabaseRepository() Retrofit
.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
@Provides
@Singleton
fun provideMolbioApi(retrofit: Retrofit): MolbioApi =
retrofit.create(MolbioApi::class.java)
@Provides
@Singleton
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences {
return context.getSharedPreferences("my_preferences", Context.MODE_PRIVATE)
}
@Provides
@Singleton
fun provideViewModelFactory(application: Application): ViewModelProvider.Factory {
return ViewModelProvider.AndroidViewModelFactory.getInstance(application)
} }
} }

View File

@@ -10,16 +10,12 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import com.firebase.ui.firestore.FirestoreRecyclerAdapter import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions import com.firebase.ui.firestore.FirestoreRecyclerOptions
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding
class UserListAdapter( class UserListAdapter(options: FirestoreRecyclerOptions<UserData>, private val view: View) :
options: FirestoreRecyclerOptions<UserData>,
private val view: View
) :
FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) { FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) {
class OrderItemViewHolder(val binding: UserItemViewBinding) : class OrderItemViewHolder(val binding: UserItemViewBinding) :

View File

@@ -19,7 +19,6 @@ class DashboardActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDashboardBinding private lateinit var binding: ActivityDashboardBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -5,6 +5,7 @@ import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -13,6 +14,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.adapter.UserListAdapter import com.example.hpostesting.presentation.adapter.UserListAdapter
@@ -20,6 +22,7 @@ import com.example.hpostesting.presentation.testRight.TestRightViewModel
import com.firebase.ui.firestore.FirestoreRecyclerOptions import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.firestore.ktx.firestore import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import com.google.gson.JsonObject
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
@@ -33,11 +36,13 @@ class HomeFragment : Fragment() {
private val viewModel: TestRightViewModel by activityViewModels() private val viewModel: TestRightViewModel by activityViewModels()
private lateinit var rvAdapter: UserListAdapter private lateinit var rvAdapter: UserListAdapter
private lateinit var sharedPreference: SharedPreferences private lateinit var sharedPreference: SharedPreferences
private var loginCount = 1
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View { ): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false) _binding = FragmentHomeBinding.inflate(inflater, container, false)
sharedPreference = requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
DataHolder.selectedTest = null DataHolder.selectedTest = null
return binding.root return binding.root
@@ -52,9 +57,10 @@ class HomeFragment : Fragment() {
if (isConnected) { if (isConnected) {
binding.internetAvailableCL.visibility = View.VISIBLE binding.internetAvailableCL.visibility = View.VISIBLE
binding.internetNotAvailableCL.visibility = View.GONE binding.internetNotAvailableCL.visibility = View.GONE
login()
loadUserData() loadUserData()
setSearch() setSearch()
checkForLocalDBData() // checkForLocalDBData()
} else { } else {
binding.internetAvailableCL.visibility = View.GONE binding.internetAvailableCL.visibility = View.GONE
binding.internetNotAvailableCL.visibility = View.VISIBLE binding.internetNotAvailableCL.visibility = View.VISIBLE
@@ -65,8 +71,56 @@ class HomeFragment : Fragment() {
logoutUser(requireContext()) logoutUser(requireContext())
} }
binding.uploadData.setOnClickListener { binding.uploadData.setOnClickListener {
showUploadDialog(requireContext()) showUploadDialog()
} }
//
// val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
//
// val jobInfo = JobInfo.Builder(1, ComponentName(this, MyJobScheduler::class.java))
// .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
// .setPersisted(true)
// .setPeriodic(30 * 60 * 1000)
// .build()
// jobScheduler.schedule(jobInfo)
}
override fun onStart() {
super.onStart()
val jsonObject = JsonObject()
jsonObject.addProperty("Username", "hposdevice")
jsonObject.addProperty("Password", "sickle")
viewModel.loginResponse.observe(viewLifecycleOwner) { response ->
when (response) {
is Result.Success -> {
val editor = sharedPreference.edit()
editor.putString(Constants.TOKEN, response.data.token)
editor.apply()
Log.d("login_api", "called")
// showUploadDialog()
}
is Result.Error -> {
if (loginCount < 3) {
viewModel.login(jsonObject)
loginCount++
}
Log.d("API Error", response.exception.message.toString())
}
is Result.Loading -> {
Toast.makeText(requireContext(), "Loading", Toast.LENGTH_SHORT).show()
}
else -> {}
}
}
}
private fun login() {
val jsonObject = JsonObject()
jsonObject.addProperty("Username", "hposdevice")
jsonObject.addProperty("Password", "sickle")
viewModel.login(jsonObject)
} }
private fun setUserId() { private fun setUserId() {
@@ -85,14 +139,7 @@ class HomeFragment : Fragment() {
} }
private fun loadUserData() { private fun loadUserData() {
val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false) val query = Firebase.firestore.collection("patientData")
query.get().addOnSuccessListener {
if (it.documents.isEmpty()) {
binding.pendingTest.visibility = View.VISIBLE
} else {
binding.pendingTest.visibility = View.GONE
}
}
val recyclerViewOptions = val recyclerViewOptions =
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java) FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
.build() .build()
@@ -107,6 +154,7 @@ class HomeFragment : Fragment() {
apply() apply()
} }
} }
private fun logoutUser(context: Context) { private fun logoutUser(context: Context) {
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(context)
builder.setTitle("Log Out") builder.setTitle("Log Out")
@@ -129,7 +177,6 @@ class HomeFragment : Fragment() {
} }
private fun getData(search: String?, field: String) { private fun getData(search: String?, field: String) {
val capitalizedSearch = search?.replaceFirstChar { val capitalizedSearch = search?.replaceFirstChar {
if (search.lowercase() if (search.lowercase()
@@ -194,8 +241,8 @@ class HomeFragment : Fragment() {
} }
} }
private fun showUploadDialog(context: Context) { private fun showUploadDialog() {
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(requireContext())
builder.setTitle(R.string.upload_db_registration_title) builder.setTitle(R.string.upload_db_registration_title)
builder.setMessage(R.string.upload_db_registration_message) builder.setMessage(R.string.upload_db_registration_message)
@@ -212,19 +259,17 @@ class HomeFragment : Fragment() {
} }
private fun uploadLocalDBData(dialog: DialogInterface) { private fun uploadLocalDBData(dialog: DialogInterface) {
val token = sharedPreference.getString(Constants.TOKEN, "")
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
if (userDataList.isEmpty()) { if (userDataList.isEmpty()) {
dialog.dismiss() dialog.dismiss()
} else { } else {
userDataList.forEach { userData -> userDataList.forEach { userData ->
viewModel.bulkUploadResultToDatabase(userData) viewModel.bulkUploadResultToDatabase(userData, token!!)
viewModel.deleteById(userData._id)
} }
dialog.dismiss() dialog.dismiss()
Toast.makeText( Toast.makeText(
requireContext(), requireContext(), R.string.upload_success_message, Toast.LENGTH_SHORT
R.string.upload_success_message,
Toast.LENGTH_SHORT
).show() ).show()
} }
} }

View File

@@ -8,6 +8,7 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
@@ -247,10 +248,13 @@ class TestRightExpSample : Fragment() {
// viewModel.mapWavelengthToAbsorbance() // viewModel.mapWavelengthToAbsorbance()
// viewModel.calculateResults() // viewModel.calculateResults()
viewModel.progressBar.postValue(false) if (viewModel.calculationData.absorbanceOne!! < 0 || viewModel.calculationData.absorbanceTwo!! < 0) {
// binding.progressBar.visibility = View.GONE Toast.makeText(requireContext(), " ", Toast.LENGTH_SHORT).show()
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightResults()) viewModel.progressBar.postValue(false)
.commit() } else {
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightResults())
.commit()
}
} }
private fun saveDataLocally() { private fun saveDataLocally() {

View File

@@ -12,7 +12,6 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.test.TestRightResultType import com.example.hpostesting.data.model.test.TestRightResultType
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
@@ -35,7 +34,7 @@ class TestRightResults : Fragment() {
private lateinit var binding: FragmentTestRightResultsBinding private lateinit var binding: FragmentTestRightResultsBinding
private val viewModel: TestRightViewModel by activityViewModels() private val viewModel: TestRightViewModel by activityViewModels()
private lateinit var sharedPreference: SharedPreferences private lateinit var sharedPreference: SharedPreferences
private var bloodGroup: String = ""
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View { ): View {
@@ -52,12 +51,20 @@ class TestRightResults : Fragment() {
updateResults() updateResults()
viewModel.fireBaseUpload.observe(viewLifecycleOwner) { viewModel.fireBaseUpload.observe(viewLifecycleOwner) {
if (it == "Success") { when (it) {
Toast.makeText( "Success" -> {
requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT Toast.makeText(
).show() requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT
).show()
binding.progressBar.visibility = View.GONE
}
"Loading" -> {
binding.progressBar.visibility = View.VISIBLE
}
else -> {
Toast.makeText(requireContext(), "Test upload failed, please try again $it", Toast.LENGTH_SHORT).show()
}
} }
binding.progressBar.visibility = View.GONE
} }
} }
@@ -65,49 +72,36 @@ class TestRightResults : Fragment() {
private fun setupListeners() { private fun setupListeners() {
binding.ivHome.setOnClickListener { binding.ivHome.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
val bloodGroupText = binding.etBloodGroup.text.toString() checkBloodGroup()
if (bloodGroupText.isNullOrBlank() || bloodGroupText == "Select Blood Group") {
withContext(Dispatchers.Main) {
binding.etBloodGroup.error = "Please enter your blood group"
}
withContext(Dispatchers.Main) {
Toast.makeText(context, "Please enter your blood group", Toast.LENGTH_SHORT).show()
}
} else {
withContext(Dispatchers.Main) {
binding.etBloodGroup.error = null
}
bloodGroup = bloodGroupText
checkBloodGroup()
}
} }
} }
binding.ivNext.setOnClickListener { binding.ivNext.setOnClickListener {
val i = Intent(requireContext().applicationContext, DashboardActivity::class.java) val i = Intent(requireContext().applicationContext, DashboardActivity::class.java)
startActivity(i) startActivity(i)
// moveToSamplePage()
} }
} }
private suspend fun checkBloodGroup() { private suspend fun checkBloodGroup() {
binding.apply { binding.apply {
bloodGroup = etBloodGroup.text.toString() val bloodGroup = etBloodGroup.text.toString()
if (bloodGroup.isEmpty()) {
etBloodGroup.error = "Please enter your blood group"
} else {
val db: FirebaseFirestore = Firebase.firestore val db: FirebaseFirestore = Firebase.firestore
val userdata = val userdata =
db.collection("patientData").whereEqualTo("_id", viewModel.testDetails?._id) db.collection("patientData").whereEqualTo("_id", viewModel.testDetails?._id)
.get().await() .get().await()
if (userdata.documents.isNotEmpty()) { if (userdata.documents.isNotEmpty()) {
db.collection("patientData").document(userdata.documents[0].id) userdata.documents.forEach {
.update("bloodGroup", bloodGroup) db.collection("patientData").document(it.id).update("bloodGroup", bloodGroup)
withContext(Dispatchers.Main) {
val i = Intent(
requireContext().applicationContext,
DashboardActivity::class.java
)
startActivity(i)
} }
} }
}
withContext(Dispatchers.Main) {
val i = Intent(requireContext().applicationContext, DashboardActivity::class.java)
startActivity(i)
}
} }
} }
@@ -180,11 +174,16 @@ class TestRightResults : Fragment() {
} }
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable -> viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
val deviceStaticId = sharedPreference.getString(Constants.USER_ID, "") val deviceStaticId = sharedPreference.getString(Constants.USER_ID, "")
val token = sharedPreference.getString(Constants.TOKEN,"")
if (isNetworkAvailable) { if (isNetworkAvailable) {
viewModel.uploadResultToDatabase(requireContext(), true, deviceStaticId!!) if (token != null) {
viewModel.uploadResultToDatabase(requireContext(), true, deviceStaticId!!,token)
}
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
} else { } else {
viewModel.uploadResultToDatabase(requireContext(), false, deviceStaticId!!) if (token != null) {
viewModel.uploadResultToDatabase(requireContext(), false, deviceStaticId!!,token)
}
Toast.makeText( Toast.makeText(
requireContext(), requireContext(),
"Internet not available, Test Data added to Local DB", "Internet not available, Test Data added to Local DB",

View File

@@ -2,18 +2,19 @@ package com.example.hpostesting.presentation.testRight
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.CalculationVariableForTest import com.example.hpostesting.data.model.CalculationVariableForTest
import com.example.hpostesting.data.model.ErrorMessage import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.MolbioLogin
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
import com.example.hpostesting.data.model.test.TestRightDeviceConstants import com.example.hpostesting.data.model.test.TestRightDeviceConstants
@@ -26,9 +27,13 @@ import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl
import com.example.hpostesting.domain.TestRightResultCalculation import com.example.hpostesting.domain.TestRightResultCalculation
import com.example.hpostesting.util.MyUtils import com.example.hpostesting.util.MyUtils
import com.google.firebase.storage.FirebaseStorage import com.google.firebase.storage.FirebaseStorage
import com.google.gson.JsonObject
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
@@ -53,17 +58,17 @@ class TestRightViewModel @Inject constructor(
val errorTriggered = MutableLiveData<ErrorMessage>() val errorTriggered = MutableLiveData<ErrorMessage>()
var numberOfSampleRun = 0 var numberOfSampleRun = 0
val loginResponse = MutableLiveData<Result<MolbioLogin>>()
val fireBaseUpload = MutableLiveData<String>() val fireBaseUpload = MutableLiveData<String>()
val testDetails = DataHolder.selectedTest val testDetails = DataHolder.selectedTest
private val _networkStatusLiveData = NetworkStatusLiveData(context) private val _networkStatusLiveData = NetworkStatusLiveData(context)
val networkStatusLiveData: LiveData<Boolean> val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData get() = _networkStatusLiveData
val allUserData = userDao.getAll() val allUserData = userDao.getAll()
private lateinit var calculationData: TestRightCalculationData lateinit var calculationData: TestRightCalculationData
/* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */ /* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */
val intensitySampleArray = ArrayList<Double>() val intensitySampleArray = ArrayList<Double>()
@@ -435,7 +440,7 @@ class TestRightViewModel @Inject constructor(
return prefixTxt + fileExtensionTxt return prefixTxt + fileExtensionTxt
} }
private fun addResultTestToDb() { private fun addResultTestToDb(csvFilePath: String, logTxtFilePath: String, token: String) {
testDetails?.testTime = SimpleDateFormat( testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
@@ -445,15 +450,51 @@ class TestRightViewModel @Inject constructor(
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(testDetails)) { when (repository.addTestToDatabase(testDetails)) {
is Response.Success -> { is Response.Success -> {
fireBaseUpload.postValue("Success") uploadToMolbio(csvFilePath, logTxtFilePath, token)
} }
else -> {} else -> {}
} }
} }
} }
fun uploadResultToDatabase(context: Context, isOnline: Boolean,deviceSerialNumber: String) = viewModelScope.launch { private fun uploadToMolbio(csvFilePath: String, logTxtFilePath: String, token: String) = viewModelScope.launch {
val csv_file = File(csvFilePath)
val log_file=File(logTxtFilePath)
val csv_reqBody = RequestBody.create(MediaType.parse("text/csv"), csv_file)
val log_reqBody = RequestBody.create(MediaType.parse("text/txt"), log_file)
val deviceId= testDetails?.deviceSerialNumber?.let {
RequestBody.create(MediaType.parse("text/plain"),
it
)
}
val userId= testDetails?._id?.let { RequestBody.create(MediaType.parse("text/plain"), it) }
val csv_formData = MultipartBody.Part.createFormData("csv_file", csv_file.name, csv_reqBody)
val log_formData = MultipartBody.Part.createFormData("csv_file", log_file.name, log_reqBody)
val count = "1".let {
RequestBody.create(MediaType.parse("text/plain"),
it
)
}
repository.uploadPdf(token, count, userId!!, csv_formData, log_formData, deviceId!!).let { upload ->
when(upload) {
is Result.Success -> {
fireBaseUpload.postValue("Success")
}
is Result.Error -> {
fireBaseUpload.postValue(upload.exception.message)
}
else -> {
}
}
}
}
fun uploadResultToDatabase(context: Context, isOnline: Boolean, deviceSerialNumber: String, token: String) = viewModelScope.launch {
fireBaseUpload.postValue("Loading")
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName() val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName() val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
testDetails?.csvPath = csvFilePath testDetails?.csvPath = csvFilePath
@@ -478,8 +519,7 @@ class TestRightViewModel @Inject constructor(
val serialNumber = Constants.STATICID.firstOrNull { it == deviceSerialNumber } val serialNumber = Constants.STATICID.firstOrNull { it == deviceSerialNumber }
testDetails?.csvPath = csvUri testDetails?.csvPath = csvUri
testDetails?.reportPath = logUri testDetails?.reportPath = logUri
addResultTestToDb(csvFilePath, logTxtFilePath, token)
addResultTestToDb()
} catch (exception: Exception) { } catch (exception: Exception) {
// Handle the exception appropriately (e.g., log the error, display an error message) // Handle the exception appropriately (e.g., log the error, display an error message)
} }
@@ -487,11 +527,14 @@ class TestRightViewModel @Inject constructor(
testDetails?.testTime = SimpleDateFormat( testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
userDao.insertAll(testDetails!!) userDao.insertAll(testDetails!!).let {
fireBaseUpload.postValue("Success")
}
} }
} }
fun bulkUploadResultToDatabase(userData: UserData) = viewModelScope.launch { fun bulkUploadResultToDatabase(userData: UserData, token: String?) = viewModelScope.launch {
fireBaseUpload.postValue("Loading")
val storageRef = FirebaseStorage.getInstance().reference val storageRef = FirebaseStorage.getInstance().reference
val storageTestDetailsRef = storageRef.child("${testDetails?._id}/") val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
try { try {
@@ -508,24 +551,31 @@ class TestRightViewModel @Inject constructor(
val csvUri = csvUploadTask.storage.downloadUrl.await().toString() val csvUri = csvUploadTask.storage.downloadUrl.await().toString()
val logUri = logUploadTask.storage.downloadUrl.await().toString() val logUri = logUploadTask.storage.downloadUrl.await().toString()
val csvFilePath = userData.csvPath
val logTxtFilePath = userData.reportPath
userData.csvPath = csvUri userData.csvPath = csvUri
userData.reportPath = logUri userData.reportPath = logUri
bulkAddResultTestToDb(userData, csvFilePath, logTxtFilePath, token)
bulkAddResultTestToDb(userData)
} catch (exception: Exception) { } catch (exception: Exception) {
// Handle the exception appropriately (e.g., log the error, display an error message) // Handle the exception appropriately (e.g., log the error, display an error message)
} }
} }
private fun bulkAddResultTestToDb(userData: UserData) { private fun bulkAddResultTestToDb(
userData: UserData,
csvFilePath: String,
logTxtFilePath: String,
token: String?
) {
viewModelScope.launch { viewModelScope.launch {
userData.reportUploadTime = SimpleDateFormat( userData.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) { when (repository.addTestToDatabase(userData)) {
is Response.Success -> { is Response.Success -> {
fireBaseUpload.postValue("Success") uploadToMolbio(csvFilePath, logTxtFilePath, token!!)
} }
else -> {} else -> {}
@@ -537,5 +587,12 @@ class TestRightViewModel @Inject constructor(
userDao.deleteById(id = userId) userDao.deleteById(id = userId)
} }
fun login(jsonObject: JsonObject) = viewModelScope.launch {
loginResponse.postValue(Result.Loading())
repository.login(jsonObject).let {
loginResponse.postValue(it)
}
}
} }

View File

@@ -24,6 +24,7 @@ class UsbService : Service() {
private val TAG = "UsbService" private val TAG = "UsbService"
inner class UsbServiceBinder : Binder() { inner class UsbServiceBinder : Binder() {
// Return this instance of UsbService so clients can call public methods
fun getService(): UsbService = this@UsbService fun getService(): UsbService = this@UsbService
} }
@@ -38,12 +39,14 @@ class UsbService : Service() {
mPort = driver.ports[0] // Most devices have just one port (port 0) mPort = driver.ports[0] // Most devices have just one port (port 0)
mPort.open(connection) mPort.open(connection)
mPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE) mPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
//
isUsbConnected = true isUsbConnected = true
Log.d(TAG, "My Usb Connected ${mPort.driver}") Log.d(TAG, "My Usb Connected ${mPort.driver}")
val usbIoManager = SerialInputOutputManager(mPort, val usbIoManager = SerialInputOutputManager(mPort,
object : SerialInputOutputManager.Listener{ object : SerialInputOutputManager.Listener{
override fun onNewData(data: ByteArray?) { override fun onNewData(data: ByteArray?) {
// Log.e(TAG, "onNewData() called inside eventDrivenWrite()")
listener?.onUsbRead(data) listener?.onUsbRead(data)
} }
override fun onRunError(e: Exception?) { override fun onRunError(e: Exception?) {

View File

@@ -5,19 +5,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView
android:id="@+id/pendingTest"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:visibility="gone"
android:text="@string/all_registered_user_are_tested_successfully"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/internetNotAvailableCL" android:id="@+id/internetNotAvailableCL"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -184,6 +184,5 @@
<string name="upload_success_message">Upload done successfully</string> <string name="upload_success_message">Upload done successfully</string>
<string name="test_completed">Test Completed</string> <string name="test_completed">Test Completed</string>
<string name="select_blood_group">Select Blood Group</string> <string name="select_blood_group">Select Blood Group</string>
<string name="all_registered_user_are_tested_successfully">All registered user are tested successfully</string>
</resources> </resources>