Compare commits
2 Commits
review_rel
...
dev-server
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12e022a00a | ||
|
|
88cdc01978 |
@@ -47,6 +47,7 @@ object Constants {
|
|||||||
|
|
||||||
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE = 34
|
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE = 34
|
||||||
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM = 9
|
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM = 9
|
||||||
|
const val MAXIMUM_TEST_ALLOWED_SINGLE_TEST = 0
|
||||||
|
|
||||||
const val RANGE_IN_RESULT_CALCULATIONS = 10
|
const val RANGE_IN_RESULT_CALCULATIONS = 10
|
||||||
|
|
||||||
@@ -1586,6 +1587,7 @@ object Constants {
|
|||||||
//Trueheme for 10mm
|
//Trueheme for 10mm
|
||||||
//Before changing below values review before
|
//Before changing below values review before
|
||||||
//classification borderline metric
|
//classification borderline metric
|
||||||
|
const val TEST_FOR_10MM = "SMI/SC-2-D10/"
|
||||||
const val positiveBoderLineMetricCheck10mmMin = 1.3
|
const val positiveBoderLineMetricCheck10mmMin = 1.3
|
||||||
const val positiveBoderLineMetricCheck10mmMax = 1.66
|
const val positiveBoderLineMetricCheck10mmMax = 1.66
|
||||||
const val negativeBoderLineMetricCheck10mmMin = 2.0
|
const val negativeBoderLineMetricCheck10mmMin = 2.0
|
||||||
@@ -1603,6 +1605,7 @@ object Constants {
|
|||||||
const val sickleCellDiseaseMax10mm = 0.7
|
const val sickleCellDiseaseMax10mm = 0.7
|
||||||
//Trueheme for 2mm
|
//Trueheme for 2mm
|
||||||
//classification borderline metric
|
//classification borderline metric
|
||||||
|
const val TEST_FOR_2MM = "SMI/SC/"
|
||||||
const val positiveBoderLineMetricCheck2mmMin = 0.8
|
const val positiveBoderLineMetricCheck2mmMin = 0.8
|
||||||
const val positiveBoderLineMetricCheck2mmMax = 1.1
|
const val positiveBoderLineMetricCheck2mmMax = 1.1
|
||||||
const val negativeBoderLineMetricCheck2mmMin = 1.5
|
const val negativeBoderLineMetricCheck2mmMin = 1.5
|
||||||
@@ -1619,6 +1622,25 @@ object Constants {
|
|||||||
const val sickleCellDiseaseMin2mm = 0.45
|
const val sickleCellDiseaseMin2mm = 0.45
|
||||||
const val sickleCellDiseaseMax2mm = 0.7
|
const val sickleCellDiseaseMax2mm = 0.7
|
||||||
|
|
||||||
|
//Trueheme for 10mm Single Test
|
||||||
|
//classification borderline metric
|
||||||
|
const val singleTest = "SMI/SC-ST/"
|
||||||
|
const val positiveBoderLineMetricCheck2mmStMin = 1.3
|
||||||
|
const val positiveBoderLineMetricCheck2mmStMax = 1.66
|
||||||
|
const val negativeBoderLineMetricCheck2mmStMin = 2.0
|
||||||
|
const val negativeBoderLineMetricCheck2mmStMax = 2.4
|
||||||
|
//classification device ratio
|
||||||
|
const val normalMinSt2mm = 0.07
|
||||||
|
const val normalMaxSt2mm = 0.23
|
||||||
|
const val negativeBorderlineMinSt2mm = 0.23
|
||||||
|
const val negativeBorderlineMaxSt2mm = 0.27
|
||||||
|
const val sickleCellTraitMinSt2mm = 0.27
|
||||||
|
const val sickleCellTraitMaxSt2mm = 0.31
|
||||||
|
const val positiveForSickleCellMinSt2mm = 0.31
|
||||||
|
const val positiveForSickleCellMaxSt2mm = 0.39
|
||||||
|
const val sickleCellDiseaseMinSt2mm = 0.39
|
||||||
|
const val sickleCellDiseaseMaxSt2mm = 0.7
|
||||||
|
|
||||||
const val min2mmLed1 = 0.34
|
const val min2mmLed1 = 0.34
|
||||||
const val max2mmLed1 = 1.48
|
const val max2mmLed1 = 1.48
|
||||||
const val min2mmLed2 = 0.04
|
const val min2mmLed2 = 0.04
|
||||||
|
|||||||
@@ -38,15 +38,16 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun exportDataToCSV(
|
override fun exportDataToCSV(
|
||||||
fileName: String, dataList: List<HemoCubeTestData>,
|
filePath: String, dataList: List<HemoCubeTestData>,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
try {
|
try {
|
||||||
val formattedFileName = fileName.replace(
|
// Create the file directly from the provided path
|
||||||
Regex("[^a-zA-Z0-9.-]"),
|
val file = File(filePath)
|
||||||
"_"
|
|
||||||
) // Replace special characters with underscores
|
// Ensure parent directory exists
|
||||||
val filePath = File(getExternalStorageDirectory(), formattedFileName)
|
file.parentFile?.mkdirs()
|
||||||
val writer = FileWriter(filePath)
|
|
||||||
|
val writer = FileWriter(file)
|
||||||
val csvWriter = CSVWriter(writer)
|
val csvWriter = CSVWriter(writer)
|
||||||
// Write CSV header
|
// Write CSV header
|
||||||
val header = arrayOf(
|
val header = arrayOf(
|
||||||
@@ -103,8 +104,8 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
|
|||||||
csvWriter.writeNext(header)
|
csvWriter.writeNext(header)
|
||||||
|
|
||||||
// Filter and write data rows where testStatus is true
|
// Filter and write data rows where testStatus is true
|
||||||
val filteredDataList = dataList.filter { it.testStatus == true }
|
// val filteredDataList = dataList.filter { it.testStatus == true }
|
||||||
for (data in filteredDataList) {
|
for (data in dataList) {
|
||||||
val row = arrayOf(
|
val row = arrayOf(
|
||||||
data._id,
|
data._id,
|
||||||
data.name,
|
data.name,
|
||||||
@@ -226,8 +227,8 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
|
|||||||
csvWriter.writeNext(header)
|
csvWriter.writeNext(header)
|
||||||
|
|
||||||
// Filter and write data rows where testStatus is true
|
// Filter and write data rows where testStatus is true
|
||||||
val filteredDataList = dataList.filter { it.testStatus == true }
|
//val filteredDataList = dataList.filter { it.testStatus == true }
|
||||||
for (data in filteredDataList) {
|
for (data in dataList) {
|
||||||
val row = arrayOf(
|
val row = arrayOf(
|
||||||
data._id,
|
data._id,
|
||||||
data.name,
|
data.name,
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ import android.widget.Toast
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.hpostesting.data.constant.DataHolder
|
import com.example.hpostesting.data.constant.DataHolder
|
||||||
import com.example.hpostesting.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
|
import com.example.hpostesting.data.constant.Constants.TEST_FOR_10MM
|
||||||
|
import com.example.hpostesting.data.constant.Constants.TEST_FOR_2MM
|
||||||
|
import com.example.hpostesting.data.constant.Constants.singleTest
|
||||||
import com.example.hpostesting.data.constant.LanguageManager
|
import com.example.hpostesting.data.constant.LanguageManager
|
||||||
import com.example.hpostesting.data.model.test.TestType
|
import com.example.hpostesting.data.model.test.TestType
|
||||||
import com.example.hpostesting.presentation.main_base.DashboardActivity
|
import com.example.hpostesting.presentation.main_base.DashboardActivity
|
||||||
@@ -52,7 +55,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
|
|||||||
private var fromWhere = "Home"
|
private var fromWhere = "Home"
|
||||||
private val TAG = "KitScanActivity"
|
private val TAG = "KitScanActivity"
|
||||||
private lateinit var binding: ActivityKitScanBinding
|
private lateinit var binding: ActivityKitScanBinding
|
||||||
|
private var maxTest = 9
|
||||||
private lateinit var sharedPreference: SharedPreferences
|
private lateinit var sharedPreference: SharedPreferences
|
||||||
|
|
||||||
var sdkHandler: SDKHandler? = null
|
var sdkHandler: SDKHandler? = null
|
||||||
@@ -71,20 +74,27 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processScannedData(contents: String) {//edited auto selection of cuvette size
|
private fun processScannedData(contents: String) {//edited auto selection of cuvette size
|
||||||
if(contents.contains("SMI/SC/")){
|
if(contents.contains(TEST_FOR_2MM)){
|
||||||
with(sharedPreference.edit()) {
|
with(sharedPreference.edit()) {
|
||||||
putString(Constants.CUVETTE_SIZE, "2mm")
|
putString(Constants.CUVETTE_SIZE, "2mm")
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show()
|
||||||
binding.nameEditText.setText(contents)
|
binding.nameEditText.setText(contents)
|
||||||
}else if(contents.contains("SMI/SC-2-D10/")){
|
}else if(contents.contains(TEST_FOR_10MM)){
|
||||||
with(sharedPreference.edit()) {
|
with(sharedPreference.edit()) {
|
||||||
putString(Constants.CUVETTE_SIZE, "10mm")
|
putString(Constants.CUVETTE_SIZE, "10mm")
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
|
||||||
binding.nameEditText.setText(contents)
|
binding.nameEditText.setText(contents)
|
||||||
|
}else if(contents.contains(singleTest)){
|
||||||
|
with(sharedPreference.edit()) {
|
||||||
|
putString(Constants.CUVETTE_SIZE, "10mmSt")
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
Toast.makeText(this, "Selected cuvette size: 2mm for single test", Toast.LENGTH_SHORT).show()
|
||||||
|
binding.nameEditText.setText(contents)
|
||||||
}else{
|
}else{
|
||||||
Toast.makeText(this, R.string.invalid_kit, Toast.LENGTH_LONG).show()
|
Toast.makeText(this, R.string.invalid_kit, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
@@ -133,10 +143,12 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
|
|||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
binding.toolbar.title = "Kit Serial Number"
|
binding.toolbar.title = "Kit Serial Number"
|
||||||
fromWhere = intent.getStringExtra("fromWhere").toString()
|
fromWhere = intent.getStringExtra("fromWhere").toString()
|
||||||
val maxTest = if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "2mm"){
|
if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "2mm"){
|
||||||
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
|
maxTest = Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
|
||||||
}else{
|
}else if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "10mm"){
|
||||||
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM
|
maxTest = Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM
|
||||||
|
} else if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mmSt").toString() == "10mmSt"){
|
||||||
|
maxTest = Constants.MAXIMUM_TEST_ALLOWED_SINGLE_TEST
|
||||||
}
|
}
|
||||||
val time = timeDifference(sharedPreference.getString(Constants.KIT_TIME, "").toString())
|
val time = timeDifference(sharedPreference.getString(Constants.KIT_TIME, "").toString())
|
||||||
val kitNum = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
|
val kitNum = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
|
||||||
@@ -212,19 +224,27 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
|
|||||||
binding.btnGo.setOnClickListener {
|
binding.btnGo.setOnClickListener {
|
||||||
val serialNumber = binding.nameEditText.text.toString().trim()
|
val serialNumber = binding.nameEditText.text.toString().trim()
|
||||||
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) {
|
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) {
|
||||||
if(serialNumber.contains("SMI/SC/")){
|
if(serialNumber.contains(TEST_FOR_2MM)){
|
||||||
with(sharedPreference.edit()) {
|
with(sharedPreference.edit()) {
|
||||||
putString(Constants.CUVETTE_SIZE, "2mm")
|
putString(Constants.CUVETTE_SIZE, "2mm")
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show()
|
||||||
}else if(serialNumber.contains("SMI/SC-2-D10/")){
|
}else if(serialNumber.contains(TEST_FOR_10MM)){
|
||||||
with(sharedPreference.edit()) {
|
with(sharedPreference.edit()) {
|
||||||
putString(Constants.CUVETTE_SIZE, "10mm")
|
putString(Constants.CUVETTE_SIZE, "10mm")
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
|
||||||
|
}else if(serialNumber.contains(singleTest)){
|
||||||
|
with(sharedPreference.edit()) {
|
||||||
|
putString(Constants.CUVETTE_SIZE, "10mmSt")
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
Toast.makeText(this, "Selected cuvette size: 2mm for single test", Toast.LENGTH_SHORT).show()
|
||||||
|
binding.nameEditText.setText(serialNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
val kitTime = SimpleDateFormat(
|
val kitTime = SimpleDateFormat(
|
||||||
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
|
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
|
||||||
).format(Calendar.getInstance().time).toString()
|
).format(Calendar.getInstance().time).toString()
|
||||||
@@ -351,16 +371,21 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
private fun isSerialValid(s: String): Boolean {
|
private fun isSerialValid(s: String): Boolean {
|
||||||
if (s.contains("SMI/SC/")) {
|
if (s.contains(TEST_FOR_2MM)) {
|
||||||
if(s.length != 17){
|
if(s.length != 17){
|
||||||
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC/000/00/000"
|
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC/000/00/000"
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}else if(s.contains("SMI/SC-2-D10/")){
|
}else if(s.contains(TEST_FOR_10MM)){
|
||||||
if(s.length != 27){
|
if(s.length != 27){
|
||||||
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC-2-D10/000000/000/000"
|
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC-2-D10/000000/000/000"
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}else if(s.contains(singleTest)){
|
||||||
|
if(s.length != 27){
|
||||||
|
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC-ST/000000/000/000"
|
||||||
|
return false
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,17 +14,23 @@
|
|||||||
package com.example.hpostesting.presentation.main_base
|
package com.example.hpostesting.presentation.main_base
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.net.Uri
|
||||||
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
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
@@ -33,20 +39,33 @@ import androidx.preference.SwitchPreferenceCompat
|
|||||||
import com.example.hpostesting.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpostesting.data.constant.DataHolder
|
import com.example.hpostesting.data.constant.DataHolder
|
||||||
import com.example.hpostesting.data.constant.LanguageManager
|
import com.example.hpostesting.data.constant.LanguageManager
|
||||||
|
import com.example.hpostesting.data.model.patient.HemoCubeTestData
|
||||||
import com.example.hpostesting.data.repository.DatabaseRepository
|
import com.example.hpostesting.data.repository.DatabaseRepository
|
||||||
import com.example.hpostesting.firebase.FirebaseConfig
|
import com.example.hpostesting.firebase.FirebaseConfig
|
||||||
import com.example.hpostesting.firebase.FirebaseManager
|
import com.example.hpostesting.firebase.FirebaseManager
|
||||||
|
import com.example.hpostesting.presentation.trueheme_test.TrueHemeTestViewModel
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import com.google.firebase.ktx.Firebase
|
||||||
|
import com.google.firebase.storage.ktx.storage
|
||||||
|
import com.google.firebase.storage.ktx.storageMetadata
|
||||||
import `in`.sminnovations.hpostesting.R
|
import `in`.sminnovations.hpostesting.R
|
||||||
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
|
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.io.File
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
private var isLanguageChanged = false
|
private var isLanguageChanged = false
|
||||||
|
|
||||||
class SlideshowFragment : Fragment() {
|
class SlideshowFragment : Fragment() {
|
||||||
private var selectedItem = "10mm"
|
private var selectedItem = "10mm"
|
||||||
private val values = arrayOf("10mm", "2mm")
|
private val values = arrayOf("10mm", "2mm", "10mmSt")
|
||||||
private lateinit var binding: FragmentSlideshowBinding
|
private lateinit var binding: FragmentSlideshowBinding
|
||||||
|
private val trueHemeTestViewModel: TrueHemeTestViewModel by activityViewModels()
|
||||||
private lateinit var sharedPreferences: SharedPreferences
|
private lateinit var sharedPreferences: SharedPreferences
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@@ -59,7 +78,9 @@ class SlideshowFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
binding.btnDownload.setOnClickListener {
|
||||||
|
sendData()
|
||||||
|
}
|
||||||
binding.nameEditText.setText(sharedPreferences.getString(Constants.LABNAME, ""))
|
binding.nameEditText.setText(sharedPreferences.getString(Constants.LABNAME, ""))
|
||||||
selectedItem = sharedPreferences.getString(Constants.CUVETTE_SIZE, "10mm").toString()
|
selectedItem = sharedPreferences.getString(Constants.CUVETTE_SIZE, "10mm").toString()
|
||||||
binding.btnGo.setOnClickListener {
|
binding.btnGo.setOnClickListener {
|
||||||
@@ -81,8 +102,10 @@ class SlideshowFragment : Fragment() {
|
|||||||
val pos: Int
|
val pos: Int
|
||||||
if (selectedItem == "10mm") {
|
if (selectedItem == "10mm") {
|
||||||
pos = 0
|
pos = 0
|
||||||
} else {
|
} else if (selectedItem == "2mm"){
|
||||||
pos = 1
|
pos = 1
|
||||||
|
} else {
|
||||||
|
pos = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.spinnerCuvette.adapter = adapter
|
binding.spinnerCuvette.adapter = adapter
|
||||||
@@ -114,6 +137,111 @@ class SlideshowFragment : Fragment() {
|
|||||||
childFragmentManager.beginTransaction().replace(binding.container.id, PrefsFragment())
|
childFragmentManager.beginTransaction().replace(binding.container.id, PrefsFragment())
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun sendData() {
|
||||||
|
//This data will saved in firebase storage check in HPOS-Prod
|
||||||
|
val dialog = AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle("Downloading")
|
||||||
|
.setMessage("Please wait...")
|
||||||
|
.setCancelable(false)
|
||||||
|
.create()
|
||||||
|
dialog.show()
|
||||||
|
downloadLocalDBData(dialog)
|
||||||
|
|
||||||
|
}
|
||||||
|
private fun downloadLocalDBData(dialog: DialogInterface) {
|
||||||
|
var csvDownloaded = false
|
||||||
|
|
||||||
|
trueHemeTestViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
|
||||||
|
if (!csvDownloaded) {
|
||||||
|
val downloadList = mutableListOf<HemoCubeTestData>()
|
||||||
|
|
||||||
|
userDataList.forEach { userData ->
|
||||||
|
Log.d("DownloadDebug", "userData: $userData, isCSVCreated: ${userData.isCSVCreated}")
|
||||||
|
downloadList.add(userData)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloadList.isNotEmpty()) {
|
||||||
|
// Set flag to prevent multiple executions due to observer
|
||||||
|
csvDownloaded = true
|
||||||
|
|
||||||
|
// Launch coroutine to handle CSV creation and upload
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
// Call suspend function to create CSV and wait for result
|
||||||
|
val csvFile = trueHemeTestViewModel.createCSVNew(downloadList, requireContext())
|
||||||
|
|
||||||
|
if (csvFile != null && csvFile.exists() && csvFile.length() > 0) {
|
||||||
|
uploadToFirebaseStorage(csvFile)
|
||||||
|
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
"CSV file created successfully at ${csvFile.absolutePath}",
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
} else {
|
||||||
|
csvDownloaded = false // Reset flag if failed
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
"CSV file creation failed, please try again",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
csvDownloaded = false // Reset flag if exception
|
||||||
|
e.printStackTrace()
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
"Error creating CSV file: ${e.message}",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
} finally {
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(requireContext(), "No data to download", Toast.LENGTH_SHORT).show()
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun uploadToFirebaseStorage(file: File) {
|
||||||
|
// Get Firebase Storage reference
|
||||||
|
val storage = Firebase.storage
|
||||||
|
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
|
||||||
|
val storageRef = storage.reference.child("!!!csv_files/hemocube_data_$timestamp.csv")
|
||||||
|
|
||||||
|
// Create file metadata
|
||||||
|
val metadata = storageMetadata {
|
||||||
|
contentType = "text/csv"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload file
|
||||||
|
val uploadTask = storageRef.putFile(Uri.fromFile(file), metadata)
|
||||||
|
|
||||||
|
uploadTask
|
||||||
|
.addOnSuccessListener {
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
"CSV file uploaded to Firebase successfully",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
.addOnFailureListener { exception ->
|
||||||
|
Log.e("FirebaseUpload", "Upload failed", exception)
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
"Failed to upload CSV to Firebase",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
.addOnProgressListener { taskSnapshot ->
|
||||||
|
val progress = (100.0 * taskSnapshot.bytesTransferred / taskSnapshot.totalByteCount)
|
||||||
|
Log.d("FirebaseUpload", "Upload is $progress% done")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrefsFragment : PreferenceFragmentCompat() {
|
class PrefsFragment : PreferenceFragmentCompat() {
|
||||||
|
|||||||
@@ -32,6 +32,20 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import com.example.hpostesting.data.constant.DataHolder
|
import com.example.hpostesting.data.constant.DataHolder
|
||||||
import com.example.hpostesting.util.Result
|
import com.example.hpostesting.util.Result
|
||||||
import com.example.hpostesting.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
|
import com.example.hpostesting.data.constant.Constants.negativeBoderLineMetricCheck2mmStMax
|
||||||
|
import com.example.hpostesting.data.constant.Constants.negativeBoderLineMetricCheck2mmStMin
|
||||||
|
import com.example.hpostesting.data.constant.Constants.negativeBorderlineMaxSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.negativeBorderlineMinSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.normalMaxSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.normalMinSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.positiveBoderLineMetricCheck2mmStMax
|
||||||
|
import com.example.hpostesting.data.constant.Constants.positiveBoderLineMetricCheck2mmStMin
|
||||||
|
import com.example.hpostesting.data.constant.Constants.positiveForSickleCellMaxSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.positiveForSickleCellMinSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.sickleCellDiseaseMaxSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.sickleCellDiseaseMinSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.sickleCellTraitMaxSt2mm
|
||||||
|
import com.example.hpostesting.data.constant.Constants.sickleCellTraitMinSt2mm
|
||||||
import com.example.hpostesting.data.constant.HemoCubeCommands
|
import com.example.hpostesting.data.constant.HemoCubeCommands
|
||||||
import com.example.hpostesting.data.constant.TestStatus
|
import com.example.hpostesting.data.constant.TestStatus
|
||||||
import com.example.hpostesting.data.model.TestState
|
import com.example.hpostesting.data.model.TestState
|
||||||
@@ -1196,6 +1210,20 @@ class TrueHemeTestFragment : Fragment() {
|
|||||||
binding.btnSamplestart.isEnabled = true
|
binding.btnSamplestart.isEnabled = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}else if(cuvetteSizeSP == "2mmSt"){
|
||||||
|
inRange2mmLed1 = led1Average in min2mmLed1..max2mmLed1
|
||||||
|
inRange2mmLed2 = led2Average in min2mmLed2..max2mmLed2
|
||||||
|
if(!inRange2mmLed1 || !inRange2mmLed2){
|
||||||
|
trueHemeTestViewModel.messages.postValue("Absorbance out-of-Range - Repeat test with adequate blood volume and Incubation time")
|
||||||
|
this.testStatusCode = TestStatus.BUFFER_PRINT_COMPLETED.code
|
||||||
|
binding.testing.visibility = View.GONE
|
||||||
|
binding.btnPlaceRefreshbuffer.visibility = View.GONE
|
||||||
|
binding.btnPlacebuffer.visibility = View.GONE
|
||||||
|
binding.btnSamplestart.visibility = View.VISIBLE
|
||||||
|
binding.btnSamplestart.isClickable = true
|
||||||
|
binding.btnSamplestart.isEnabled = true
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1478,6 +1506,25 @@ class TrueHemeTestFragment : Fragment() {
|
|||||||
return "Positive for Sickle Cell. Confirm with HPLC"
|
return "Positive for Sickle Cell. Confirm with HPLC"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}else if(cuvetteSizeSP == "2mmSt"){
|
||||||
|
if (deviceRatioClass == "Negative Borderline") {
|
||||||
|
if (borderlineMetric < negativeBoderLineMetricCheck2mmStMin){//1.34
|
||||||
|
return "Sickle Cell Trait"
|
||||||
|
}else if(borderlineMetric > negativeBoderLineMetricCheck2mmStMax){
|
||||||
|
return "Normal"
|
||||||
|
}else if(borderlineMetric > negativeBoderLineMetricCheck2mmStMin && borderlineMetric < negativeBoderLineMetricCheck2mmStMax){
|
||||||
|
return "Negative borderline. Confirm with HPLC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
|
||||||
|
if (borderlineMetric < positiveBoderLineMetricCheck2mmStMin){//1.34
|
||||||
|
return "Sickle Cell Disease"
|
||||||
|
}else if(borderlineMetric > positiveBoderLineMetricCheck2mmStMax){
|
||||||
|
return "Sickle Cell Trait"
|
||||||
|
}else if(borderlineMetric > positiveBoderLineMetricCheck2mmStMin && borderlineMetric < positiveBoderLineMetricCheck2mmStMax){
|
||||||
|
return "Positive for Sickle Cell. Confirm with HPLC"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -1548,6 +1595,22 @@ class TrueHemeTestFragment : Fragment() {
|
|||||||
if (ratio in sickleCellDiseaseMin2mm..sickleCellDiseaseMax2mm){
|
if (ratio in sickleCellDiseaseMin2mm..sickleCellDiseaseMax2mm){
|
||||||
return "Sickle Cell Disease"
|
return "Sickle Cell Disease"
|
||||||
}
|
}
|
||||||
|
}else if(cuvetteSize == "2mmSt"){
|
||||||
|
if (ratio in normalMinSt2mm..normalMaxSt2mm) {
|
||||||
|
return "Normal"
|
||||||
|
}
|
||||||
|
if (ratio in negativeBorderlineMinSt2mm..negativeBorderlineMaxSt2mm){
|
||||||
|
return "Negative Borderline"
|
||||||
|
}
|
||||||
|
if (ratio in sickleCellTraitMinSt2mm..sickleCellTraitMaxSt2mm){
|
||||||
|
return "Sickle Cell Trait"
|
||||||
|
}
|
||||||
|
if (ratio in positiveForSickleCellMinSt2mm..positiveForSickleCellMaxSt2mm){//0.36
|
||||||
|
return "Positive for Sickle Cell. HPLC for Confirmation"
|
||||||
|
}
|
||||||
|
if (ratio in sickleCellDiseaseMinSt2mm..sickleCellDiseaseMaxSt2mm){
|
||||||
|
return "Sickle Cell Disease"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -53,11 +53,15 @@ import com.example.hpostesting.util.NetworkMonitor
|
|||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.MultipartBody
|
import okhttp3.MultipartBody
|
||||||
import okhttp3.RequestBody.Companion.asRequestBody
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
|
import java.io.BufferedWriter
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileWriter
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -775,7 +779,44 @@ class TrueHemeTestViewModel @Inject constructor(
|
|||||||
|
|
||||||
return maxCapacity
|
return maxCapacity
|
||||||
}
|
}
|
||||||
|
suspend fun createCSVNew(data: List<HemoCubeTestData>, context: Context): File? {
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
val timestamp = System.currentTimeMillis()
|
||||||
|
val fileName = "hemocube_data_$timestamp.csv"
|
||||||
|
|
||||||
|
// Create file in app's external files directory
|
||||||
|
val appFile = File(context.getExternalFilesDir(null), fileName)
|
||||||
|
|
||||||
|
// Ensure this file is used by localFileDataSource
|
||||||
|
val exportSuccess = localFileDataSource.exportDataToCSV(appFile.absolutePath, data)
|
||||||
|
|
||||||
|
if (exportSuccess) {
|
||||||
|
// Update database records
|
||||||
|
data.forEach { item ->
|
||||||
|
hemoCubeDao.updateCSVFieldById(
|
||||||
|
item._id,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify file exists and has content
|
||||||
|
if (appFile.exists() && appFile.length() > 0) {
|
||||||
|
return@withContext appFile
|
||||||
|
} else {
|
||||||
|
Log.e("CSVCreation", "File creation verified failed: exists=${appFile.exists()}, size=${appFile.length()}")
|
||||||
|
return@withContext null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e("CSVCreation", "exportDataToCSV returned false")
|
||||||
|
return@withContext null
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("CSVCreation", "Error creating CSV", e)
|
||||||
|
return@withContext null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
fun createCSV(hemoCubeTestData: List<HemoCubeTestData>, appContext: Context) =
|
fun createCSV(hemoCubeTestData: List<HemoCubeTestData>, appContext: Context) =
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val fileName = "HPOS${getCurrentDate()}.csv"
|
val fileName = "HPOS${getCurrentDate()}.csv"
|
||||||
|
|||||||
@@ -88,12 +88,22 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="@id/spinnerCuvette"
|
app:layout_constraintBottom_toBottomOf="@id/spinnerCuvette"
|
||||||
app:layout_constraintStart_toEndOf="@id/spinnerCuvette"
|
app:layout_constraintStart_toEndOf="@id/spinnerCuvette"
|
||||||
app:layout_constraintTop_toTopOf="@id/spinnerCuvette" />
|
app:layout_constraintTop_toTopOf="@id/spinnerCuvette" />
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btn_download"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:text="Send Data To Server"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
app:cornerRadius="16dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/spinnerCuvette"
|
||||||
|
/>
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/container"
|
android:id="@+id/container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/btn_add_size"
|
app:layout_constraintTop_toBottomOf="@+id/btn_download"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:layout_marginTop="10dp"/>
|
android:layout_marginTop="10dp"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user