This commit is contained in:
jithu
2023-07-17 17:40:45 +05:30
parent 2e0b0be7f4
commit b461fa0710
13 changed files with 394 additions and 21 deletions

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")
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")
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 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 reportPath: String = "",
var result: TestRightResultType? = null,
var resultRatio: Double? = null
var resultRatio: Double? = null,
var uploadFlag: Boolean? = false
) {
enum class Gender {
MALE,

View File

@@ -1,21 +1,63 @@
package com.example.hpostesting.data.repository
import android.net.Uri
import com.example.hpostesting.data.api.MolbioApi
import com.example.hpostesting.data.model.PendingUploads
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.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.ktx.storage
import com.google.gson.JsonObject
import kotlinx.coroutines.tasks.await
import okhttp3.MultipartBody
import okhttp3.RequestBody
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 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> {
return try {
val userdata = db.collection("patientData").whereEqualTo("_id", data._id).get().await()

View File

@@ -0,0 +1,178 @@
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.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.NetworkInfo
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.example.hpos.api.db.DatabaseHandler
import com.example.hpos.api.db.FileModel
import com.example.hpos.data.DataHolder
import com.google.gson.JsonObject
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.File
class MyJobScheduler : JobService(){
lateinit var sharedPreference: SharedPreferences
var dummyService = ApiClient.getClient().create(apiService::class.java)
var Flag=0
override fun onStartJob(p0: JobParameters?): Boolean {
Log.d("jober","job started")
try{
if(isOnline(this))
{
val databaseHandler: DatabaseHandler = DatabaseHandler(this)
val normList:List<FileModel> = databaseHandler.getPendingNormFiles()
Log.d("jober_norm",normList.size.toString())
val testList:List<FileModel> = databaseHandler.getPendingTestFiles()
Log.d("jober_test",testList.size.toString())
val logList:List<FileModel> = databaseHandler.getPendingLogFiles()
Log.d("jober_test",logList.size.toString())
for(normDetails in normList)
{
Log.d("jober_norm",normDetails.normFilename)
var file = File(normDetails.normFilename)
if(file.exists())
{
uploadFile(applicationContext,normDetails.normFilename,normDetails.PatientId,0)
}
}
for(testDetails in testList)
{
Log.d("jober_test",testDetails.testFilename)
var file = File(testDetails.testFilename)
if(file.exists())
{
uploadFile(this,testDetails.testFilename,testDetails.PatientId,1)
}
}
for(logDetails in logList)
{
Log.d("jober_log",logDetails.logFilename)
var file = File(logDetails.logFilename)
if(file.exists())
{
uploadFile(this,logDetails.logFilename,logDetails.PatientId,2)
}
}
}
else
{
Log.d("jober","no net")
}
}
catch (e:Exception)
{
e.printStackTrace()
}
return false
}
fun uploadFile(appContext: Context, filePath: String,pid:String, type:Int) {
val logInfo="log_info"
val devicename= DataHolder.deviceSerialNumber
sharedPreference = appContext.getSharedPreferences(logInfo,Context.MODE_PRIVATE)
var path=filePath
var file = File(path)
if(file.exists())
{
Log.d("jober","getting in fileexist")
val token=sharedPreference.getString("token","")
val reqBody = RequestBody.create(MediaType.parse("text/csv"), file)
val reqString= RequestBody.create(MediaType.parse("text/plain"),devicename)
val formData = MultipartBody.Part.createFormData("raw_data_file", file.name, reqBody)
if (token != null) {
dummyService.uploadPdf(token,formData,reqString).enqueue(object :
Callback<JsonObject> {
override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
if (response.isSuccessful) {
Log.d("jober","upload success_"+response.body().toString())
Flag=1
} else {
Log.d("jober","upload not success"+response.raw().toString()
)
Flag=0
}
updateFile(appContext,pid,type,Flag)
}
override fun onFailure(call: Call<JsonObject>, t: Throwable) {
Log.d("jober","upload error"+t.toString())
Flag=0
}
})
}
}
else
{
Log.d("filecheck","given file doesn't exist")
}
}
fun updateFile(appContext: Context,pid:String,type:Int,flag:Int)
{
val databaseHandler: DatabaseHandler = DatabaseHandler(appContext)
var fileData=databaseHandler.getFileFromId(pid.toString())
if(fileData!=null)
{
if(type==0) {
fileData.normFlag = flag
}
else if(type==1)
{
fileData.testFlag = flag
}
else if(type==2)
{
fileData.logFlag=flag
}
var vn=databaseHandler.updateFile(fileData)
Log.d("jober",vn.toString()+"updated as :"+flag+" \n$pid\n$type")
}
else
{
Log.d("jober","filedata is null")
}
}
override fun onStopJob(p0: JobParameters?): Boolean {
Log.d("jober_stop","Job stopped")
return false
}
fun isOnline(context: Context): Boolean {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val n = cm.activeNetwork
if (n != null) {
val nc = cm.getNetworkCapabilities(n)
//It will check for both wifi and cellular network
return nc!!.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
}
return false
} else {
val netInfo = cm.activeNetworkInfo
return netInfo != null && netInfo.isConnectedOrConnecting
}
}
}

View File

@@ -3,6 +3,8 @@ package com.example.hpostesting.domain.di
import android.app.Application
import android.content.Context
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.UserDao
import com.example.hpostesting.data.datasource.LocalFileDataSource
@@ -15,6 +17,10 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create
import javax.inject.Singleton
@Module
@@ -57,7 +63,16 @@ object AppModule {
@Provides
@Singleton
fun provideDatabaseRepository(): DatabaseRepository {
return DatabaseRepository()
}
fun provideRetrofit(client: OkHttpClient): Retrofit =
Retrofit
.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
@Provides
@Singleton
fun provideMolbioApi(retrofit: Retrofit): MolbioApi =
retrofit.create(MolbioApi::class.java)
}

View File

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

View File

@@ -14,6 +14,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.adapter.UserListAdapter
@@ -21,6 +22,7 @@ import com.example.hpostesting.presentation.testRight.TestRightViewModel
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.google.gson.JsonObject
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
@@ -34,6 +36,7 @@ class HomeFragment : Fragment() {
private val viewModel: TestRightViewModel by activityViewModels()
private lateinit var rvAdapter: UserListAdapter
private lateinit var sharedPreference: SharedPreferences
private var loginCount = 1
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
@@ -53,9 +56,10 @@ class HomeFragment : Fragment() {
if (isConnected) {
binding.internetAvailableCL.visibility = View.VISIBLE
binding.internetNotAvailableCL.visibility = View.GONE
login()
loadUserData()
setSearch()
checkForLocalDBData()
// checkForLocalDBData()
} else {
binding.internetAvailableCL.visibility = View.GONE
binding.internetNotAvailableCL.visibility = View.VISIBLE
@@ -66,7 +70,36 @@ class HomeFragment : Fragment() {
logoutUser(requireContext())
}
binding.uploadData.setOnClickListener {
showUploadDialog(requireContext())
showUploadDialog()
}
}
private fun login()
{
val jsonObject= JsonObject();
jsonObject.addProperty("Username","hposdevice");
jsonObject.addProperty("Password","sickle");
viewModel.login(jsonObject)
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++
}
}
is Result.Loading -> {
}
else -> {}
}
}
}
@@ -188,8 +221,8 @@ class HomeFragment : Fragment() {
}
}
private fun showUploadDialog(context: Context) {
val builder = AlertDialog.Builder(context)
private fun showUploadDialog() {
val builder = AlertDialog.Builder(requireContext())
builder.setTitle(R.string.upload_db_registration_title)
builder.setMessage(R.string.upload_db_registration_message)
@@ -212,7 +245,6 @@ class HomeFragment : Fragment() {
} else {
userDataList.forEach { userData ->
viewModel.bulkUploadResultToDatabase(userData)
viewModel.deleteById(userData._id)
}
dialog.dismiss()
Toast.makeText(

View File

@@ -166,11 +166,16 @@ class TestRightResults : Fragment() {
}
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
val deviceStaticId = sharedPreference.getString(Constants.USER_ID, "")
val token=sharedPreference.getString(Constants.TOKEN,"")
if (isNetworkAvailable) {
viewModel.uploadResultToDatabase(requireContext(), true, deviceStaticId!!)
if (token != null) {
viewModel.uploadResultToDatabase(requireContext(), true, deviceStaticId!!,token)
}
binding.progressBar.visibility = View.VISIBLE
} else {
viewModel.uploadResultToDatabase(requireContext(), false, deviceStaticId!!)
if (token != null) {
viewModel.uploadResultToDatabase(requireContext(), false, deviceStaticId!!,token)
}
Toast.makeText(
requireContext(),
"Internet not available, Test Data added to Local DB",

View File

@@ -1,19 +1,21 @@
package com.example.hpostesting.presentation.testRight
import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.CalculationVariableForTest
import com.example.hpostesting.data.model.ErrorMessage
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.test.TestRightCalculationData
import com.example.hpostesting.data.model.test.TestRightDeviceConstants
@@ -26,9 +28,13 @@ import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl
import com.example.hpostesting.domain.TestRightResultCalculation
import com.example.hpostesting.util.MyUtils
import com.google.firebase.storage.FirebaseStorage
import com.google.gson.JsonObject
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File
import java.text.SimpleDateFormat
import java.util.Calendar
@@ -53,10 +59,12 @@ class TestRightViewModel @Inject constructor(
val errorTriggered = MutableLiveData<ErrorMessage>()
var numberOfSampleRun = 0
val loginResponse = MutableLiveData<Result<MolbioLogin>>()
val fireBaseUpload = MutableLiveData<String>()
lateinit var sharedPreference: SharedPreferences
val testDetails = DataHolder.selectedTest
var Flag=0
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
@@ -435,7 +443,7 @@ class TestRightViewModel @Inject constructor(
return prefixTxt + fileExtensionTxt
}
private fun addResultTestToDb() {
private fun addResultTestToDb(csvFilePath: String, logTxtFilePath: String, token: String) {
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
@@ -445,7 +453,7 @@ class TestRightViewModel @Inject constructor(
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(testDetails)) {
is Response.Success -> {
fireBaseUpload.postValue("Success")
uploadToMolbio(csvFilePath, logTxtFilePath, token)
}
else -> {}
@@ -453,7 +461,40 @@ class TestRightViewModel @Inject constructor(
}
}
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")
}
else -> {
}
}
}
}
fun uploadResultToDatabase(context: Context, isOnline: Boolean, deviceSerialNumber: String, token: String) = viewModelScope.launch {
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
testDetails?.csvPath = csvFilePath
@@ -478,8 +519,7 @@ class TestRightViewModel @Inject constructor(
val serialNumber = Constants.STATICID.firstOrNull { it == deviceSerialNumber }
testDetails?.csvPath = csvUri
testDetails?.reportPath = logUri
addResultTestToDb()
addResultTestToDb(csvFilePath, logTxtFilePath, token)
} catch (exception: Exception) {
// Handle the exception appropriately (e.g., log the error, display an error message)
}
@@ -526,6 +566,7 @@ class TestRightViewModel @Inject constructor(
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
fireBaseUpload.postValue("Success")
// repository.uploadPdf()
}
else -> {}
@@ -537,5 +578,12 @@ class TestRightViewModel @Inject constructor(
userDao.deleteById(id = userId)
}
fun login(jsonObject: JsonObject) = viewModelScope.launch {
loginResponse.postValue(Result.Loading())
repository.login(jsonObject).let {
loginResponse.postValue(it)
}
}
}