From 6a49b573ca8fab9af0ea1f7408cc2686121cb0bf Mon Sep 17 00:00:00 2001 From: leca Date: Thu, 17 Oct 2024 21:59:15 +0300 Subject: [PATCH] ability to edit products on shelf --- .../DBStorageController.kt | 10 ++ .../activities/AddProductActivity.kt | 137 ++++++++++-------- .../activities/MainActivity.kt | 5 + .../fragments/ShelfFragment.kt | 25 ++++ 4 files changed, 120 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/DBStorageController.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/DBStorageController.kt index ff3469c..5c9b450 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/DBStorageController.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/DBStorageController.kt @@ -258,6 +258,16 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE return abstractProduct } + fun updateProduct(db: SQLiteDatabase, 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())) + } + companion object { const val DATABASE_VERSION = 1 const val DATABASE_NAME = "database.db" diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/AddProductActivity.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/AddProductActivity.kt index b64d562..36836f9 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/AddProductActivity.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/AddProductActivity.kt @@ -1,14 +1,11 @@ package org.foxarmy.barcodescannerforemployees.activities import android.app.DatePickerDialog -import android.content.DialogInterface -import android.content.Intent import android.os.Bundle import android.view.View import android.widget.* -import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.ContextCompat +import androidx.core.widget.addTextChangedListener import com.google.mlkit.vision.codescanner.GmsBarcodeScanning import org.foxarmy.barcodescannerforemployees.DBStorageController import org.foxarmy.barcodescannerforemployees.R @@ -37,20 +34,15 @@ class AddProductActivity : AppCompatActivity() { private lateinit var saveProductButton: Button private var expiryDateOverShelfLife: Boolean? = null - private var dateOfProduction: Long = 0 - private var dateOfExpiry: Long = 0 - - private var barcode: String = "" + private var updatingExistentProduct = false + private var product: Product? = null + private var abstractProduct: AbstractProduct? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.fragment_add_product) - val extras = intent.extras - var product = extras!!.get("product") as Product? - - scanButton = findViewById(R.id.scanButton) abstractProductView = findViewById(R.id.abstractProductView) expiryDateRadioButton = findViewById(R.id.expiryDateRadio) @@ -67,12 +59,31 @@ class AddProductActivity : AppCompatActivity() { dateOfProductionSelectButton = findViewById(R.id.selectDateOfProductionButton) saveProductButton = findViewById(R.id.saveProductButton) + val extras = intent.extras + product = extras!!.get("product") as Product? + + if (product != null) { + abstractProduct = DBStorageController(this).findAbstractProductById(DBStorageController(this).readableDatabase, product!!.abstractProductId) + abstractProductView.abstractProduct = abstractProduct!! + expiryDateRadioButton.isSelected = true + shelfLifeRadioButton.isSelected = false + + expiryDateOverShelfLife = true + updatingExistentProduct = true + update() + } else { + product = Product(0, 0, 0, 0, 0) + abstractProduct = AbstractProduct(0, "", "", 0.0, "", 0) + } + scanButton.setOnClickListener { val scanner = GmsBarcodeScanning.getClient(this) scanner.startScan() .addOnSuccessListener { bc -> - barcode = bc.rawValue.toString() - findAndDisplayAbstractProductByBarcode(barcode) + abstractProduct = DBStorageController(this).findAbstractProductByBarcode(DBStorageController(this).readableDatabase, bc.rawValue.toString()) + product!!.abstractProductId = abstractProduct!!.id + + displayAbstractProduct(abstractProduct!!) } .addOnFailureListener { Toast.makeText(this, "Cannot scan barcode", Toast.LENGTH_SHORT).show() @@ -80,23 +91,13 @@ class AddProductActivity : AppCompatActivity() { } expiryDateRadioButton.setOnClickListener { - expiryDateTextView.visibility = View.VISIBLE - expiryDateSelectButton.visibility = View.VISIBLE - - shelfLifeTextEdit.visibility = View.INVISIBLE - shelfLifeTextView.visibility = View.INVISIBLE - expiryDateOverShelfLife = true + update() } shelfLifeRadioButton.setOnClickListener { - expiryDateTextView.visibility = View.INVISIBLE - expiryDateSelectButton.visibility = View.INVISIBLE - - shelfLifeTextEdit.visibility = View.VISIBLE - shelfLifeTextView.visibility = View.VISIBLE - expiryDateOverShelfLife = false + update() } dateOfProductionSelectButton.setOnClickListener { @@ -106,8 +107,8 @@ class AddProductActivity : AppCompatActivity() { val day = c.get(Calendar.DAY_OF_MONTH) val dpd = DatePickerDialog(this, { _, y, m, d -> - dateOfProduction = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y").time / 1000 - findViewById(R.id.dateOfProductionTextView).text = "Date of production: $d.${m+1}.$y" + product!!.dateOfProduction = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y")!!.time / 1000 + update() }, year, month, day) dpd.show() @@ -119,20 +120,26 @@ class AddProductActivity : AppCompatActivity() { val month = c.get(Calendar.MONTH) val day = c.get(Calendar.DAY_OF_MONTH) - val dpd = DatePickerDialog(this, { view, y, m, d -> - dateOfExpiry = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y").time / 1000 - expiryDateTextView.text = "Expiry date: $d.${m + 1}.$y" + val dpd = DatePickerDialog(this, { _, y, m, d -> + product!!.dateOfExpiry = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y")!!.time / 1000 + update() }, year, month, day) dpd.show() } + amountTextEdit.addTextChangedListener { + val text = amountTextEdit.text.toString() + if (text == "") return@addTextChangedListener + product!!.amount = text.toInt() + } + saveProductButton.setOnClickListener { if (expiryDateOverShelfLife == null) { Toast.makeText(this, "Please, choose and fill in shelf life or expiry date.", Toast.LENGTH_SHORT).show() return@setOnClickListener } - if (dateOfProduction == 0.toLong()) { + if (product!!.dateOfProduction == 0.toLong()) { Toast.makeText(this, "Please, choose date of production.", Toast.LENGTH_SHORT).show() return@setOnClickListener } @@ -142,53 +149,69 @@ class AddProductActivity : AppCompatActivity() { evaluateDateOfExpiry(shelfLifeTextEdit.text.toString().toInt()) } } else { - if (dateOfExpiry == 0.toLong()) { + if (product!!.dateOfExpiry == 0.toLong()) { Toast.makeText(this, "Please, choose date of expiry.", Toast.LENGTH_SHORT).show() return@setOnClickListener } } - if (amountTextEdit.text.toString() == "") { + if (product!!.amount == 0) { Toast.makeText(this, "Please, specify an amount of product.", Toast.LENGTH_SHORT).show() return@setOnClickListener } - val abstractProduct = DBStorageController(this).findAbstractProductByBarcode(DBStorageController(this).readableDatabase, barcode) - product = Product(0, abstractProduct!!.id, amountTextEdit.text.toString().toInt(), dateOfProduction, dateOfExpiry) + if (updatingExistentProduct) { + DBStorageController(this).updateProduct(DBStorageController(this).writableDatabase, product!!) + } else { + DBStorageController(this).insertNewProduct(DBStorageController(this).writableDatabase, product!!) + } - DBStorageController(this).insertNewProduct(DBStorageController(this).writableDatabase, product!!) finish() } } - fun evaluateDateOfExpiry(shelfLifeMonths: Int) { - if (dateOfProduction == 0.toLong() ) { + private fun update () { + if (expiryDateOverShelfLife == true) { + expiryDateTextView.visibility = View.VISIBLE + expiryDateSelectButton.visibility = View.VISIBLE + + shelfLifeTextEdit.visibility = View.INVISIBLE + shelfLifeTextView.visibility = View.INVISIBLE + } else if (expiryDateOverShelfLife == false){ + expiryDateTextView.visibility = View.INVISIBLE + expiryDateSelectButton.visibility = View.INVISIBLE + + shelfLifeTextEdit.visibility = View.VISIBLE + shelfLifeTextView.visibility = View.VISIBLE + } + val dateOfProductionParsed = SimpleDateFormat("dd.MM.yyyy").format(Date(product!!.dateOfProduction * 1000)) + findViewById(R.id.dateOfProductionTextView).text = "Date of production: $dateOfProductionParsed" + + val expiryDateParsed = SimpleDateFormat("dd.MM.yyyy").format(Date(product!!.dateOfExpiry * 1000)) + expiryDateTextView.text = "Expiry date: $expiryDateParsed" + + if (amountTextEdit.text.toString() == "") { + amountTextEdit.setText(product!!.amount.toString()) + } else { + product!!.amount = amountTextEdit.text.toString().toInt() + } + + abstractProductView.update() + } + + private fun evaluateDateOfExpiry(shelfLifeMonths: Int) { + if (product!!.dateOfProduction == 0.toLong() ) { return } val c = Calendar.getInstance() - c.timeInMillis = dateOfProduction * 1000 + c.timeInMillis = product!!.dateOfProduction * 1000 c.add(Calendar.MONTH, shelfLifeMonths) - dateOfExpiry = c.timeInMillis / 1000 + product!!.dateOfExpiry = c.timeInMillis / 1000 } - fun findAndDisplayAbstractProductByBarcode(barcode: String) { - val abstractProduct = DBStorageController(this).findAbstractProductByBarcode(DBStorageController(this).readableDatabase, barcode) - if (abstractProduct == null) { - AlertDialog.Builder(this).setMessage("Product with such barcode not found. Try scanning with better lightning or add new abstract product") - .setPositiveButton("Add") { _: DialogInterface, _: Int -> - val addAbstractProductIntent = Intent(this, AddAbstractProductActivity::class.java) - val extras = Bundle() - extras.putParcelable("abstractProduct", AbstractProduct(0, barcode, "", 0.0, "", 0)) - addAbstractProductIntent.putExtras(extras) - ContextCompat.startActivity(this, addAbstractProductIntent, extras) - } - .setNegativeButton("Try again") {_: DialogInterface, _: Int -> - - }.show() - return - } + private fun displayAbstractProduct(abstractProduct: AbstractProduct) { abstractProductView.abstractProduct = abstractProduct abstractProductView.update() } diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/MainActivity.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/MainActivity.kt index 4fa5f4c..2c8d336 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/MainActivity.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/MainActivity.kt @@ -139,6 +139,11 @@ class MainActivity : AppCompatActivity() { val categoriesFragment = fragment as CategoriesFragment categoriesFragment.updateSelected() } + + "ShelfFragment" -> { + val shelfFragment = fragment as ShelfFragment + shelfFragment.updateSelected() + } } true } diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/fragments/ShelfFragment.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/fragments/ShelfFragment.kt index abd864d..c908d04 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/fragments/ShelfFragment.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/fragments/ShelfFragment.kt @@ -1,5 +1,6 @@ package org.foxarmy.barcodescannerforemployees.fragments +import android.content.Intent import android.os.Bundle import android.provider.BaseColumns import android.view.LayoutInflater @@ -9,6 +10,7 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.ImageView import android.widget.Toast +import androidx.core.content.ContextCompat import androidx.core.view.children import androidx.fragment.app.Fragment import androidx.gridlayout.widget.GridLayout @@ -16,6 +18,7 @@ import org.foxarmy.barcodescannerforemployees.AbstractProductContract 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 @@ -49,6 +52,28 @@ class ShelfFragment : Fragment() { return binding.root } + fun updateSelected() { + val grv = view?.findViewById(R.id.contentGridLayout) + + var updated = false + for (view: ProductView in grv?.children!!.iterator() as Iterator) { + if (view.isProductSelected) { + val addProductIntent = Intent(requireContext(), AddProductActivity::class.java) + val extras = Bundle() + extras.putParcelable("product", view.product) + addProductIntent.putExtras(extras) + ContextCompat.startActivity(requireContext(), addProductIntent, extras) + + updated = true + } + } + + if (!updated) { + Toast.makeText(requireContext(), "Nothing to update", Toast.LENGTH_SHORT).show() + } + updateContent() + } + private fun fillUpSortBySpinner() { val sorts = mutableListOf("Name", "Category", "Freshness", "Date of production", "Date of expiry")