refactored for work with multiple databases. Didn't test yet
This commit is contained in:
		@@ -6,7 +6,11 @@ import android.database.DatabaseUtils
 | 
			
		||||
import android.database.sqlite.SQLiteDatabase
 | 
			
		||||
import android.database.sqlite.SQLiteOpenHelper
 | 
			
		||||
import android.provider.BaseColumns
 | 
			
		||||
import android.widget.Toast
 | 
			
		||||
import androidx.security.crypto.EncryptedSharedPreferences
 | 
			
		||||
import androidx.security.crypto.MasterKeys
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.dataclasses.Category
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.dataclasses.Product
 | 
			
		||||
import java.io.File
 | 
			
		||||
 | 
			
		||||
@@ -51,20 +55,27 @@ const val SQL_CREATE_ABSTRACT_PRODUCTS_TABLE =
 | 
			
		||||
 | 
			
		||||
const val SQL_CREATE_PRODUCTS_TABLE =
 | 
			
		||||
    "CREATE TABLE ${ProductContract.ProductEntry.TABLE_NAME} (" +
 | 
			
		||||
        "${BaseColumns._ID} INTEGER PRIMARY KEY," +
 | 
			
		||||
        "${ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID} INTEGER," +
 | 
			
		||||
        "${ProductContract.ProductEntry.AMOUNT} INTEGER," +
 | 
			
		||||
        "${ProductContract.ProductEntry.DATE_OF_PRODUCTION} INTEGER," +
 | 
			
		||||
        "${ProductContract.ProductEntry.EXPIRY_DATE} INTGER)"
 | 
			
		||||
            "${BaseColumns._ID} INTEGER PRIMARY KEY," +
 | 
			
		||||
            "${ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID} INTEGER," +
 | 
			
		||||
            "${ProductContract.ProductEntry.AMOUNT} INTEGER," +
 | 
			
		||||
            "${ProductContract.ProductEntry.DATE_OF_PRODUCTION} INTEGER," +
 | 
			
		||||
            "${ProductContract.ProductEntry.EXPIRY_DATE} INTGER)"
 | 
			
		||||
 | 
			
		||||
const val SQL_CREATE_CATEGORIES_TABLE =
 | 
			
		||||
    "CREATE TABLE ${CategoriesContract.CategoryEntry.TABLE_NAME} (" +
 | 
			
		||||
            "${BaseColumns._ID} INTEGER PRIMARY KEY," +
 | 
			
		||||
            "${CategoriesContract.CategoryEntry.CATEGORY_NAME} TEXT)"
 | 
			
		||||
 | 
			
		||||
class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
 | 
			
		||||
