From e64fb0914493145a318efedfa3f4e7994dc5abda Mon Sep 17 00:00:00 2001 From: Sathwik Date: Thu, 24 Jul 2025 11:18:32 +0530 Subject: [PATCH] created 132 for gitub --- README.md | 2 +- app/build.gradle | 5 +- app/src/main/AndroidManifest.xml | 2 +- app/src/main/cpp/server.cpp | 2 +- .../reportgen/ui/report/ReportViewModel.kt | 19 - .../presentation/main_base/PanelFragment.kt | 8 +- .../reportgen/ReportActivity.kt | 4 +- .../reportgen/ui/report/BufferAdapter.kt | 2 +- .../reportgen/ui/report/PrintObject.kt | 329 ++++++++++++++++++ .../reportgen/ui/report/ReportFragment.kt | 50 +-- .../reportgen/viewModel/ReportViewModel.kt | 188 ++++++++++ .../trueheme_test/TrueHemeTestFragment.kt | 9 +- app/src/main/res/layout/fragment_report.xml | 2 +- 13 files changed, 556 insertions(+), 66 deletions(-) delete mode 100644 app/src/main/java/com/example/hpostesting/data/model/reportgen/ui/report/ReportViewModel.kt rename app/src/main/java/com/example/hpostesting/{data/model => presentation}/reportgen/ReportActivity.kt (81%) rename app/src/main/java/com/example/hpostesting/{data/model => presentation}/reportgen/ui/report/BufferAdapter.kt (97%) create mode 100644 app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/PrintObject.kt rename app/src/main/java/com/example/hpostesting/{data/model => presentation}/reportgen/ui/report/ReportFragment.kt (86%) create mode 100644 app/src/main/java/com/example/hpostesting/presentation/reportgen/viewModel/ReportViewModel.kt diff --git a/README.md b/README.md index 24c77b2..c2c3e4c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## current version : 2.1.132 ### Release key - + key0: prime24 ### Version 133.3 diff --git a/app/build.gradle b/app/build.gradle index 91d80e8..d78f36a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,7 +22,7 @@ android { minSdk 30 targetSdk 34 versionCode 138 - versionName "2.1.133.3" + versionName "2.1.132" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { @@ -183,4 +183,7 @@ dependencies { implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.17' implementation 'androidx.security:security-crypto:1.1.0-alpha03' + + + } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a26d297..c645e1e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,7 +43,7 @@ android:theme="@style/Theme.HPOSTesting" tools:targetApi="31"> > = hemoCubeDao.getAll() -} diff --git a/app/src/main/java/com/example/hpostesting/presentation/main_base/PanelFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/main_base/PanelFragment.kt index 41ce1be..945868c 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/main_base/PanelFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/main_base/PanelFragment.kt @@ -25,7 +25,7 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import com.example.hpostesting.data.constant.Constants -import com.example.hpostesting.data.model.reportgen.ReportActivity +import com.example.hpostesting.presentation.reportgen.ReportActivity import com.example.hpostesting.presentation.autodac.AutoDacActivity import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity import com.example.hpostesting.presentation.calibration.CalibrationActivity @@ -90,7 +90,7 @@ class PanelFragment : Fragment() { binding.btnDeviceInfo.visibility = View.VISIBLE binding.btnResetPassword.visibility = View.VISIBLE binding.btnUpdateValues.visibility = View.VISIBLE - binding.btnPrintReport.visibility = View.VISIBLE + binding.btnPrintReport.visibility = View.GONE }else{ binding.btnResetPassword.visibility = View.GONE binding.btnDeviceProvision.visibility = View.GONE @@ -104,7 +104,7 @@ class PanelFragment : Fragment() { binding.btnSubmit.visibility = View.GONE binding.btnDeviceInfo.visibility = View.VISIBLE binding.btnUpdateValues.visibility = View.GONE - binding.btnPrintReport.visibility = View.VISIBLE + binding.btnPrintReport.visibility = View.GONE } binding.btnResetPassword.setOnClickListener{ @@ -140,7 +140,7 @@ class PanelFragment : Fragment() { } binding.btnPrintReport.setOnClickListener{ - startActivity(Intent(requireContext(),ReportActivity::class.java)) + startActivity(Intent(requireContext(), ReportActivity::class.java)) } binding.btnFirefox.setOnClickListener { diff --git a/app/src/main/java/com/example/hpostesting/data/model/reportgen/ReportActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ReportActivity.kt similarity index 81% rename from app/src/main/java/com/example/hpostesting/data/model/reportgen/ReportActivity.kt rename to app/src/main/java/com/example/hpostesting/presentation/reportgen/ReportActivity.kt index 4400af1..0d09df6 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/reportgen/ReportActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ReportActivity.kt @@ -1,8 +1,8 @@ -package com.example.hpostesting.data.model.reportgen +package com.example.hpostesting.presentation.reportgen import androidx.appcompat.app.AppCompatActivity import android.os.Bundle -import com.example.hpostesting.data.model.reportgen.ui.report.ReportFragment +import com.example.hpostesting.presentation.reportgen.ui.report.ReportFragment import dagger.hilt.android.AndroidEntryPoint import `in`.sminnovations.hpostesting.R @AndroidEntryPoint diff --git a/app/src/main/java/com/example/hpostesting/data/model/reportgen/ui/report/BufferAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/BufferAdapter.kt similarity index 97% rename from app/src/main/java/com/example/hpostesting/data/model/reportgen/ui/report/BufferAdapter.kt rename to app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/BufferAdapter.kt index c8ca75e..7e05035 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/reportgen/ui/report/BufferAdapter.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/BufferAdapter.kt @@ -1,4 +1,4 @@ -package com.example.hpostesting.data.model.reportgen.ui.report +package com.example.hpostesting.presentation.reportgen.ui.report import android.graphics.Color import android.view.LayoutInflater diff --git a/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/PrintObject.kt b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/PrintObject.kt new file mode 100644 index 0000000..d8a8aed --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/PrintObject.kt @@ -0,0 +1,329 @@ +package com.example.hpostesting.presentation.reportgen.ui.report + +import android.content.ActivityNotFoundException +import android.content.Context +import android.content.Intent +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.Typeface +import android.graphics.pdf.PdfDocument +import android.util.Log +import android.widget.Toast +import androidx.core.content.ContextCompat +import androidx.core.content.FileProvider +import com.example.hpostesting.data.model.patient.HemoCubeTestData +import `in`.sminnovations.hpostesting.R +import java.io.File +import java.io.FileOutputStream +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + + +object ReportGen { + + private const val PAGE_WIDTH = 595 // A4 width in points + private const val PAGE_HEIGHT = 842 // A4 height in points + private const val MARGIN_LEFT = 50f + private const val MARGIN_RIGHT = 50f + private const val MARGIN_TOP = 80f + private const val MARGIN_BOTTOM = 80f + + fun generate(context: Context, dataList: List) { + if (dataList.isEmpty()) { + Toast.makeText(context, "No items selected for report generation", Toast.LENGTH_SHORT).show() + return + } + + Log.d("ReportGen", "Generating report for ${dataList.size} items") + + val message = if (dataList.size == 1) { + "Report for kit ${dataList.first()._id} started." + } else { + "Report for ${dataList.size} kits started." + } + Toast.makeText(context, message, Toast.LENGTH_SHORT).show() + + val pdfFile = createProfessionalPdfReport(context, dataList) + previewPdf(context, pdfFile) + } + + private fun createProfessionalPdfReport(context: Context, dataList: List): File { + val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date()) + val file = File(context.getExternalFilesDir(null), "HemoCube_Report_$timestamp.pdf") + + val pdfDocument = PdfDocument() + + // Paint styles + val headerPaint = Paint().apply { + typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD) + textSize = 20f + color = Color.rgb(0, 102, 153) // Professional blue + } + + val titlePaint = Paint().apply { + typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD) + textSize = 18f + color = Color.BLACK + } + + val sectionHeaderPaint = Paint().apply { + typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD) + textSize = 14f + color = Color.rgb(0, 102, 153) + } + + val contentPaint = Paint().apply { + textSize = 11f + color = Color.DKGRAY + } + + val boldContentPaint = Paint().apply { + typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD) + textSize = 11f + color = Color.BLACK + } + + val disclaimerPaint = Paint().apply { + textSize = 9f + color = Color.GRAY + typeface = Typeface.create(Typeface.DEFAULT, Typeface.ITALIC) + } + + // Create one page per test data + dataList.forEachIndexed { index, testData -> + val pageInfo = PdfDocument.PageInfo.Builder(PAGE_WIDTH, PAGE_HEIGHT, index + 1).create() + val page = pdfDocument.startPage(pageInfo) + val canvas = page.canvas + + drawPage(canvas, testData, index + 1, dataList.size, + headerPaint, titlePaint, sectionHeaderPaint, + contentPaint, boldContentPaint, disclaimerPaint,context) + + pdfDocument.finishPage(page) + } + + pdfDocument.writeTo(FileOutputStream(file)) + pdfDocument.close() + return file + } + + private fun drawPage( + canvas: Canvas, + testData: HemoCubeTestData, + pageNumber: Int, + totalPages: Int, + headerPaint: Paint, + titlePaint: Paint, + sectionHeaderPaint: Paint, + contentPaint: Paint, + boldContentPaint: Paint, + disclaimerPaint: Paint, + context: Context + ) { + var currentY = MARGIN_TOP + + // Header with logo placeholder and title + drawHeader(canvas, headerPaint, titlePaint, currentY, context) + currentY += 100f + + // Sample Information Section + currentY = drawSection(canvas, "SAMPLE INFORMATION", sectionHeaderPaint, currentY) + currentY = drawKeyValuePair(canvas, "Sample ID:", testData.sampleid.toString(), boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Blood Group:", testData.bloodGroup, boldContentPaint, contentPaint, currentY) + currentY += 15f + + // Test Information Section + currentY = drawSection(canvas, "TEST INFORMATION", sectionHeaderPaint, currentY) + currentY = drawKeyValuePair(canvas, "Test ID:", testData._id, boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Test Type:", testData.testType ?: "TrueHeme", boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Test Time:", testData.testTime ?: "N/A", boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Incubation Time:", testData.incubationTime, boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Kit Serial:", testData.kitSerial, boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Device Serial:", testData.deviceSerialNumber, boldContentPaint, contentPaint, currentY) + currentY += 15f + + // Test Results Section + currentY = drawSection(canvas, "TEST RESULTS", sectionHeaderPaint, currentY) + currentY = drawKeyValuePair(canvas, "Classification Result:", testData.classificationResult, boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Device Ratio:", testData.deviceRatio?.toString() ?: "N/A", boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Calculated Ratio:", testData.calculatedRatio?.toString() ?: "N/A", boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Slope Ratio:", testData.slopeRatio?.toString() ?: "N/A", boldContentPaint, contentPaint, currentY) + currentY += 15f + + // LED Measurements Section + currentY = drawSection(canvas, "LED MEASUREMENTS", sectionHeaderPaint, currentY) + currentY = drawLEDData(canvas, testData, boldContentPaint, contentPaint, currentY) + currentY += 15f + + // Laboratory Information Section + currentY = drawSection(canvas, "LABORATORY INFORMATION", sectionHeaderPaint, currentY) + currentY = drawKeyValuePair(canvas, "Lab Name:", testData.labName ?: "N/A", boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "Center Name:", testData.centerName ?: "N/A", boldContentPaint, contentPaint, currentY) + currentY = drawKeyValuePair(canvas, "District:", testData.district ?: "N/A", boldContentPaint, contentPaint, currentY) + currentY += 15f + + // Footer with page number and disclaimer + drawFooter(canvas, pageNumber, totalPages, contentPaint, disclaimerPaint) + } + + private fun drawHeader(canvas: Canvas, headerPaint: Paint, titlePaint: Paint, startY: Float, context: Context) { + // Load and draw actual logo + try { + // Method 1: Load from drawable resources + val logoDrawable = ContextCompat.getDrawable(context, R.mipmap.hpos_icon) // Replace with your logo resource + logoDrawable?.let { drawable -> + val logoWidth = 70 + val logoHeight = 60 + drawable.setBounds( + MARGIN_LEFT.toInt(), + (startY - 20f).toInt(), + (MARGIN_LEFT + logoWidth).toInt(), + (startY + logoHeight - 20f).toInt() + ) + drawable.draw(canvas) + } + } catch (e: Exception) { + // Fallback to placeholder if logo loading fails + val logoPaint = Paint().apply { + color = Color.rgb(0, 102, 153) + style = Paint.Style.FILL + } + canvas.drawRect(MARGIN_LEFT, startY - 20f, MARGIN_LEFT + 60f, startY + 20f, logoPaint) + + // Draw "LOGO" text as placeholder + val placeholderPaint = Paint().apply { + color = Color.WHITE + textSize = 12f + typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD) + textAlign = Paint.Align.CENTER + } + canvas.drawText("LOGO", MARGIN_LEFT + 30f, startY, placeholderPaint) + } + + // Company name and title + canvas.drawText("HemoCube", MARGIN_LEFT + 80f, startY + 10f, headerPaint) + canvas.drawText("Medical Test Report", MARGIN_LEFT, startY + 40f, titlePaint) + + // Report generation date + val currentDate = SimpleDateFormat("dd MMM yyyy, HH:mm", Locale.getDefault()).format(Date()) + canvas.drawText("Generated: $currentDate", PAGE_WIDTH - MARGIN_RIGHT - 150f, startY + 10f, Paint().apply { + textSize = 10f + color = Color.GRAY + }) + + // Line under header + val linePaint = Paint().apply { + color = Color.rgb(0, 102, 153) + strokeWidth = 2f + } + canvas.drawLine(MARGIN_LEFT, startY + 60f, PAGE_WIDTH - MARGIN_RIGHT, startY + 60f, linePaint) + } + + private fun drawSection(canvas: Canvas, title: String, paint: Paint, y: Float): Float { + canvas.drawText(title, MARGIN_LEFT, y, paint) + + // Underline for section + val linePaint = Paint().apply { + color = Color.rgb(0, 102, 153) + strokeWidth = 1f + } + canvas.drawLine(MARGIN_LEFT, y + 5f, MARGIN_LEFT + paint.measureText(title), y + 5f, linePaint) + + return y + 25f + } + + private fun drawKeyValuePair(canvas: Canvas, key: String, value: String, keyPaint: Paint, valuePaint: Paint, y: Float): Float { + canvas.drawText(key, MARGIN_LEFT + 10f, y, keyPaint) + canvas.drawText(value, MARGIN_LEFT + 150f, y, valuePaint) + return y + 18f + } + + private fun drawLEDData(canvas: Canvas, testData: HemoCubeTestData, keyPaint: Paint, valuePaint: Paint, startY: Float): Float { + var currentY = startY + + currentY = drawKeyValuePair(canvas, "LED1 Sample:", testData.led1Sample?.toString() ?: "N/A", keyPaint, valuePaint, currentY) + currentY = drawKeyValuePair(canvas, "LED2 Sample:", testData.led2Sample?.toString() ?: "N/A", keyPaint, valuePaint, currentY) + currentY = drawKeyValuePair(canvas, "LED3 Sample:", testData.led3Sample?.toString() ?: "N/A", keyPaint, valuePaint, currentY) + currentY = drawKeyValuePair(canvas, "LED4 Sample:", testData.led4Sample?.toString() ?: "N/A", keyPaint, valuePaint, currentY) + + currentY = drawKeyValuePair(canvas, "ABS1:", testData.abs1?.toString() ?: "N/A", keyPaint, valuePaint, currentY) + currentY = drawKeyValuePair(canvas, "ABS2:", testData.abs2?.toString() ?: "N/A", keyPaint, valuePaint, currentY) + currentY = drawKeyValuePair(canvas, "ABS3:", testData.abs3?.toString() ?: "N/A", keyPaint, valuePaint, currentY) + currentY = drawKeyValuePair(canvas, "ABS4:", testData.abs4?.toString() ?: "N/A", keyPaint, valuePaint, currentY) + + return currentY + } + + private fun drawFooter(canvas: Canvas, pageNumber: Int, totalPages: Int, contentPaint: Paint, disclaimerPaint: Paint) { + val footerY = PAGE_HEIGHT - MARGIN_BOTTOM + 20f + + // Page number + canvas.drawText("Page $pageNumber of $totalPages", PAGE_WIDTH - MARGIN_RIGHT - 80f, footerY, contentPaint) + + // Disclaimer + val disclaimerText = "DISCLAIMER: This report is generated by HemoCube automated system. " + + "Results should be interpreted by qualified medical professionals. " + + "This report is for diagnostic purposes only and should not be used as the sole basis for medical decisions. " + + "Please consult with your healthcare provider for proper interpretation and treatment recommendations." + + val disclaimerLines = wrapText(disclaimerText, disclaimerPaint, PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT) + var disclaimerY = footerY + 20f + + disclaimerLines.forEach { line -> + canvas.drawText(line, MARGIN_LEFT, disclaimerY, disclaimerPaint) + disclaimerY += 12f + } + + // Footer line + val linePaint = Paint().apply { + color = Color.rgb(0, 102, 153) + strokeWidth = 1f + } + canvas.drawLine(MARGIN_LEFT, footerY - 10f, PAGE_WIDTH - MARGIN_RIGHT, footerY - 10f, linePaint) + } + + private fun wrapText(text: String, paint: Paint, maxWidth: Float): List { + val words = text.split(" ") + val lines = mutableListOf() + var currentLine = "" + + for (word in words) { + val testLine = if (currentLine.isEmpty()) word else "$currentLine $word" + if (paint.measureText(testLine) <= maxWidth) { + currentLine = testLine + } else { + if (currentLine.isNotEmpty()) { + lines.add(currentLine) + } + currentLine = word + } + } + + if (currentLine.isNotEmpty()) { + lines.add(currentLine) + } + + return lines + } + + private fun previewPdf(context: Context, file: File) { + val uri = FileProvider.getUriForFile( + context, + "${context.packageName}.fileprovider", + file + ) + + val intent = Intent(Intent.ACTION_VIEW).apply { + setDataAndType(uri, "application/pdf") + flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NO_HISTORY + } + + try { + context.startActivity(intent) + } catch (e: ActivityNotFoundException) { + Toast.makeText(context, "No PDF viewer found", Toast.LENGTH_SHORT).show() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/model/reportgen/ui/report/ReportFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/ReportFragment.kt similarity index 86% rename from app/src/main/java/com/example/hpostesting/data/model/reportgen/ui/report/ReportFragment.kt rename to app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/ReportFragment.kt index 623d01e..34e746b 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/reportgen/ui/report/ReportFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/ReportFragment.kt @@ -1,7 +1,14 @@ -package com.example.hpostesting.data.model.reportgen.ui.report +package com.example.hpostesting.presentation.reportgen.ui.report import android.app.DatePickerDialog +import android.content.ActivityNotFoundException import android.content.Context +import android.content.Intent +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.Typeface +import android.graphics.pdf.PdfDocument import android.os.Bundle import android.util.Log import android.view.LayoutInflater @@ -14,27 +21,31 @@ import android.widget.EditText import android.widget.Spinner import android.widget.TextView import android.widget.Toast +import androidx.core.content.ContextCompat +import androidx.core.content.FileProvider import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.presentation.reportgen.viewModel.ReportViewModel import dagger.hilt.android.AndroidEntryPoint import `in`.sminnovations.hpostesting.R +import java.io.File +import java.io.FileOutputStream import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date import java.util.Locale + + @AndroidEntryPoint class ReportFragment : Fragment() { - companion object { fun newInstance() = ReportFragment() } - private val viewModel: ReportViewModel by viewModels() - private lateinit var recyclerView: RecyclerView private lateinit var searchBar: EditText private lateinit var filterSpinner: Spinner @@ -59,7 +70,7 @@ class ReportFragment : Fragment() { setupObservers() setupListeners() - // Set default filter to Today + // default filter to Today setDefaultFilter() } @@ -148,7 +159,7 @@ class ReportFragment : Fragment() { val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) val selectedCalendar = Calendar.getInstance() selectedCalendar.set(selectedYear, selectedMonth, selectedDay) - customDate = sdf.format(selectedCalendar.time) + customDate = sdf.format(selectedCalendar.time) // Update calendar button text val displayFormat = SimpleDateFormat("MMM dd, yyyy", Locale.getDefault()) @@ -205,30 +216,3 @@ class ReportFragment : Fragment() { } } - - -object ReportGen { - fun generate(context: Context, dataList: List) { - if (dataList.isEmpty()) { - Toast.makeText(context, "No items selected for report generation", Toast.LENGTH_SHORT).show() - return - } - - Log.d("ReportGen", "Generating report for ${dataList.size} items") - - val kitNumbers = dataList.map { it._id } - val message = if (dataList.size == 1) { - "Report for kit ${kitNumbers.first()} started." - } else { - "Report for ${dataList.size} kits started." - } - - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() - - // TODO: Add PDF generation, email, or preview logic here - // You can iterate through dataList to include all selected items in the report - dataList.forEach { item-> - Log.d("ReportGen", "Processing kit: ${item._id}, Result: ${item.classificationResult}, Time: ${item.testTime}") - } - } -} diff --git a/app/src/main/java/com/example/hpostesting/presentation/reportgen/viewModel/ReportViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/reportgen/viewModel/ReportViewModel.kt new file mode 100644 index 0000000..8127af6 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/reportgen/viewModel/ReportViewModel.kt @@ -0,0 +1,188 @@ +package com.example.hpostesting.presentation.reportgen.viewModel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.hpostesting.data.dao.HemoCubeDao +import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.UserData +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + + +@HiltViewModel +class ReportViewModel @Inject constructor( + private val hemoCubeDao: HemoCubeDao, +) : ViewModel() { + // val allKitTestData: LiveData> = hemoCubeDao.getAll() + val allKitTestData = MutableLiveData>() + init { + loadTestData() + } + private fun loadTestData() { + viewModelScope.launch { + val data = hemoCubeDao.getAll() + if (data.value.isNullOrEmpty()) { + allKitTestData.value = dummyDataList + } else { + allKitTestData.value = data.value + } + } + } +} + + +val dummyDataList = listOf( + HemoCubeTestData( + sampleid = 1, + _id = "ID001", + name = "John Doe", + incubationTime = "15 mins", + bloodGroup = "A+", + age = "30", + state = "Karnataka", + abhaId = "ABHA123456", + userImageURL = "https://example.com/image1.jpg", + location = UserData.Location(latitude = 12.9716, longitude = 77.5946), + reportUploadTime = "2025-07-20T10:30:00", + testTime = "2025-07-20T10:00:00", + gender = "Male", + classificationResult = "Normal", + prdClassification = "Class A", + deviceSerialNumber = "SN123456", + deviceId = "DEVICE001", + appVersion = "1.2.3", + kitSerial = "KIT001", + resultData = "{\"hb\":13.5}", + led1Buffer = 0.95, + led2Buffer = 1.01, + led3Buffer = 0.98, + led4Buffer = 1.02, + led1Sample = 0.75, + led2Sample = 0.80, + led3Sample = 0.78, + led4Sample = 0.81, + led1Average = 0.85, + led2Average = 0.86, + led3Average = 0.87, + led4Average = 0.88, + abs1 = 0.10, + abs2 = 0.12, + abs3 = 0.11, + abs4 = 0.13, + hb3 = 13.2, + hb4 = 13.6, + led1Gain1 = 1.1, + led2Gain1 = 1.1, + led3Gain1 = 1.1, + led4Gain1 = 1.1, + led1Air1 = 0.5, + led2Air1 = 0.5, + led3Air1 = 0.5, + led4Air1 = 0.5, + deviceRatio = 1.23, + calculatedRatio = 1.21, + predictedDenovixRatio = 1.22, + slopeRatio = 0.98, + coefficients = "{\"a\":0.1,\"b\":0.2}", + deviceRatioClass = "Optimal", + slopeRatioClass = "Stable", + borderlineMethod2Class = "Negative", + errorMessages = "", + batteryLevel = "85%", + batteryCapacity = "4000mAh", + batteryMaxCapacity = "5000mAh", + batteryTemperature = "36C", + batteryVoltage = "3.7V", + molbioFlag = true, + quickCapture = true, + solution = "NaCl", + concentration = "5%", + filter = "HE", + volume = "0.5ml", + isCSVCreated = true, + labName = "LabCorp", + cuvetteSize = "Standard", + district = "Bangalore Urban", + centerName = "Health Center 1", + ipAddress = "192.168.0.100", + configUpdatedRecent = "2025-07-19T08:45:00" + ), + + HemoCubeTestData( + sampleid = 2, + _id = "ID002", + name = "Jane Smith", + incubationTime = "10 mins", + bloodGroup = "B-", + age = "28", + state = "Maharashtra", + abhaId = "ABHA654321", + userImageURL = "https://example.com/image2.jpg", + location = UserData.Location(latitude = 18.5204, longitude = 73.8567), + reportUploadTime = "2025-07-21T09:15:00", + testTime = "2025-07-21T08:45:00", + gender = "Female", + classificationResult = "Anemia", + prdClassification = "Class B", + deviceSerialNumber = "SN654321", + deviceId = "DEVICE002", + appVersion = "1.2.3", + kitSerial = "KIT002", + resultData = "{\"hb\":9.0}", + led1Buffer = 1.05, + led2Buffer = 1.00, + led3Buffer = 1.02, + led4Buffer = 0.99, + led1Sample = 0.60, + led2Sample = 0.65, + led3Sample = 0.63, + led4Sample = 0.62, + led1Average = 0.70, + led2Average = 0.71, + led3Average = 0.72, + led4Average = 0.69, + abs1 = 0.15, + abs2 = 0.16, + abs3 = 0.17, + abs4 = 0.14, + hb3 = 9.2, + hb4 = 8.8, + led1Gain1 = 1.2, + led2Gain1 = 1.2, + led3Gain1 = 1.2, + led4Gain1 = 1.2, + led1Air1 = 0.6, + led2Air1 = 0.6, + led3Air1 = 0.6, + led4Air1 = 0.6, + deviceRatio = 0.95, + calculatedRatio = 0.93, + predictedDenovixRatio = 0.94, + slopeRatio = 1.02, + coefficients = "{\"a\":0.15,\"b\":0.25}", + deviceRatioClass = "Low", + slopeRatioClass = "Fluctuating", + borderlineMethod2Class = "Positive", + errorMessages = "Low Hb detected", + batteryLevel = "78%", + batteryCapacity = "3800mAh", + batteryMaxCapacity = "5000mAh", + batteryTemperature = "37C", + batteryVoltage = "3.6V", + molbioFlag = false, + quickCapture = false, + solution = "PBS", + concentration = "3%", + filter = "LE", + volume = "0.4ml", + isCSVCreated = false, + labName = "MedLab", + cuvetteSize = "Small", + district = "Pune", + centerName = "Health Center 2", + ipAddress = "192.168.0.101", + configUpdatedRecent = "2025-07-20T11:00:00" + ) +) diff --git a/app/src/main/java/com/example/hpostesting/presentation/trueheme_test/TrueHemeTestFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/trueheme_test/TrueHemeTestFragment.kt index 97e11c8..fdb1f02 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/trueheme_test/TrueHemeTestFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/trueheme_test/TrueHemeTestFragment.kt @@ -56,6 +56,8 @@ import kotlin.random.Random //This is TrueHemeTestFragment, where actual tests are done first buffer check and then sample check //and finally on submit test data to database if online or store in offline database @Suppress("MemberVisibilityCanBePrivate") + +val autoSumbt = false class TrueHemeTestFragment : Fragment() { private var positiveBoderLine10mm1=Constants.positiveBoderLineMetricCheck10mmMin private var positiveBoderLine10mm2=Constants.positiveBoderLineMetricCheck10mmMax @@ -1011,11 +1013,14 @@ class TrueHemeTestFragment : Fragment() { activity?.runOnUiThread { //changing to invisible - binding.btnSubmit.visibility = View.GONE + binding.btnSubmit.visibility = View.VISIBLE // binding.btnSubmit.isEnabled = true // binding.btnSubmit.isClickable = true // binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) - autoSmbt(true) + if (autoSumbt){ + binding.btnSubmit.visibility = View.GONE + autoSmbt(autoSumbt) + } binding.ivCheck.visibility = View.VISIBLE } diff --git a/app/src/main/res/layout/fragment_report.xml b/app/src/main/res/layout/fragment_report.xml index 1db7b78..1bc085b 100644 --- a/app/src/main/res/layout/fragment_report.xml +++ b/app/src/main/res/layout/fragment_report.xml @@ -10,7 +10,7 @@ android:id="@+id/searchBar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="Search by kitno or result" + android:hint="Search by smaple ID or result" android:imeOptions="actionSearch" android:inputType="text" />