diff --git a/inventory-app/app/build.gradle b/inventory-app/app/build.gradle
index 22a3067f63df..0112ed41c62c 100644
--- a/inventory-app/app/build.gradle
+++ b/inventory-app/app/build.gradle
@@ -21,8 +21,13 @@ android {
viewBinding true
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
kotlinOptions {
- jvmTarget = '17'
+ jvmTarget = '1.8'
}
}
@@ -41,15 +46,23 @@ dependencies {
implementation "com.squareup.okhttp3:okhttp:4.12.0"
implementation "com.squareup.retrofit2:retrofit:2.11.0"
+ implementation "com.squareup.retrofit2:converter-gson:2.11.0"
- implementation "org.apache.poi:poi-ooxml-lite:5.2.5"
+ // Apache POI for Excel and Streaming Reader
+ implementation "org.apache.poi:poi:5.2.5"
+ implementation "org.apache.poi:poi-ooxml:5.2.5"
+ // Using excel-streaming-reader for memory efficiency (batch processing of large files)
+ implementation "com.github.pjfanning:excel-streaming-reader:4.2.1"
implementation "com.journeyapps:zxing-android-embedded:4.3.0"
+ implementation "com.google.zxing:core:3.5.3"
implementation "com.google.dagger:hilt-android:2.51"
kapt "com.google.dagger:hilt-compiler:2.51"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.7.0"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0"
+ implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.7.0"
implementation "androidx.activity:activity-ktx:1.9.0"
implementation "androidx.fragment:fragment-ktx:1.6.2"
}
diff --git a/inventory-app/app/src/main/AndroidManifest.xml b/inventory-app/app/src/main/AndroidManifest.xml
index 6f95bf322585..2551ecfa416a 100644
--- a/inventory-app/app/src/main/AndroidManifest.xml
+++ b/inventory-app/app/src/main/AndroidManifest.xml
@@ -1,21 +1,38 @@
+
+
+
-
+ android:label="Inventory App"
+ android:supportsRtl="true"
+ android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
+ tools:replace="android:theme">
+
+
+
+
+
+
+
diff --git a/inventory-app/app/src/main/java/com/example/inventory/InventoryApplication.kt b/inventory-app/app/src/main/java/com/example/inventory/InventoryApplication.kt
new file mode 100644
index 000000000000..b8ce83e2c7e3
--- /dev/null
+++ b/inventory-app/app/src/main/java/com/example/inventory/InventoryApplication.kt
@@ -0,0 +1,7 @@
+package com.example.inventory
+
+import android.app.Application
+import dagger.hilt.android.HiltAndroidApp
+
+@HiltAndroidApp
+class InventoryApplication : Application()
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/AppDatabase.kt b/inventory-app/app/src/main/java/com/example/inventory/data/AppDatabase.kt
index 2ca95d56ccf2..0a7f92d2526b 100644
--- a/inventory-app/app/src/main/java/com/example/inventory/data/AppDatabase.kt
+++ b/inventory-app/app/src/main/java/com/example/inventory/data/AppDatabase.kt
@@ -2,9 +2,11 @@ package com.example.inventory.data
import androidx.room.Database
import androidx.room.RoomDatabase
+import com.example.inventory.data.dao.InventoryDao
+import com.example.inventory.data.entity.Item
+import com.example.inventory.data.entity.WarehouseStock
-@Database(entities = [Item::class, WarehouseStock::class], version = 1)
+@Database(entities = [Item::class, WarehouseStock::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
- abstract fun itemDao(): ItemDao
- abstract fun warehouseStockDao(): WarehouseStockDao
+ abstract fun inventoryDao(): InventoryDao
}
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/Item.kt b/inventory-app/app/src/main/java/com/example/inventory/data/Item.kt
deleted file mode 100644
index 8244964546db..000000000000
--- a/inventory-app/app/src/main/java/com/example/inventory/data/Item.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.example.inventory.data
-
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.Index
-import androidx.room.PrimaryKey
-
-@Entity(tableName = "items", indices = [Index(value = ["code"], unique = true)])
-data class Item(
- @PrimaryKey(autoGenerate = true) val id: Long = 0,
- @ColumnInfo(name = "code") val code: String,
- @ColumnInfo(name = "name") val name: String,
- @ColumnInfo(name = "price") val price: Double
-)
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/ItemDao.kt b/inventory-app/app/src/main/java/com/example/inventory/data/ItemDao.kt
deleted file mode 100644
index 05ec3346c64f..000000000000
--- a/inventory-app/app/src/main/java/com/example/inventory/data/ItemDao.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.example.inventory.data
-
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.OnConflictStrategy
-import androidx.room.Query
-import androidx.room.Transaction
-
-@Dao
-interface ItemDao {
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- suspend fun insertItems(items: List- ): List
-
- @Query("SELECT * FROM items WHERE code = :code LIMIT 1")
- suspend fun findByCode(code: String): Item?
-
- @Transaction
- @Query("SELECT * FROM items WHERE code = :code LIMIT 1")
- suspend fun findWithStock(code: String): ItemWithStock?
-
- @Query("DELETE FROM items")
- suspend fun clearItems()
-}
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/ItemWithStock.kt b/inventory-app/app/src/main/java/com/example/inventory/data/ItemWithStock.kt
deleted file mode 100644
index 488e62ee740b..000000000000
--- a/inventory-app/app/src/main/java/com/example/inventory/data/ItemWithStock.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.example.inventory.data
-
-import androidx.room.Embedded
-import androidx.room.Relation
-
-data class ItemWithStock(
- @Embedded val item: Item,
- @Relation(parentColumn = "id", entityColumn = "itemId")
- val stock: List
-)
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/WarehouseStockDao.kt b/inventory-app/app/src/main/java/com/example/inventory/data/WarehouseStockDao.kt
deleted file mode 100644
index aa9e3e9f1b8a..000000000000
--- a/inventory-app/app/src/main/java/com/example/inventory/data/WarehouseStockDao.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.example.inventory.data
-
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.OnConflictStrategy
-import androidx.room.Query
-
-@Dao
-interface WarehouseStockDao {
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- suspend fun insertAll(stocks: List)
-
- @Query("DELETE FROM warehouse_stock")
- suspend fun clearStock()
-}
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/api/DownloadService.kt b/inventory-app/app/src/main/java/com/example/inventory/data/api/DownloadService.kt
new file mode 100644
index 000000000000..f13be3ff6cb8
--- /dev/null
+++ b/inventory-app/app/src/main/java/com/example/inventory/data/api/DownloadService.kt
@@ -0,0 +1,13 @@
+package com.example.inventory.data.api
+
+import okhttp3.ResponseBody
+import retrofit2.Response
+import retrofit2.http.GET
+import retrofit2.http.Streaming
+import retrofit2.http.Url
+
+interface DownloadService {
+ @Streaming
+ @GET
+ suspend fun downloadFile(@Url url: String): Response
+}
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/dao/InventoryDao.kt b/inventory-app/app/src/main/java/com/example/inventory/data/dao/InventoryDao.kt
new file mode 100644
index 000000000000..a35fa88eca52
--- /dev/null
+++ b/inventory-app/app/src/main/java/com/example/inventory/data/dao/InventoryDao.kt
@@ -0,0 +1,42 @@
+package com.example.inventory.data.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Transaction
+import com.example.inventory.data.entity.Item
+import com.example.inventory.data.entity.WarehouseStock
+
+@Dao
+interface InventoryDao {
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertItems(items: List
- ): List
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertStocks(stocks: List)
+
+ @Query("SELECT * FROM items WHERE code = :code LIMIT 1")
+ suspend fun getItemByCode(code: String): Item?
+
+ @Query("SELECT * FROM warehouse_stocks WHERE itemId = :itemId AND quantity > 0")
+ suspend fun getStocksByItemId(itemId: Long): List
+
+ @Query("DELETE FROM items")
+ suspend fun clearAllItems()
+
+ @Query("DELETE FROM warehouse_stocks")
+ suspend fun clearAllStocks()
+
+ @Transaction
+ suspend fun clearAndInsertBatch(items: List
- , stocks: Map>) {
+ // This method is tricky because we need IDs for stocks.
+ // It's better to handle logic in Repository to insert items, get IDs, then insert stocks.
+ // But for batch processing, we might want to do it differently.
+ // Actually, if we use code as a reference in stock it might be easier but requirement says:
+ // "Item (id, code, name, price) and WarehouseStock (itemId, warehouseName, quantity)"
+
+ // So we will just provide basic insert methods and handle logic in repository/usecase.
+ }
+}
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/entity/Item.kt b/inventory-app/app/src/main/java/com/example/inventory/data/entity/Item.kt
new file mode 100644
index 000000000000..0795f2b9876e
--- /dev/null
+++ b/inventory-app/app/src/main/java/com/example/inventory/data/entity/Item.kt
@@ -0,0 +1,17 @@
+package com.example.inventory.data.entity
+
+import androidx.room.Entity
+import androidx.room.Index
+import androidx.room.PrimaryKey
+
+@Entity(
+ tableName = "items",
+ indices = [Index(value = ["code"], unique = true)]
+)
+data class Item(
+ @PrimaryKey(autoGenerate = true)
+ val id: Long = 0,
+ val code: String,
+ val name: String,
+ val price: Double
+)
diff --git a/inventory-app/app/src/main/java/com/example/inventory/data/WarehouseStock.kt b/inventory-app/app/src/main/java/com/example/inventory/data/entity/WarehouseStock.kt
similarity index 66%
rename from inventory-app/app/src/main/java/com/example/inventory/data/WarehouseStock.kt
rename to inventory-app/app/src/main/java/com/example/inventory/data/entity/WarehouseStock.kt
index 92675ba8a977..7222938fba53 100644
--- a/inventory-app/app/src/main/java/com/example/inventory/data/WarehouseStock.kt
+++ b/inventory-app/app/src/main/java/com/example/inventory/data/entity/WarehouseStock.kt
@@ -1,12 +1,12 @@
-package com.example.inventory.data
+package com.example.inventory.data.entity
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
+import androidx.room.PrimaryKey
@Entity(
- tableName = "warehouse_stock",
- primaryKeys = ["itemId", "warehouseName"],
+ tableName = "warehouse_stocks",
foreignKeys = [
ForeignKey(
entity = Item::class,
@@ -15,9 +15,11 @@ import androidx.room.Index
onDelete = ForeignKey.CASCADE
)
],
- indices = [Index("itemId"), Index("warehouseName")]
+ indices = [Index(value = ["itemId"])]
)
data class WarehouseStock(
+ @PrimaryKey(autoGenerate = true)
+ val id: Long = 0,
val itemId: Long,
val warehouseName: String,
val quantity: Int
diff --git a/inventory-app/app/src/main/java/com/example/inventory/di/DatabaseModule.kt b/inventory-app/app/src/main/java/com/example/inventory/di/DatabaseModule.kt
new file mode 100644
index 000000000000..dfab6a2a1dee
--- /dev/null
+++ b/inventory-app/app/src/main/java/com/example/inventory/di/DatabaseModule.kt
@@ -0,0 +1,32 @@
+package com.example.inventory.di
+
+import android.content.Context
+import androidx.room.Room
+import com.example.inventory.data.AppDatabase
+import com.example.inventory.data.dao.InventoryDao
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.qualifiers.ApplicationContext
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Module
+@InstallIn(SingletonComponent::class)
+object DatabaseModule {
+
+ @Provides
+ @Singleton
+ fun provideDatabase(@ApplicationContext context: Context): AppDatabase {
+ return Room.databaseBuilder(
+ context,
+ AppDatabase::class.java,
+ "inventory_db"
+ ).fallbackToDestructiveMigration().build()
+ }
+
+ @Provides
+ fun provideInventoryDao(database: AppDatabase): InventoryDao {
+ return database.inventoryDao()
+ }
+}
diff --git a/inventory-app/app/src/main/java/com/example/inventory/repository/InventoryRepository.kt b/inventory-app/app/src/main/java/com/example/inventory/repository/InventoryRepository.kt
index 44c540fc6d1d..7a546197b07f 100644
--- a/inventory-app/app/src/main/java/com/example/inventory/repository/InventoryRepository.kt
+++ b/inventory-app/app/src/main/java/com/example/inventory/repository/InventoryRepository.kt
@@ -1,118 +1,90 @@
package com.example.inventory.repository
-import com.example.inventory.data.AppDatabase
-import com.example.inventory.data.Item
-import com.example.inventory.data.ItemWithStock
-import com.example.inventory.data.WarehouseStock
-import kotlinx.coroutines.CoroutineDispatcher
+import com.example.inventory.data.api.DownloadService
+import com.example.inventory.data.dao.InventoryDao
+import com.example.inventory.data.entity.Item
+import com.example.inventory.data.entity.WarehouseStock
+import com.example.inventory.util.ExcelParser
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.withContext
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import org.apache.poi.ss.usermodel.WorkbookFactory
-import java.io.File
-import java.io.FileInputStream
-
-data class PendingStock(
- val itemIndex: Int,
- val warehouseName: String,
- val quantity: Int
-)
-
-class InventoryRepository(
- private val db: AppDatabase,
- private val okHttpClient: OkHttpClient,
- private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOn
+import okhttp3.ResponseBody
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import java.io.InputStream
+import javax.inject.Inject
+
+class InventoryRepository @Inject constructor(
+ private val inventoryDao: InventoryDao
) {
-
- private val _importProgress = MutableStateFlow(0)
- val importProgress: StateFlow = _importProgress.asStateFlow()
-
- suspend fun downloadAndImport(url: String) = withContext(ioDispatcher) {
- val tempFile = File.createTempFile("inventory", ".xlsx")
- okHttpClient.newCall(Request.Builder().url(url).build()).execute().use { resp ->
- resp.body?.byteStream()?.use { input ->
- tempFile.outputStream().use { output -> input.copyTo(output) }
- }
+ // Ideally, injected via Hilt
+ private val retrofit = Retrofit.Builder()
+ .baseUrl("https://google.com/") // Placeholder, URL will be dynamic
+ .addConverterFactory(GsonConverterFactory.create())
+ .build()
+
+ private val downloadService = retrofit.create(DownloadService::class.java)
+ private val parser = ExcelParser()
+
+ fun getItemByCode(code: String): Flow
- = flow {
+ emit(inventoryDao.getItemByCode(code))
+ }.flowOn(Dispatchers.IO)
+
+ fun getStocksByItemId(itemId: Long): Flow
> = flow {
+ emit(inventoryDao.getStocksByItemId(itemId))
+ }.flowOn(Dispatchers.IO)
+
+ suspend fun downloadAndProcessExcel(url: String, onProgress: (String) -> Unit) {
+ // 1. Download
+ onProgress("Downloading...")
+ // For dynamic URL with retrofit, we can just pass the full URL to the @Url parameter
+ // The base URL doesn't matter much if we use @Url
+ val response = downloadService.downloadFile(url)
+ val body = response.body()
+
+ if (!response.isSuccessful || body == null) {
+ throw Exception("Download failed: ${response.code()}")
}
- importExcel(tempFile)
- }
-
- private suspend fun importExcel(file: File) = withContext(ioDispatcher) {
- db.withTransaction {
- db.itemDao().clearItems()
- db.warehouseStockDao().clearStock()
- }
-
- FileInputStream(file).use { fis ->
- val workbook = WorkbookFactory.create(fis)
- val sheet = workbook.getSheetAt(0)
- val totalRows = sheet.lastRowNum
- if (totalRows == 0) return@use
-
- val headerRow = sheet.getRow(0)
- val headers = headerRow.map { it.stringCellValue.trim() }
- val warehouseCols = headers.drop(3)
-
- val batchItems = mutableListOf- ()
- val pendingStocks = mutableListOf()
- var processed = 0
- for (rowIndex in 1..totalRows) {
- val row = sheet.getRow(rowIndex) ?: continue
- val code = row.getCell(0)?.stringCellValue.orEmpty()
- val name = row.getCell(1)?.stringCellValue.orEmpty()
- val price = row.getCell(2)?.numericCellValue ?: 0.0
-
- val itemIndex = batchItems.size
- batchItems.add(Item(code = code, name = name, price = price))
-
- warehouseCols.forEachIndexed { idx, warehouseName ->
- val qty = row.getCell(3 + idx)?.numericCellValue?.toInt() ?: 0
- if (qty > 0) {
- pendingStocks.add(PendingStock(itemIndex, warehouseName, qty))
- }
- }
-
- if (batchItems.size >= 500) {
- persistBatch(batchItems, pendingStocks)
- processed += batchItems.size
- batchItems.clear()
- pendingStocks.clear()
- _importProgress.value = ((processed / totalRows.toFloat()) * 100).toInt().coerceAtMost(99)
+ // 2. Parse and Insert
+ onProgress("Processing...")
+ val inputStream: InputStream = body.byteStream()
+
+ // Clear old data? Requirement implies inventory update.
+ // Strategy: Clear all before load or Update?
+ // Usually full replace for "Import".
+ inventoryDao.clearAllStocks()
+ inventoryDao.clearAllItems()
+
+ var count = 0
+ parser.parseSuspending(inputStream) { batch ->
+ // Batch is List
+ val items = batch.map { it.item }
+
+ // Insert Items
+ val insertedIds = inventoryDao.insertItems(items)
+
+ // Prepare Stocks with correct ItemIDs
+ val stocks = mutableListOf()
+ batch.forEachIndexed { index, parsedData ->
+ val itemId = insertedIds[index] // Assuming ordered return match ordered insert
+ parsedData.stocks.forEach { dummy ->
+ stocks.add(WarehouseStock(
+ itemId = itemId,
+ warehouseName = dummy.warehouseName,
+ quantity = dummy.quantity
+ ))
}
}
- if (batchItems.isNotEmpty()) {
- persistBatch(batchItems, pendingStocks)
- processed += batchItems.size
- }
- _importProgress.value = 100
- workbook.close()
- }
- }
+ // Insert Stocks
+ inventoryDao.insertStocks(stocks)
- private suspend fun persistBatch(
- items: List
- ,
- pendingStocks: List
- ) {
- db.withTransaction {
- val ids = db.itemDao().insertItems(items)
- val idMap = ids.withIndex().associate { (index, id) -> index to id }
- val stocks = pendingStocks.mapNotNull { pending ->
- val itemId = idMap[pending.itemIndex] ?: return@mapNotNull null
- WarehouseStock(itemId = itemId, warehouseName = pending.warehouseName, quantity = pending.quantity)
- }
- if (stocks.isNotEmpty()) {
- db.warehouseStockDao().insertAll(stocks)
- }
+ count += batch.size
+ onProgress("Processed $count records...")
}
- }
- suspend fun searchByCode(code: String): ItemWithStock? = withContext(ioDispatcher) {
- db.itemDao().findWithStock(code.trim())
+ onProgress("Completed! Total: $count")
}
}
diff --git a/inventory-app/app/src/main/java/com/example/inventory/ui/InventoryViewModel.kt b/inventory-app/app/src/main/java/com/example/inventory/ui/InventoryViewModel.kt
deleted file mode 100644
index a8fa3033c0f5..000000000000
--- a/inventory-app/app/src/main/java/com/example/inventory/ui/InventoryViewModel.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.example.inventory.ui
-
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import com.example.inventory.data.ItemWithStock
-import com.example.inventory.repository.InventoryRepository
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.launch
-
-class InventoryViewModel(
- private val repository: InventoryRepository,
- private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
-) : ViewModel() {
-
- val importProgress: StateFlow = repository.importProgress
-
- private val _searchResult = MutableStateFlow(null)
- val searchResult: StateFlow = _searchResult.asStateFlow()
-
- fun import(url: String) {
- viewModelScope.launch {
- repository.downloadAndImport(url)
- }
- }
-
- fun search(code: String) {
- viewModelScope.launch(ioDispatcher) {
- _searchResult.value = repository.searchByCode(code)
- }
- }
-}
diff --git a/inventory-app/app/src/main/java/com/example/inventory/ui/MainActivity.kt b/inventory-app/app/src/main/java/com/example/inventory/ui/MainActivity.kt
deleted file mode 100644
index 82dd48560e6d..000000000000
--- a/inventory-app/app/src/main/java/com/example/inventory/ui/MainActivity.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.example.inventory.ui
-
-import android.os.Bundle
-import android.view.View
-import android.widget.Button
-import android.widget.EditText
-import android.widget.ProgressBar
-import android.widget.TextView
-import androidx.activity.ComponentActivity
-import androidx.activity.viewModels
-import androidx.appcompat.app.AlertDialog
-import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.ViewModelProvider
-import androidx.room.Room
-import com.example.inventory.R
-import com.example.inventory.data.AppDatabase
-import com.example.inventory.data.WarehouseStock
-import com.example.inventory.repository.InventoryRepository
-import com.journeyapps.barcodescanner.ScanContract
-import com.journeyapps.barcodescanner.ScanOptions
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-
-class MainActivity : ComponentActivity() {
-
- private val viewModel: InventoryViewModel by viewModels {
- object : ViewModelProvider.Factory {
- override fun create(modelClass: Class): T {
- val db = Room.databaseBuilder(
- applicationContext,
- AppDatabase::class.java,
- "inventory-db"
- ).fallbackToDestructiveMigration().build()
- val repo = InventoryRepository(db, OkHttpClient())
- @Suppress("UNCHECKED_CAST")
- return InventoryViewModel(repo) as T
- }
- }
- }
-
- private lateinit var etCode: EditText
- private lateinit var tvResult: TextView
- private lateinit var btnShowStock: Button
- private lateinit var progressBar: ProgressBar
-
- private val barcodeLauncher = registerForActivityResult(ScanContract()) { result ->
- result.contents?.let {
- etCode.setText(it)
- viewModel.search(it)
- }
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
-
- etCode = findViewById(R.id.etCode)
- tvResult = findViewById(R.id.tvResult)
- btnShowStock = findViewById(R.id.btnShowStock)
- progressBar = findViewById(R.id.progressImport)
-
- findViewById