class DBStorageController(context: Context, dbname: String) :
 | 
			
		||||
    SQLiteOpenHelper(context, dbname, null, DATABASE_VERSION) {
 | 
			
		||||
 | 
			
		||||
    private lateinit var dbname: String
 | 
			
		||||
    private lateinit var db: SQLiteDatabase
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(db: SQLiteDatabase) {
 | 
			
		||||
        this.db = db
 | 
			
		||||
        DATABASE_NAME = "$dbname.db"
 | 
			
		||||
 | 
			
		||||
        db.execSQL(SQL_CREATE_ABSTRACT_PRODUCTS_TABLE)
 | 
			
		||||
        db.execSQL(SQL_CREATE_PRODUCTS_TABLE)
 | 
			
		||||
        db.execSQL(SQL_CREATE_CATEGORIES_TABLE)
 | 
			
		||||
@@ -74,26 +85,34 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        TODO("Not yet implemented")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun eraseCategory (db: SQLiteDatabase, id: Int, context: Context) {
 | 
			
		||||
        val productsInCategory = getAllAbstractProductInCategory(db, id)
 | 
			
		||||
    fun eraseCategory(id: Int, context: Context) {
 | 
			
		||||
        val productsInCategory = getAllAbstractProductInCategory(id)
 | 
			
		||||
 | 
			
		||||
        for (product in productsInCategory.iterator()) {
 | 
			
		||||
            eraseAbstractProduct(db, product.id, context)
 | 
			
		||||
            eraseAbstractProduct(product.id, context)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.delete(CategoriesContract.CategoryEntry.TABLE_NAME, BaseColumns._ID + "=" + id, null)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getCategoryNameById(db: SQLiteDatabase, id: Int) : String {
 | 
			
		||||
    fun getCategoryNameById(id: Int): String {
 | 
			
		||||
        var result = ""
 | 
			
		||||
 | 
			
		||||
        val projection = arrayOf(CategoriesContract.CategoryEntry.CATEGORY_NAME)
 | 
			
		||||
        val selection = "${BaseColumns._ID} = ?"
 | 
			
		||||
        val selectionArgs = arrayOf(id.toString())
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(CategoriesContract.CategoryEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
 | 
			
		||||
        val cursor = db.query(
 | 
			
		||||
            CategoriesContract.CategoryEntry.TABLE_NAME,
 | 
			
		||||
            projection,
 | 
			
		||||
            selection,
 | 
			
		||||
            selectionArgs,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        with (cursor) {
 | 
			
		||||
        with(cursor) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                result = getString(getColumnIndexOrThrow(CategoriesContract.CategoryEntry.CATEGORY_NAME))
 | 
			
		||||
            }
 | 
			
		||||
@@ -102,7 +121,7 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        return result
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getAllAbstractProductInCategory(db: SQLiteDatabase, id: Int) : List<AbstractProduct> {
 | 
			
		||||
    fun getAllAbstractProductInCategory(id: Int): List<AbstractProduct> {
 | 
			
		||||
 | 
			
		||||
        var result = mutableListOf<AbstractProduct>()
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
@@ -117,18 +136,39 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        val selection = "${AbstractProductContract.AbstractProductEntry.CATEGORY} = ?"
 | 
			
		||||
        val selectionArgs = arrayOf(id.toString())
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(AbstractProductContract.AbstractProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
 | 
			
		||||
        val cursor = db.query(
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.TABLE_NAME,
 | 
			
		||||
            projection,
 | 
			
		||||
            selection,
 | 
			
		||||
            selectionArgs,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        with(cursor) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                val abstractProductId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
			
		||||
                val abstractProductBarcode = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.BARCODE))
 | 
			
		||||
                val abstractProductName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
			
		||||
                val abstractProductNetWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
 | 
			
		||||
                val abstractProductImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
 | 
			
		||||
                val abstractProductUnit = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.UNIT))
 | 
			
		||||
                val abstractProductBarcode =
 | 
			
		||||
                    getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.BARCODE))
 | 
			
		||||
                val abstractProductName =
 | 
			
		||||
                    getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
			
		||||
                val abstractProductNetWeight =
 | 
			
		||||
                    getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
 | 
			
		||||
                val abstractProductImageHash =
 | 
			
		||||
                    getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
 | 
			
		||||
                val abstractProductUnit =
 | 
			
		||||
                    getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.UNIT))
 | 
			
		||||
 | 
			
		||||
                val abstractProduct = AbstractProduct(abstractProductId, abstractProductBarcode, abstractProductName, abstractProductNetWeight, abstractProductImageHash, category = id, abstractProductUnit)
 | 
			
		||||
                val abstractProduct = AbstractProduct(
 | 
			
		||||
                    abstractProductId,
 | 
			
		||||
                    abstractProductBarcode,
 | 
			
		||||
                    abstractProductName,
 | 
			
		||||
                    abstractProductNetWeight,
 | 
			
		||||
                    abstractProductImageHash,
 | 
			
		||||
                    category = id,
 | 
			
		||||
                    abstractProductUnit
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
                result.add(abstractProduct)
 | 
			
		||||
            }
 | 
			
		||||
@@ -137,10 +177,15 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        return result
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getAmountOfAbstractProductsInCategory(db:SQLiteDatabase, id: Int) : Int {
 | 
			
		||||
        return DatabaseUtils.longForQuery(db, "SELECT COUNT(*) FROM ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} WHERE ${AbstractProductContract.AbstractProductEntry.CATEGORY} = ?", arrayOf(id.toString())).toInt()
 | 
			
		||||
    fun getAmountOfAbstractProductsInCategory(id: Int): Int {
 | 
			
		||||
        return DatabaseUtils.longForQuery(
 | 
			
		||||
            db,
 | 
			
		||||
            "SELECT COUNT(*) FROM ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} WHERE ${AbstractProductContract.AbstractProductEntry.CATEGORY} = ?",
 | 
			
		||||
            arrayOf(id.toString())
 | 
			
		||||
        ).toInt()
 | 
			
		||||
    }
 | 
			
		||||
    fun eraseAbstractProduct(db: SQLiteDatabase, id: Int, context: Context) {
 | 
			
		||||
 | 
			
		||||
    fun eraseAbstractProduct(id: Int, context: Context) {
 | 
			
		||||
        val projectionForAbstractProduct = arrayOf(
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME
 | 
			
		||||
        )
 | 
			
		||||
@@ -158,9 +203,10 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        )
 | 
			
		||||
        var imageHash: String = ""
 | 
			
		||||
 | 
			
		||||
        with (cursorForAbstractProduct) {
 | 
			
		||||
            while(moveToNext()) {
 | 
			
		||||
                val productImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
 | 
			
		||||
        with(cursorForAbstractProduct) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                val productImageHash =
 | 
			
		||||
                    getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
 | 
			
		||||
                imageHash = productImageHash
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -174,22 +220,30 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        val selectionForProducts = "${ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID} = ?"
 | 
			
		||||
        val selectionArgsForProducts = arrayOf(id.toString())
 | 
			
		||||
 | 
			
		||||
        val cursorForProducts = db.query(ProductContract.ProductEntry.TABLE_NAME, projectionForProducts, selectionForProducts, selectionArgsForProducts, null, null, null)
 | 
			
		||||
        val cursorForProducts = db.query(
 | 
			
		||||
            ProductContract.ProductEntry.TABLE_NAME,
 | 
			
		||||
            projectionForProducts,
 | 
			
		||||
            selectionForProducts,
 | 
			
		||||
            selectionArgsForProducts,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        with (cursorForProducts) {
 | 
			
		||||
            while(moveToNext()) {
 | 
			
		||||
                eraseProduct(db, getInt(getColumnIndexOrThrow(BaseColumns._ID)))
 | 
			
		||||
        with(cursorForProducts) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                eraseProduct(getInt(getColumnIndexOrThrow(BaseColumns._ID)))
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.delete(AbstractProductContract.AbstractProductEntry.TABLE_NAME, BaseColumns._ID + "=" + id, null)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun eraseProduct(db:SQLiteDatabase, id: Int) {
 | 
			
		||||
    fun eraseProduct(id: Int) {
 | 
			
		||||
        db.delete(ProductContract.ProductEntry.TABLE_NAME, BaseColumns._ID + "=" + id, null)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun insertNewProduct(db: SQLiteDatabase, product: Product) {
 | 
			
		||||
    fun insertNewProduct(product: Product) {
 | 
			
		||||
        val values = ContentValues().apply {
 | 
			
		||||
            put(ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID, product.abstractProductId)
 | 
			
		||||
            put(ProductContract.ProductEntry.AMOUNT, product.amount)
 | 
			
		||||
@@ -200,7 +254,7 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        db.insert(ProductContract.ProductEntry.TABLE_NAME, null, values)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun findAmountOfProductsWithExpiryDate(db: SQLiteDatabase, date: Long): Int {
 | 
			
		||||
    fun findAmountOfProductsWithExpiryDate(date: Long): Int {
 | 
			
		||||
        var amount = 0
 | 
			
		||||
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
@@ -212,7 +266,8 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        val selection = "${ProductContract.ProductEntry.EXPIRY_DATE} = ?"
 | 
			
		||||
        val selectionArgs = arrayOf(date.toString())
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(ProductContract.ProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
 | 
			
		||||
        val cursor =
 | 
			
		||||
            db.query(ProductContract.ProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
 | 
			
		||||
 | 
			
		||||
        with(cursor) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
@@ -223,7 +278,7 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        return amount
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun findAllExpiryDates(db:SQLiteDatabase): Set<Long> {
 | 
			
		||||
    fun findAllExpiryDates(): Set<Long> {
 | 
			
		||||
        val dates: MutableSet<Long> = mutableSetOf<Long>()
 | 
			
		||||
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
@@ -243,7 +298,7 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        return dates
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun findAbstractProductByBarcode (db: SQLiteDatabase, barcode: String) : AbstractProduct? {
 | 
			
		||||
    fun findAbstractProductByBarcode(barcode: String): AbstractProduct? {
 | 
			
		||||
        var abstractProduct: AbstractProduct? = null
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
            BaseColumns._ID,
 | 
			
		||||
@@ -257,14 +312,25 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        val selection = "${AbstractProductContract.AbstractProductEntry.BARCODE} = ?"
 | 
			
		||||
        val selectionArgs = arrayOf(barcode)
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(AbstractProductContract.AbstractProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
 | 
			
		||||
        val cursor = db.query(
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.TABLE_NAME,
 | 
			
		||||
            projection,
 | 
			
		||||
            selection,
 | 
			
		||||
            selectionArgs,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        with(cursor) {
 | 
			
		||||
            while(moveToNext()) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                val id = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
			
		||||
                val productName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
			
		||||
                val imageFilename = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
 | 
			
		||||
                val netWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
 | 
			
		||||
                val productName =
 | 
			
		||||
                    getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
			
		||||
                val imageFilename =
 | 
			
		||||
                    getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
 | 
			
		||||
                val netWeight =
 | 
			
		||||
                    getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
 | 
			
		||||
                val category = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.CATEGORY))
 | 
			
		||||
                val unit = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.UNIT))
 | 
			
		||||
 | 
			
		||||
@@ -275,7 +341,7 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        return abstractProduct
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun findAbstractProductById(db: SQLiteDatabase, id: Int): AbstractProduct? {
 | 
			
		||||
    fun findAbstractProductById(id: Int): AbstractProduct? {
 | 
			
		||||
        var abstractProduct: AbstractProduct? = null
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
            BaseColumns._ID,
 | 
			
		||||
@@ -290,15 +356,25 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        val selection = "${BaseColumns._ID} = ?"
 | 
			
		||||
        val selectionArgs = arrayOf(id.toString())
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(AbstractProductContract.AbstractProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
 | 
			
		||||
        val cursor = db.query(
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.TABLE_NAME,
 | 
			
		||||
            projection,
 | 
			
		||||
            selection,
 | 
			
		||||
            selectionArgs,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        with (cursor) {
 | 
			
		||||
        with(cursor) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
			
		||||
                val barcode = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.BARCODE))
 | 
			
		||||
                val name = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
			
		||||
                val netWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
 | 
			
		||||
                val imageHash = getString((getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME)))
 | 
			
		||||
                val netWeight =
 | 
			
		||||
                    getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
 | 
			
		||||
                val imageHash =
 | 
			
		||||
                    getString((getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME)))
 | 
			
		||||
                val category = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.CATEGORY))
 | 
			
		||||
                val unit = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.UNIT))
 | 
			
		||||
 | 
			
		||||
@@ -309,18 +385,246 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
 | 
			
		||||
        return abstractProduct
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun updateProduct(db: SQLiteDatabase, product: Product) {
 | 
			
		||||
    fun updateProduct(product: Product) {
 | 
			
		||||
        val values = ContentValues().apply {
 | 
			
		||||
            put(ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID, product.abstractProductId)
 | 
			
		||||
            put(ProductContract.ProductEntry.AMOUNT, product.amount)
 | 
			
		||||
            put(ProductContract.ProductEntry.DATE_OF_PRODUCTION, product.dateOfProduction)
 | 
			
		||||
            put(ProductContract.ProductEntry.EXPIRY_DATE, product.dateOfExpiry)
 | 
			
		||||
        }
 | 
			
		||||
        db.update(ProductContract.ProductEntry.TABLE_NAME, values, "${BaseColumns._ID} = ?", arrayOf(product.id.toString()))
 | 
			
		||||
        db.update(
 | 
			
		||||
            ProductContract.ProductEntry.TABLE_NAME,
 | 
			
		||||
            values,
 | 
			
		||||
            "${BaseColumns._ID} = ?",
 | 
			
		||||
            arrayOf(product.id.toString())
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addAbstractProduct(abstractProduct: AbstractProduct, context: Context) {
 | 
			
		||||
        val values = ContentValues().apply {
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.BARCODE, abstractProduct.barcode)
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME, abstractProduct.name)
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT, abstractProduct.netWeight.toString())
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME, abstractProduct.imageHash)
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.CATEGORY, abstractProduct.category)
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.UNIT, abstractProduct.unit)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val id = db.insert(AbstractProductContract.AbstractProductEntry.TABLE_NAME, null, values)
 | 
			
		||||
        val n = Net()
 | 
			
		||||
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
 | 
			
		||||
 | 
			
		||||
        val sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            masterKeyAlias,
 | 
			
		||||
            context,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        n.language = sharedPreferences.getString("language", "en-US")!!
 | 
			
		||||
        n.server = sharedPreferences.getString("server", "")!!
 | 
			
		||||
        n.token = sharedPreferences.getString("token", "")!!
 | 
			
		||||
        val pictureFile = File(File(context.filesDir, "pictures"), "${abstractProduct.imageHash}.png")
 | 
			
		||||
        val response = n.uploadAbstractProduct(1, abstractProduct, pictureFile);
 | 
			
		||||
 | 
			
		||||
        Toast.makeText(context, response.body!!.string(), Toast.LENGTH_LONG).show()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun updateAbstractProduct(abstractProduct: AbstractProduct, context: Context) {
 | 
			
		||||
        val values = ContentValues().apply {
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.BARCODE, abstractProduct.barcode)
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME, abstractProduct.name)
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT, abstractProduct.netWeight.toString())
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME, abstractProduct.imageHash)
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.CATEGORY, abstractProduct.category)
 | 
			
		||||
            put(AbstractProductContract.AbstractProductEntry.UNIT, abstractProduct.unit)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.update(
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.TABLE_NAME,
 | 
			
		||||
            values,
 | 
			
		||||
            "${BaseColumns._ID} = ?",
 | 
			
		||||
            arrayOf(abstractProduct.id.toString())
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getAllCategories(): List<Category> {
 | 
			
		||||
        val categories = mutableListOf<Category>()
 | 
			
		||||
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
            CategoriesContract.CategoryEntry.CATEGORY_NAME
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(
 | 
			
		||||
            CategoriesContract.CategoryEntry.TABLE_NAME,
 | 
			
		||||
            projection,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            BaseColumns._ID + " ASC"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        with(cursor) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                val category = Category(
 | 
			
		||||
                    getInt(getColumnIndexOrThrow(BaseColumns._ID)),
 | 
			
		||||
                    getString(getColumnIndexOrThrow(CategoriesContract.CategoryEntry.CATEGORY_NAME))
 | 
			
		||||
                )
 | 
			
		||||
                categories.add(category)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return categories
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addCategory(category: Category) {
 | 
			
		||||
        val values = ContentValues().apply {
 | 
			
		||||
            put(CategoriesContract.CategoryEntry.CATEGORY_NAME, category.name)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.insert(CategoriesContract.CategoryEntry.TABLE_NAME, null, values)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun updateCategory(category: Category) {
 | 
			
		||||
        val values = ContentValues().apply {
 | 
			
		||||
            put(CategoriesContract.CategoryEntry.CATEGORY_NAME, category.name)
 | 
			
		||||
        }
 | 
			
		||||
        db.update(CategoriesContract.CategoryEntry.TABLE_NAME, values, "${BaseColumns._ID} = ?", arrayOf(category.id.toString()))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getSortedListOfProducts(selectedSort: Int, filterBy: String, filter: String): List<Product> {
 | 
			
		||||
        val products = mutableListOf<Product>()
 | 
			
		||||
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
            BaseColumns._ID,
 | 
			
		||||
            ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID,
 | 
			
		||||
            ProductContract.ProductEntry.AMOUNT,
 | 
			
		||||
            ProductContract.ProductEntry.DATE_OF_PRODUCTION,
 | 
			
		||||
            ProductContract.ProductEntry.EXPIRY_DATE,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        var orderBy: String = ""
 | 
			
		||||
 | 
			
		||||
        when (selectedSort) {
 | 
			
		||||
            0 -> {
 | 
			
		||||
                orderBy =
 | 
			
		||||
                    "(SELECT ${AbstractProductContract.AbstractProductEntry.PRODUCT_NAME} FROM ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} WHERE ${BaseColumns._ID} = ${ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID}) ASC"
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            1 -> {
 | 
			
		||||
                orderBy =
 | 
			
		||||
                    "(SELECT ${AbstractProductContract.AbstractProductEntry.CATEGORY} FROM ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} WHERE ${BaseColumns._ID} = ${ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID}) ASC"
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            3 -> {
 | 
			
		||||
                orderBy = "${ProductContract.ProductEntry.DATE_OF_PRODUCTION} ASC"
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            4 -> {
 | 
			
		||||
                orderBy = "${ProductContract.ProductEntry.EXPIRY_DATE} ASC"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var selection: String? = null
 | 
			
		||||
        var selectionArgs: Array<String>? = null
 | 
			
		||||
 | 
			
		||||
        when (filterBy) {
 | 
			
		||||
            "expiryDate" -> {
 | 
			
		||||
                selection = "${ProductContract.ProductEntry.EXPIRY_DATE} = ?"
 | 
			
		||||
                selectionArgs = arrayOf(filter)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            "" -> {}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(ProductContract.ProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, orderBy)
 | 
			
		||||
 | 
			
		||||
        with(cursor) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
			
		||||
                val abstractProductId =
 | 
			
		||||
                    getInt(getColumnIndexOrThrow(ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID))
 | 
			
		||||
                val amount = getInt(getColumnIndexOrThrow(ProductContract.ProductEntry.AMOUNT))
 | 
			
		||||
                val dateOfProduction =
 | 
			
		||||
                    getLong(getColumnIndexOrThrow(ProductContract.ProductEntry.DATE_OF_PRODUCTION))
 | 
			
		||||
                val dateOfExpiry = getLong(getColumnIndexOrThrow(ProductContract.ProductEntry.EXPIRY_DATE))
 | 
			
		||||
 | 
			
		||||
                val product = Product(productId, abstractProductId, amount, dateOfProduction, dateOfExpiry)
 | 
			
		||||
 | 
			
		||||
                if (selectedSort == 2) { //freshness
 | 
			
		||||
                    products.add(product)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        products.sortWith(compareByDescending { it.freshness })
 | 
			
		||||
 | 
			
		||||
        return products
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getSortedListOfAbstractProducts(selectedSort: Int, filterBy: String, filter: Array<String>): List<AbstractProduct> {
 | 
			
		||||
 | 
			
		||||
        val abstractProducts = mutableListOf<AbstractProduct>()
 | 
			
		||||
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
            BaseColumns._ID,
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.BARCODE,
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.PRODUCT_NAME,
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT,
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME,
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.CATEGORY,
 | 
			
		||||
            AbstractProductContract.AbstractProductEntry.UNIT
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        var orderBy: String = ""
 | 
			
		||||
        when(selectedSort) {
 | 
			
		||||
            0 -> {
 | 
			
		||||
                orderBy = "${AbstractProductContract.AbstractProductEntry.PRODUCT_NAME} ASC"
 | 
			
		||||
            }
 | 
			
		||||
            1 -> {
 | 
			
		||||
                orderBy = "${AbstractProductContract.AbstractProductEntry.CATEGORY} ASC"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var selection = ""
 | 
			
		||||
        var selectionArgs: Array<String>? = null
 | 
			
		||||
 | 
			
		||||
        when (filterBy) {
 | 
			
		||||
            "category" -> {
 | 
			
		||||
                selection = "${AbstractProductContract.AbstractProductEntry.CATEGORY} = ?"
 | 
			
		||||
                selectionArgs = filter
 | 
			
		||||
            }
 | 
			
		||||
            "barcodeless" -> {
 | 
			
		||||
                selection = "${AbstractProductContract.AbstractProductEntry.BARCODE} = '' "
 | 
			
		||||
                selectionArgs = null
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(AbstractProductContract.AbstractProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, orderBy)
 | 
			
		||||
 | 
			
		||||
        with (cursor) {
 | 
			
		||||
            while(moveToNext()) {
 | 
			
		||||
                val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
			
		||||
                val barcode = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.BARCODE))
 | 
			
		||||
                val productName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
			
		||||
                val netWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
 | 
			
		||||
                val productImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
 | 
			
		||||
                val category = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.CATEGORY))
 | 
			
		||||
                val unit = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.UNIT))
 | 
			
		||||
 | 
			
		||||
                val product = AbstractProduct(productId, barcode, productName, netWeight, productImageHash, category, unit)
 | 
			
		||||
 | 
			
		||||
                abstractProducts.add(product)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return  abstractProducts
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val DATABASE_VERSION = 1
 | 
			
		||||
        const val DATABASE_NAME = "database.db"
 | 
			
		||||
        var DATABASE_NAME = "database.db"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,10 @@
 | 
			
		||||
package org.foxarmy.barcodescannerforemployees.activities
 | 
			
		||||
 | 
			
		||||
import android.content.ContentValues
 | 
			
		||||
import android.content.DialogInterface
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.provider.BaseColumns
 | 
			
		||||
import android.util.Log
 | 
			
		||||
import android.widget.*
 | 
			
		||||
import androidx.activity.result.contract.ActivityResultContracts
 | 
			
		||||
@@ -49,11 +48,23 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
    private var scanningBarcode = false
 | 
			
		||||
 | 
			
		||||
    private lateinit var db: DBStorageController
 | 
			
		||||
    private lateinit var sharedPreferences: SharedPreferences
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        setContentView(R.layout.fragment_add_abstract_product)
 | 
			
		||||
 | 
			
		||||
        sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        db = DBStorageController(this, sharedPreferences.getString("currentGroup", "database")!!)
 | 
			
		||||
 | 
			
		||||
        picturesPath = File(filesDir, "pictures")
 | 
			
		||||
        val thumbnailsDir = File(cacheDir, "thumbnails")
 | 
			
		||||
@@ -92,6 +103,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
			
		||||
            "update" -> {
 | 
			
		||||
                abstractProduct = extras.get("abstractProduct") as AbstractProduct?
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            "new_from_barcode" -> {
 | 
			
		||||
                abstractProduct = extras.get("abstractProduct") as AbstractProduct?
 | 
			
		||||
                barcode = abstractProduct!!.barcode
 | 
			
		||||
@@ -131,43 +143,10 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
			
		||||
                Toast.makeText(this, getString(R.string.product_net_weight_request), Toast.LENGTH_SHORT).show()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val db = DBStorageController(this).writableDatabase
 | 
			
		||||
            val values = ContentValues().apply {
 | 
			
		||||
                put(AbstractProductContract.AbstractProductEntry.BARCODE, barcode)
 | 
			
		||||
                put(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME, productName)
 | 
			
		||||
                put(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
 | 
			
		||||
                put(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension)
 | 
			
		||||
                put(AbstractProductContract.AbstractProductEntry.CATEGORY, categorySpinner.selectedItemPosition)
 | 
			
		||||
                put(AbstractProductContract.AbstractProductEntry.UNIT, unitTypeSpinner.selectedItemPosition)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (action == "update") {
 | 
			
		||||
                db.update(
 | 
			
		||||
                    AbstractProductContract.AbstractProductEntry.TABLE_NAME,
 | 
			
		||||
                    values,
 | 
			
		||||
                    "${BaseColumns._ID} = ?",
 | 
			
		||||
                    arrayOf(abstractProduct!!.id.toString())
 | 
			
		||||
                )
 | 
			
		||||
            } else if (action == "new" || action == "new_from_barcode"){
 | 
			
		||||
                val id = db.insert(AbstractProductContract.AbstractProductEntry.TABLE_NAME, null, values)
 | 
			
		||||
                val n = Net()
 | 
			
		||||
                val abstractProduct = AbstractProduct(id.toInt(), barcode, productName, netWeight.toString().toDouble(), pictureFile.nameWithoutExtension, categorySpinner.selectedItemPosition, unitTypeSpinner.selectedItemPosition)
 | 
			
		||||
                val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
 | 
			
		||||
 | 
			
		||||
                val sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
                    "sensitive",
 | 
			
		||||
                    masterKeyAlias,
 | 
			
		||||
                    applicationContext,
 | 
			
		||||
                    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
                    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
                n.language = sharedPreferences.getString("language", "en-US")!!
 | 
			
		||||
                n.server = sharedPreferences.getString("server", "")!!
 | 
			
		||||
                n.token = sharedPreferences.getString("token", "")!!
 | 
			
		||||
                val response = n.uploadAbstractProduct(1, abstractProduct, File(pictureFile.absolutePath));
 | 
			
		||||
 | 
			
		||||
                Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
 | 
			
		||||
                db.updateAbstractProduct(abstractProduct!!, this)
 | 
			
		||||
            } else if (action == "new" || action == "new_from_barcode") {
 | 
			
		||||
                db.addAbstractProduct(abstractProduct!!, this)
 | 
			
		||||
            }
 | 
			
		||||
            finish()
 | 
			
		||||
        }
 | 
			
		||||
@@ -190,11 +169,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
        var abstractProduct: AbstractProduct
 | 
			
		||||
 | 
			
		||||
        if (DBStorageController(this).findAbstractProductByBarcode(
 | 
			
		||||
                DBStorageController(this).readableDatabase,
 | 
			
		||||
                this.barcode
 | 
			
		||||
            ) != null
 | 
			
		||||
        ) {
 | 
			
		||||
        if (db.findAbstractProductByBarcode(this.barcode) != null) {
 | 
			
		||||
            AlertDialog.Builder(this)
 | 
			
		||||
                .setMessage(getString(R.string.abstract_product_already_exists))
 | 
			
		||||
                .setPositiveButton(getString(R.string.quit)) { _: DialogInterface, _: Int ->
 | 
			
		||||
@@ -203,10 +178,8 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
			
		||||
                .setNegativeButton(getString(R.string.edit_existing)) { _: DialogInterface, _: Int ->
 | 
			
		||||
                    val addProductIntent = Intent(this, AddAbstractProductActivity::class.java)
 | 
			
		||||
                    val extras = Bundle()
 | 
			
		||||
                    val existingAbstractProduct = DBStorageController(this).findAbstractProductByBarcode(
 | 
			
		||||
                        DBStorageController(this).readableDatabase,
 | 
			
		||||
                        this.barcode
 | 
			
		||||
                    )
 | 
			
		||||
                    val existingAbstractProduct = db.findAbstractProductByBarcode(this.barcode)
 | 
			
		||||
 | 
			
		||||
                    extras.putParcelable("abstractProduct", existingAbstractProduct)
 | 
			
		||||
                    addProductIntent.putExtras(extras)
 | 
			
		||||
                    ContextCompat.startActivity(this, addProductIntent, extras)
 | 
			
		||||
@@ -243,40 +216,17 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
			
		||||
            getString(R.string.pieces)
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        val arrayAdapter =
 | 
			
		||||
            ArrayAdapter<String>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, units)
 | 
			
		||||
            ArrayAdapter(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, units)
 | 
			
		||||
        arrayAdapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
 | 
			
		||||
        unitTypeSpinner.adapter = arrayAdapter
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fillupCategorySpinner() {
 | 
			
		||||
        val db = DBStorageController(this).readableDatabase
 | 
			
		||||
 | 
			
		||||
        val categories = mutableListOf("")
 | 
			
		||||
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
            CategoriesContract.CategoryEntry.CATEGORY_NAME
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(
 | 
			
		||||
            CategoriesContract.CategoryEntry.TABLE_NAME,
 | 
			
		||||
            projection,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
            BaseColumns._ID + " ASC"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        with(cursor) {
 | 
			
		||||
            while (moveToNext()) {
 | 
			
		||||
                categories.add(getString(getColumnIndexOrThrow(CategoriesContract.CategoryEntry.CATEGORY_NAME)))
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        val categories = db.getAllCategories().map { category -> category.name }
 | 
			
		||||
 | 
			
		||||
        val arrayAdapter =
 | 
			
		||||
            ArrayAdapter<String>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, categories)
 | 
			
		||||
            ArrayAdapter(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, categories)
 | 
			
		||||
        arrayAdapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
 | 
			
		||||
        categorySpinner.adapter = arrayAdapter
 | 
			
		||||
    }
 | 
			
		||||
@@ -322,7 +272,8 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
			
		||||
                    getPicture()
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                Toast.makeText(this, getString(R.string.camera_permission_for_picture_request), Toast.LENGTH_LONG).show()
 | 
			
		||||
                Toast.makeText(this, getString(R.string.camera_permission_for_picture_request), Toast.LENGTH_LONG)
 | 
			
		||||
                    .show()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -339,6 +290,12 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
 | 
			
		||||
        db.close()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun prepareBarcodeScanner() {
 | 
			
		||||
        val options = ScanOptions()
 | 
			
		||||
        options.setDesiredBarcodeFormats(ScanOptions.EAN_13)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,37 @@
 | 
			
		||||
package org.foxarmy.barcodescannerforemployees.activities
 | 
			
		||||
 | 
			
		||||
import android.app.Activity
 | 
			
		||||
import android.content.ContentValues
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.provider.BaseColumns
 | 
			
		||||
import android.widget.Button
 | 
			
		||||
import android.widget.EditText
 | 
			
		||||
import android.widget.Toast
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.CategoriesContract
 | 
			
		||||
import androidx.security.crypto.EncryptedSharedPreferences
 | 
			
		||||
import androidx.security.crypto.MasterKeys
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.R
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.dataclasses.Category
 | 
			
		||||
 | 
			
		||||
class AddCategoryActivity : Activity() {
 | 
			
		||||
 | 
			
		||||
    private lateinit var db: DBStorageController
 | 
			
		||||
    private lateinit var sharedPreferences: SharedPreferences
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        setContentView(R.layout.activity_add_category)
 | 
			
		||||
 | 
			
		||||
        sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        db = DBStorageController(this, sharedPreferences.getString("currentGroup", "database")!!)
 | 
			
		||||
 | 
			
		||||
        val extras = intent.extras
 | 
			
		||||
        val category = extras!!.get("category") as Category?
 | 
			
		||||
 | 
			
		||||
@@ -26,27 +40,24 @@ class AddCategoryActivity : Activity() {
 | 
			
		||||
        categoryNameTextEdit.setText(category!!.name)
 | 
			
		||||
 | 
			
		||||
        findViewById<Button>(R.id.saveButton).setOnClickListener {
 | 
			
		||||
            val db = DBStorageController(this).writableDatabase
 | 
			
		||||
 | 
			
		||||
            if (categoryNameTextEdit.text.toString() == "") {
 | 
			
		||||
                Toast.makeText(this, getString(R.string.category_name_required), Toast.LENGTH_SHORT).show()
 | 
			
		||||
                return@setOnClickListener
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (category.id == 0) { // Inserting new category
 | 
			
		||||
                val values = ContentValues().apply {
 | 
			
		||||
                    put(CategoriesContract.CategoryEntry.CATEGORY_NAME, categoryNameTextEdit.text.toString())
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                db.insert(CategoriesContract.CategoryEntry.TABLE_NAME, null, values)
 | 
			
		||||
                db.addCategory(Category(0, categoryNameTextEdit.text.toString()))
 | 
			
		||||
            } else { // Updating existing category
 | 
			
		||||
                val values = ContentValues().apply {
 | 
			
		||||
                    put(CategoriesContract.CategoryEntry.CATEGORY_NAME, categoryNameTextEdit.text.toString())
 | 
			
		||||
                }
 | 
			
		||||
                db.update(CategoriesContract.CategoryEntry.TABLE_NAME, values, "${BaseColumns._ID} = ?", arrayOf(category.id.toString()))
 | 
			
		||||
                db.updateCategory(category)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            finish()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
 | 
			
		||||
        db.close()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,7 @@ package org.foxarmy.barcodescannerforemployees.activities
 | 
			
		||||
 | 
			
		||||
import android.app.Activity
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.View
 | 
			
		||||
@@ -12,6 +13,8 @@ import androidx.appcompat.app.AlertDialog
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import androidx.core.content.ContextCompat
 | 
			
		||||
import androidx.core.widget.addTextChangedListener
 | 
			
		||||
import androidx.security.crypto.EncryptedSharedPreferences
 | 
			
		||||
import androidx.security.crypto.MasterKeys
 | 
			
		||||
import com.journeyapps.barcodescanner.ScanContract
 | 
			
		||||
import com.journeyapps.barcodescanner.ScanIntentResult
 | 
			
		||||
import com.journeyapps.barcodescanner.ScanOptions
 | 
			
		||||
@@ -45,11 +48,24 @@ class AddProductActivity : AppCompatActivity() {
 | 
			
		||||
    private var product: Product? = null
 | 
			
		||||
    private var abstractProduct: AbstractProduct? = null
 | 
			
		||||
 | 
			
		||||
    private lateinit var db: DBStorageController
 | 
			
		||||
    private lateinit var sharedPreferences: SharedPreferences
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        setContentView(R.layout.fragment_add_product)
 | 
			
		||||
 | 
			
		||||
        sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        db = DBStorageController(this, sharedPreferences.getString("currentGroup", "database")!!)
 | 
			
		||||
 | 
			
		||||
        scanButton = findViewById(R.id.scanButton)
 | 
			
		||||
        noBarcodeButton = findViewById(R.id.noBarcodeButton)
 | 
			
		||||
        abstractProductView = findViewById(R.id.abstractProductView)
 | 
			
		||||
@@ -70,7 +86,7 @@ class AddProductActivity : AppCompatActivity() {
 | 
			
		||||
        product = extras!!.get("product") as Product?
 | 
			
		||||
 | 
			
		||||
        if (product != null) {
 | 
			
		||||
            abstractProduct = DBStorageController(this).findAbstractProductById(DBStorageController(this).readableDatabase, product!!.abstractProductId)
 | 
			
		||||
            abstractProduct = db.findAbstractProductById(product!!.abstractProductId)
 | 
			
		||||
            abstractProductView.abstractProduct = abstractProduct!!
 | 
			
		||||
            expiryDateRadioButton.isSelected = true
 | 
			
		||||
            shelfLifeRadioButton.isSelected = false
 | 
			
		||||
@@ -148,9 +164,9 @@ class AddProductActivity : AppCompatActivity() {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (updatingExistentProduct) {
 | 
			
		||||
                DBStorageController(this).updateProduct(DBStorageController(this).writableDatabase, product!!)
 | 
			
		||||
                db.updateProduct(product!!)
 | 
			
		||||
            } else {
 | 
			
		||||
                DBStorageController(this).insertNewProduct(DBStorageController(this).writableDatabase, product!!)
 | 
			
		||||
                db.insertNewProduct(product!!)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            finish()
 | 
			
		||||
@@ -245,7 +261,7 @@ class AddProductActivity : AppCompatActivity() {
 | 
			
		||||
                Toast.makeText(this, getString(R.string.cancelled), Toast.LENGTH_SHORT).show()
 | 
			
		||||
            } else {
 | 
			
		||||
                val scannedBarcode = result.contents
 | 
			
		||||
                abstractProduct = DBStorageController(this).findAbstractProductByBarcode(DBStorageController(this).readableDatabase, scannedBarcode)
 | 
			
		||||
                abstractProduct = db.findAbstractProductByBarcode(scannedBarcode)
 | 
			
		||||
 | 
			
		||||
                displayAbstractProduct(abstractProduct, scannedBarcode)
 | 
			
		||||
                if (abstractProduct != null) {
 | 
			
		||||
@@ -266,4 +282,10 @@ class AddProductActivity : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
        scanLauncher.launch(options)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
 | 
			
		||||
        db.close()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,13 @@ package org.foxarmy.barcodescannerforemployees.activities
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.widget.LinearLayout
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import androidx.core.content.ContextCompat
 | 
			
		||||
import androidx.security.crypto.EncryptedSharedPreferences
 | 
			
		||||
import androidx.security.crypto.MasterKeys
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.R
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.databinding.ActivityExpiryCalendarBinding
 | 
			
		||||
@@ -14,11 +17,24 @@ import org.foxarmy.barcodescannerforemployees.views.ExpiryGroupView
 | 
			
		||||
class ExpiryCalendarActivity : AppCompatActivity() {
 | 
			
		||||
    private lateinit var binding: ActivityExpiryCalendarBinding
 | 
			
		||||
 | 
			
		||||
    private lateinit var db: DBStorageController
 | 
			
		||||
    private lateinit var sharedPreferences: SharedPreferences
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        setContentView(R.layout.fragment_expiry_dates)
 | 
			
		||||
 | 
			
		||||
        sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        db = DBStorageController(this, sharedPreferences.getString("currentGroup", "database")!!)
 | 
			
		||||
 | 
			
		||||
        fillUp()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -31,7 +47,7 @@ class ExpiryCalendarActivity : AppCompatActivity() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun fillUp() {
 | 
			
		||||
        val dates = DBStorageController(this).findAllExpiryDates(DBStorageController(this).readableDatabase)
 | 
			
		||||
        val dates = db.findAllExpiryDates()
 | 
			
		||||
 | 
			
		||||
        val container = findViewById<LinearLayout>(R.id.datesLinearLayout)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,11 +19,9 @@ class GroupActivity : AppCompatActivity() {
 | 
			
		||||
        binding = ActivityGroupBinding.inflate(layoutInflater)
 | 
			
		||||
        setContentView(binding.root)
 | 
			
		||||
 | 
			
		||||
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
 | 
			
		||||
 | 
			
		||||
        val sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            masterKeyAlias,
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
 
 | 
			
		||||
@@ -25,11 +25,9 @@ class LoginActivity : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
        fillUpLanguagesSpinner()
 | 
			
		||||
 | 
			
		||||
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
 | 
			
		||||
 | 
			
		||||
        val sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            masterKeyAlias,
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
 
 | 
			
		||||
@@ -56,11 +56,9 @@ class ManageGroupActivity : AppCompatActivity(){
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun amIAnAdminIn(groupId: Int): Boolean {
 | 
			
		||||
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
 | 
			
		||||
 | 
			
		||||
        val sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            masterKeyAlias,
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,9 @@ class MyGroupsActivity : AppCompatActivity(){
 | 
			
		||||
        binding = ActivityMyGroupsBinding.inflate(layoutInflater)
 | 
			
		||||
        setContentView(binding.root)
 | 
			
		||||
 | 
			
		||||
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
 | 
			
		||||
 | 
			
		||||
        val sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            masterKeyAlias,
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,26 @@ package org.foxarmy.barcodescannerforemployees.activities
 | 
			
		||||
 | 
			
		||||
import android.app.Activity
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.util.Log
 | 
			
		||||
import androidx.security.crypto.EncryptedSharedPreferences
 | 
			
		||||
import androidx.security.crypto.MasterKeys
 | 
			
		||||
 | 
			
		||||
class NavigatorActivity : Activity() {
 | 
			
		||||
 | 
			
		||||
    private lateinit var sharedPreferences: SharedPreferences
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        var intent = Intent(this, MainActivity::class.java)
 | 
			
		||||
 | 
			
		||||
        if (!isInGroup()) {
 | 
			
		||||
@@ -27,33 +38,10 @@ class NavigatorActivity : Activity() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun isAuthenticated(): Boolean {
 | 
			
		||||
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
 | 
			
		||||
 | 
			
		||||
        val sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            masterKeyAlias,
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        val jwt = sharedPreferences.getString("token", "")
 | 
			
		||||
        return jwt != ""
 | 
			
		||||
        return sharedPreferences.getString("token", "") != ""
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun isInGroup(): Boolean {
 | 
			
		||||
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
 | 
			
		||||
 | 
			
		||||
        val sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            masterKeyAlias,
 | 
			
		||||
            applicationContext,
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        val groups = sharedPreferences.getStringSet("groups", emptySet())
 | 
			
		||||
        Log.d("QWERTYUIOP", groups.toString())
 | 
			
		||||
        return groups!!.isNotEmpty()
 | 
			
		||||
        return sharedPreferences.getStringSet("groups", emptySet())!!.isNotEmpty()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
package org.foxarmy.barcodescannerforemployees.fragments
 | 
			
		||||
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.provider.BaseColumns
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.view.ViewGroup
 | 
			
		||||
@@ -11,14 +11,32 @@ import android.widget.Toast
 | 
			
		||||
import androidx.core.content.ContextCompat
 | 
			
		||||
import androidx.core.view.children
 | 
			
		||||
import androidx.fragment.app.Fragment
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.CategoriesContract
 | 
			
		||||
import androidx.security.crypto.EncryptedSharedPreferences
 | 
			
		||||
import androidx.security.crypto.MasterKeys
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.R
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.activities.AddCategoryActivity
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.dataclasses.Category
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.views.CategoryView
 | 
			
		||||
 | 
			
		||||
class CategoriesFragment : Fragment() {
 | 
			
		||||
 | 
			
		||||
    private lateinit var sharedPreferences: SharedPreferences
 | 
			
		||||
    private lateinit var db: DBStorageController
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            requireContext(),
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        db = DBStorageController(requireContext(), sharedPreferences.getString("currentGroup", "database")!!)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreateView(
 | 
			
		||||
        inflater: LayoutInflater, container: ViewGroup?,
 | 
			
		||||
        savedInstanceState: Bundle?
 | 
			
		||||
@@ -35,11 +53,10 @@ class CategoriesFragment : Fragment() {
 | 
			
		||||
    fun removeSelected() {
 | 
			
		||||
        val layout = view?.findViewById<LinearLayout>(R.id.categoriesLayout)
 | 
			
		||||
 | 
			
		||||
        val db = DBStorageController(requireContext())
 | 
			
		||||
        var deleted = false
 | 
			
		||||
        for (view: CategoryView in layout?.children!!.iterator() as Iterator<CategoryView>) {
 | 
			
		||||
            if (view.isCategorySelected) {
 | 
			
		||||
                db.eraseCategory(db.writableDatabase, view.category.id, requireContext())
 | 
			
		||||
                db.eraseCategory(view.category.id, requireContext())
 | 
			
		||||
                deleted = true
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -67,25 +84,11 @@ class CategoriesFragment : Fragment() {
 | 
			
		||||
        val layout = view?.findViewById<LinearLayout>(R.id.categoriesLayout)
 | 
			
		||||
        layout?.removeAllViews()
 | 
			
		||||
 | 
			
		||||
        val db = DBStorageController(requireContext()).readableDatabase
 | 
			
		||||
        val categories = db.getAllCategories()
 | 
			
		||||
 | 
			
		||||
        val projection = arrayOf(
 | 
			
		||||
            BaseColumns._ID,
 | 
			
		||||
            CategoriesContract.CategoryEntry.CATEGORY_NAME
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        val cursor = db.query(CategoriesContract.CategoryEntry.TABLE_NAME, projection, null, null, null, null, null)
 | 
			
		||||
 | 
			
		||||
        with (cursor) {
 | 
			
		||||
            while(moveToNext()) {
 | 
			
		||||
                val categoryId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
			
		||||
                val categoryName = getString(getColumnIndexOrThrow(CategoriesContract.CategoryEntry.CATEGORY_NAME))
 | 
			
		||||
 | 
			
		||||
                val category = Category(categoryId, categoryName)
 | 
			
		||||
 | 
			
		||||
                val categoryView = CategoryView(requireActivity(), requireContext(), category)
 | 
			
		||||
                layout?.addView(categoryView)
 | 
			
		||||
            }
 | 
			
		||||
        for (category in categories) {
 | 
			
		||||
            val categoryView = CategoryView(requireActivity(), requireContext(), category)
 | 
			
		||||
            layout?.addView(categoryView)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -94,4 +97,10 @@ class CategoriesFragment : Fragment() {
 | 
			
		||||
 | 
			
		||||
        updateContent()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
 | 
			
		||||
        db.close()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
package org.foxarmy.barcodescannerforemployees.fragments
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.provider.BaseColumns
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.view.ViewGroup
 | 
			
		||||
@@ -15,13 +14,12 @@ import androidx.core.content.ContextCompat
 | 
			
		||||
import androidx.core.view.children
 | 
			
		||||
import androidx.fragment.app.Fragment
 | 
			
		||||
import androidx.gridlayout.widget.GridLayout
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.AbstractProductContract
 | 
			
		||||
import androidx.security.crypto.EncryptedSharedPreferences
 | 
			
		||||
import androidx.security.crypto.MasterKeys
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.ProductContract
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.R
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.activities.AddProductActivity
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.databinding.FragmentShelfBinding
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.dataclasses.Product
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.views.ProductView
 | 
			
		||||
import kotlin.concurrent.thread
 | 
			
		||||
 | 
			
		||||
@@ -32,6 +30,23 @@ class ShelfFragment : Fragment() {
 | 
			
		||||
    private var filterBy = ""
 | 
			
		||||
    private var filter = ""
 | 
			
		||||
 | 
			
		||||
    private lateinit var db: DBStorageController
 | 
			
		||||
    private lateinit var sharedPreferences: SharedPreferences
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            requireContext(),
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        db = DBStorageController(requireContext(), sharedPreferences.getString("currentGroup", "database")!!)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreateView(
 | 
			
		||||
        inflater: LayoutInflater, container: ViewGroup?,
 | 
			
		||||
        savedInstanceState: Bundle?
 | 
			
		||||
@@ -107,88 +122,7 @@ class ShelfFragment : Fragment() {
 | 
			
		||||
                grv?.removeAllViews()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val db = DBStorageController(requireContext()).readableDatabase
 | 
			
		||||
            val projection = arrayOf(
 | 
			
		||||
                BaseColumns._ID,
 | 
			
		||||
                ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID,
 | 
			
		||||
                ProductContract.ProductEntry.AMOUNT,
 | 
			
		||||
                ProductContract.ProductEntry.DATE_OF_PRODUCTION,
 | 
			
		||||
                ProductContract.ProductEntry.EXPIRY_DATE,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            var orderBy: String = ""
 | 
			
		||||
 | 
			
		||||
            when (binding.spinner.selectedItemPosition) {
 | 
			
		||||
                0 -> {
 | 
			
		||||
                    orderBy =
 | 
			
		||||
                        "(SELECT ${AbstractProductContract.AbstractProductEntry.PRODUCT_NAME} FROM ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} WHERE ${BaseColumns._ID} = ${ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID}) ASC"
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                1 -> {
 | 
			
		||||
                    orderBy =
 | 
			
		||||
                        "(SELECT ${AbstractProductContract.AbstractProductEntry.CATEGORY} FROM ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} WHERE ${BaseColumns._ID} = ${ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID}) ASC"
 | 
			
		||||
                }
 | 
			
		||||
// Wow, I wrote this on first try but unfortunately SQLite can't do that :(
 | 
			
		||||
// I'll leave it here as a memory.
 | 
			
		||||
//                "Freshness" -> {
 | 
			
		||||
//                    orderBy =
 | 
			
		||||
//                        "(SELECT ( (julianday(${ProductContract.ProductEntry.EXPIRY_DATE}) - julianday('now', 'localtime')) / (julianday(${ProductContract.ProductEntry.EXPIRY_DATE}) - julianday(${ProductContract.ProductEntry.DATE_OF_PRODUCTION})) )) ASC"
 | 
			
		||||
//                }
 | 
			
		||||
 | 
			
		||||
                3 -> {
 | 
			
		||||
                    orderBy = "${ProductContract.ProductEntry.DATE_OF_PRODUCTION} ASC"
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                4 -> {
 | 
			
		||||
                    orderBy = "${ProductContract.ProductEntry.EXPIRY_DATE} ASC"
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var selection: String? = null
 | 
			
		||||
            var selectionArgs: Array<String>? = null
 | 
			
		||||
 | 
			
		||||
            when (filterBy) {
 | 
			
		||||
                "expiryDate" -> {
 | 
			
		||||
                    selection = "${ProductContract.ProductEntry.EXPIRY_DATE} = ?"
 | 
			
		||||
                    selectionArgs = arrayOf(filter)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                "" -> {}
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            val cursor = db.query(ProductContract.ProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, orderBy)
 | 
			
		||||
 | 
			
		||||
            val products = mutableListOf<Product>()
 | 
			
		||||
 | 
			
		||||
            with(cursor) {
 | 
			
		||||
                while (moveToNext()) {
 | 
			
		||||
                    val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
			
		||||
                    val abstractProductId =
 | 
			
		||||
                        getInt(getColumnIndexOrThrow(ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID))
 | 
			
		||||
                    val amount = getInt(getColumnIndexOrThrow(ProductContract.ProductEntry.AMOUNT))
 | 
			
		||||
                    val dateOfProduction =
 | 
			
		||||
                        getLong(getColumnIndexOrThrow(ProductContract.ProductEntry.DATE_OF_PRODUCTION))
 | 
			
		||||
                    val dateOfExpiry = getLong(getColumnIndexOrThrow(ProductContract.ProductEntry.EXPIRY_DATE))
 | 
			
		||||
 | 
			
		||||
                    val product = Product(productId, abstractProductId, amount, dateOfProduction, dateOfExpiry)
 | 
			
		||||
 | 
			
		||||
                    if (binding.spinner.selectedItemPosition == 2) { //freshness
 | 
			
		||||
                        products.add(product)
 | 
			
		||||
                    } else {
 | 
			
		||||
                        val productView = ProductView(
 | 
			
		||||
                            requireActivity(),
 | 
			
		||||
                            requireContext(),
 | 
			
		||||
                            product
 | 
			
		||||
                        )
 | 
			
		||||
                        activity!!.runOnUiThread {
 | 
			
		||||
                            grv?.addView(productView)
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            products.sortWith(compareByDescending { it.freshness })
 | 
			
		||||
            val products = db.getSortedListOfProducts(binding.spinner.selectedItemPosition, filterBy, filter)
 | 
			
		||||
 | 
			
		||||
            for (product in products.iterator()) {
 | 
			
		||||
                val productView = ProductView(
 | 
			
		||||
@@ -201,6 +135,7 @@ class ShelfFragment : Fragment() {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            updateInProgress = false
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -208,14 +143,13 @@ class ShelfFragment : Fragment() {
 | 
			
		||||
        thread {
 | 
			
		||||
            val grv = view?.findViewById<GridLayout>(R.id.contentGridLayout)
 | 
			
		||||
 | 
			
		||||
            val db = DBStorageController(requireContext())
 | 
			
		||||
            var deleted = false
 | 
			
		||||
            for (view: ProductView in grv?.children!!.iterator() as Iterator<ProductView>) {
 | 
			
		||||
                activity!!.runOnUiThread {
 | 
			
		||||
                    view.findViewById<ImageView>(R.id.productPicture).setImageURI(null)
 | 
			
		||||
                }
 | 
			
		||||
                if (view.isProductSelected) {
 | 
			
		||||
                    db.eraseProduct(db.writableDatabase, view.product.id)
 | 
			
		||||
                    db.eraseProduct(view.product.id)
 | 
			
		||||
                    deleted = true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -229,6 +163,12 @@ class ShelfFragment : Fragment() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
 | 
			
		||||
        db.close()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
 | 
			
		||||
        fun newInstance(date: Long):ShelfFragment = ShelfFragment().apply {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
package org.foxarmy.barcodescannerforemployees.fragments
 | 
			
		||||
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.provider.BaseColumns
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.view.ViewGroup
 | 
			
		||||
@@ -10,13 +10,13 @@ import android.widget.*
 | 
			
		||||
import androidx.core.content.ContextCompat
 | 
			
		||||
import androidx.core.view.children
 | 
			
		||||
import androidx.fragment.app.Fragment
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.AbstractProductContract
 | 
			
		||||
import androidx.security.crypto.EncryptedSharedPreferences
 | 
			
		||||
import androidx.security.crypto.MasterKeys
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.R
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.activities.AddAbstractProductActivity
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.activities.FindBarcodelessAbstractProduct
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.databinding.FragmentStorageBinding
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.generateThumbnailForImage
 | 
			
		||||
import org.foxarmy.barcodescannerforemployees.views.AbstractProductView
 | 
			
		||||
import kotlin.concurrent.thread
 | 
			
		||||
@@ -26,6 +26,24 @@ class StorageFragment : Fragment() {
 | 
			
		||||
    private lateinit var binding: FragmentStorageBinding
 | 
			
		||||
    private var filterBy = ""
 | 
			
		||||
    private lateinit var filter: Array<String>
 | 
			
		||||
 | 
			
		||||
    private lateinit var sharedPreferences: SharedPreferences
 | 
			
		||||
    private lateinit var db: DBStorageController
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        sharedPreferences = EncryptedSharedPreferences.create(
 | 
			
		||||
            "sensitive",
 | 
			
		||||
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
 | 
			
		||||
            requireContext(),
 | 
			
		||||
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
 | 
			
		||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        db = DBStorageController(requireContext(), sharedPreferences.getString("currentGroup", "database")!!)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreateView(
 | 
			
		||||
        inflater: LayoutInflater, container: ViewGroup?,
 | 
			
		||||
        savedInstanceState: Bundle?
 | 
			
		||||
@@ -72,14 +90,13 @@ class StorageFragment : Fragment() {
 | 
			
		||||
        thread {
 | 
			
		||||
            val grv = binding.contentGridLayout
 | 
			
		||||
 | 
			
		||||
            val db = DBStorageController(requireContext())
 | 
			
		||||
            var deleted = false
 | 
			
		||||
            for (view: AbstractProductView in grv.children.iterator() as Iterator<AbstractProductView>) {
 | 
			
		||||
                activity!!.runOnUiThread {
 | 
			
		||||
                    view.findViewById<ImageView>(R.id.productPicture).setImageURI(null)
 | 
			
		||||
                }
 | 
			
		||||
                if (view.isProductSelected) {
 | 
			
		||||
                    db.eraseAbstractProduct(db.writableDatabase, view.abstractProduct.id, requireContext())
 | 
			
		||||
                    db.eraseAbstractProduct(view.abstractProduct.id, requireContext())
 | 
			
		||||
                    deleted = true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -115,78 +132,30 @@ class StorageFragment : Fragment() {
 | 
			
		||||
                grv.removeAllViews()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val db = DBStorageController(requireContext()).readableDatabase
 | 
			
		||||
            val projection = arrayOf(
 | 
			
		||||
                BaseColumns._ID,
 | 
			
		||||
                AbstractProductContract.AbstractProductEntry.BARCODE,
 | 
			
		||||
                AbstractProductContract.AbstractProductEntry.PRODUCT_NAME,
 | 
			
		||||
                AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT,
 | 
			
		||||
                AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME,
 | 
			
		||||
                AbstractProductContract.AbstractProductEntry.CATEGORY,
 | 
			
		||||
                AbstractProductContract.AbstractProductEntry.UNIT
 | 
			
		||||
            )
 | 
			
		||||
            val abstractProducts = db.getSortedListOfAbstractProducts(binding.spinner.selectedItemPosition, filterBy, filter)
 | 
			
		||||
 | 
			
		||||
            var orderBy: String = ""
 | 
			
		||||
            when(binding.spinner.selectedItemPosition) {
 | 
			
		||||
                0 -> {
 | 
			
		||||
                    orderBy = "${AbstractProductContract.AbstractProductEntry.PRODUCT_NAME} ASC"
 | 
			
		||||
                }
 | 
			
		||||
                1 -> {
 | 
			
		||||
                    orderBy = "${AbstractProductContract.AbstractProductEntry.CATEGORY} ASC"
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (abstractProduct in abstractProducts) {
 | 
			
		||||
                generateThumbnailForImage(context!!, abstractProduct.imageHash)
 | 
			
		||||
 | 
			
		||||
            var selection = ""
 | 
			
		||||
            var selectionArgs: Array<String>? = null
 | 
			
		||||
                val abstractProductView = AbstractProductView(
 | 
			
		||||
                    requireActivity(),
 | 
			
		||||
                    requireContext(),
 | 
			
		||||
                    abstractProduct
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            when (filterBy) {
 | 
			
		||||
                "category" -> {
 | 
			
		||||
                    selection = "${AbstractProductContract.AbstractProductEntry.CATEGORY} = ?"
 | 
			
		||||
                    selectionArgs = filter
 | 
			
		||||
                }
 | 
			
		||||
                "barcodeless" -> {
 | 
			
		||||
                    selection = "${AbstractProductContract.AbstractProductEntry.BARCODE} = '' "
 | 
			
		||||
                    selectionArgs = null
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            val cursor = db.query(AbstractProductContract.AbstractProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, orderBy)
 | 
			
		||||
 | 
			
		||||
            with (cursor) {
 | 
			
		||||
                while(moveToNext()) {
 | 
			
		||||
                    val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
			
		||||
                    val barcode = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.BARCODE))
 | 
			
		||||
                    val productName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
			
		||||
                    val netWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
 | 
			
		||||
                    val productImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
 | 
			
		||||
                    val category = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.CATEGORY))
 | 
			
		||||
                    val unit = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.UNIT))
 | 
			
		||||
 | 
			
		||||
                    val product = AbstractProduct(productId, barcode, productName, netWeight, productImageHash, category, unit)
 | 
			
		||||
 | 
			
		||||
                    generateThumbnailForImage(context!!, productImageHash)
 | 
			
		||||
 | 
			
		||||
                    val abstractProduct = AbstractProductView(
 | 
			
		||||
                        requireActivity(),
 | 
			
		||||
                        requireContext(),
 | 
			
		||||
                        product
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
                    if (filterBy == "barcodeless") {
 | 
			
		||||
                        abstractProduct.setOnClickListener {
 | 
			
		||||
                            (activity as FindBarcodelessAbstractProduct).selected(abstractProduct.abstractProduct)
 | 
			
		||||
                        }
 | 
			
		||||
                        abstractProduct.findViewById<TextView>(R.id.productNameView).setOnClickListener {
 | 
			
		||||
                            (activity as FindBarcodelessAbstractProduct).selected(abstractProduct.abstractProduct)
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                if (filterBy == "barcodeless") {
 | 
			
		||||
                    abstractProductView.setOnClickListener {
 | 
			
		||||
                        (activity as FindBarcodelessAbstractProduct).selected(abstractProductView.abstractProduct)
 | 
			
		||||
                    }
 | 
			
		||||
                    abstractProductView.findViewById<TextView>(R.id.productNameView).setOnClickListener {
 | 
			
		||||
                        (activity as FindBarcodelessAbstractProduct).selected(abstractProductView.abstractProduct)
 | 
			
		||||
 | 
			
		||||
                    activity!!.runOnUiThread{
 | 
			
		||||
                        grv.addView(abstractProduct)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                activity!!.runOnUiThread{
 | 
			
		||||
                    grv.addView(abstractProductView)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }.join()
 | 
			
		||||
    }
 | 
			
		||||
@@ -202,6 +171,13 @@ class StorageFragment : Fragment() {
 | 
			
		||||
        filter = arrayOf("$id")
 | 
			
		||||
        updateContent()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
 | 
			
		||||
        db.close()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
 | 
			
		||||
        fun newInstance(filterBy: String, filter: Array<String>):StorageFragment = StorageFragment().apply {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user