ability to edit products on shelf

This commit is contained in:
leca 2024-10-17 21:59:15 +03:00
parent b1b987e5f6
commit 6a49b573ca
4 changed files with 120 additions and 57 deletions

View File

@ -258,6 +258,16 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
return abstractProduct 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 { companion object {
const val DATABASE_VERSION = 1 const val DATABASE_VERSION = 1
const val DATABASE_NAME = "database.db" const val DATABASE_NAME = "database.db"

View File

@ -1,14 +1,11 @@
package org.foxarmy.barcodescannerforemployees.activities package org.foxarmy.barcodescannerforemployees.activities
import android.app.DatePickerDialog import android.app.DatePickerDialog
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.widget.addTextChangedListener
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
import org.foxarmy.barcodescannerforemployees.DBStorageController import org.foxarmy.barcodescannerforemployees.DBStorageController
import org.foxarmy.barcodescannerforemployees.R import org.foxarmy.barcodescannerforemployees.R
@ -37,20 +34,15 @@ class AddProductActivity : AppCompatActivity() {
private lateinit var saveProductButton: Button private lateinit var saveProductButton: Button
private var expiryDateOverShelfLife: Boolean? = null private var expiryDateOverShelfLife: Boolean? = null
private var dateOfProduction: Long = 0 private var updatingExistentProduct = false
private var dateOfExpiry: Long = 0 private var product: Product? = null
private var abstractProduct: AbstractProduct? = null
private var barcode: String = ""
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_add_product) setContentView(R.layout.fragment_add_product)
val extras = intent.extras
var product = extras!!.get("product") as Product?
scanButton = findViewById(R.id.scanButton) scanButton = findViewById(R.id.scanButton)
abstractProductView = findViewById(R.id.abstractProductView) abstractProductView = findViewById(R.id.abstractProductView)
expiryDateRadioButton = findViewById(R.id.expiryDateRadio) expiryDateRadioButton = findViewById(R.id.expiryDateRadio)
@ -67,12 +59,31 @@ class AddProductActivity : AppCompatActivity() {
dateOfProductionSelectButton = findViewById(R.id.selectDateOfProductionButton) dateOfProductionSelectButton = findViewById(R.id.selectDateOfProductionButton)
saveProductButton = findViewById(R.id.saveProductButton) 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 { scanButton.setOnClickListener {
val scanner = GmsBarcodeScanning.getClient(this) val scanner = GmsBarcodeScanning.getClient(this)
scanner.startScan() scanner.startScan()
.addOnSuccessListener { bc -> .addOnSuccessListener { bc ->
barcode = bc.rawValue.toString() abstractProduct = DBStorageController(this).findAbstractProductByBarcode(DBStorageController(this).readableDatabase, bc.rawValue.toString())
findAndDisplayAbstractProductByBarcode(barcode) product!!.abstractProductId = abstractProduct!!.id
displayAbstractProduct(abstractProduct!!)
} }
.addOnFailureListener { .addOnFailureListener {
Toast.makeText(this, "Cannot scan barcode", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Cannot scan barcode", Toast.LENGTH_SHORT).show()
@ -80,23 +91,13 @@ class AddProductActivity : AppCompatActivity() {
} }
expiryDateRadioButton.setOnClickListener { expiryDateRadioButton.setOnClickListener {
expiryDateTextView.visibility = View.VISIBLE
expiryDateSelectButton.visibility = View.VISIBLE
shelfLifeTextEdit.visibility = View.INVISIBLE
shelfLifeTextView.visibility = View.INVISIBLE
expiryDateOverShelfLife = true expiryDateOverShelfLife = true
update()
} }
shelfLifeRadioButton.setOnClickListener { shelfLifeRadioButton.setOnClickListener {
expiryDateTextView.visibility = View.INVISIBLE
expiryDateSelectButton.visibility = View.INVISIBLE
shelfLifeTextEdit.visibility = View.VISIBLE
shelfLifeTextView.visibility = View.VISIBLE
expiryDateOverShelfLife = false expiryDateOverShelfLife = false
update()
} }
dateOfProductionSelectButton.setOnClickListener { dateOfProductionSelectButton.setOnClickListener {
@ -106,8 +107,8 @@ class AddProductActivity : AppCompatActivity() {
val day = c.get(Calendar.DAY_OF_MONTH) val day = c.get(Calendar.DAY_OF_MONTH)
val dpd = DatePickerDialog(this, { _, y, m, d -> val dpd = DatePickerDialog(this, { _, y, m, d ->
dateOfProduction = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y").time / 1000 product!!.dateOfProduction = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y")!!.time / 1000
findViewById<TextView>(R.id.dateOfProductionTextView).text = "Date of production: $d.${m+1}.$y" update()
}, year, month, day) }, year, month, day)
dpd.show() dpd.show()
@ -119,20 +120,26 @@ class AddProductActivity : AppCompatActivity() {
val month = c.get(Calendar.MONTH) val month = c.get(Calendar.MONTH)
val day = c.get(Calendar.DAY_OF_MONTH) val day = c.get(Calendar.DAY_OF_MONTH)
val dpd = DatePickerDialog(this, { view, y, m, d -> val dpd = DatePickerDialog(this, { _, y, m, d ->
dateOfExpiry = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y").time / 1000 product!!.dateOfExpiry = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y")!!.time / 1000
expiryDateTextView.text = "Expiry date: $d.${m + 1}.$y" update()
}, year, month, day) }, year, month, day)
dpd.show() dpd.show()
} }
amountTextEdit.addTextChangedListener {
val text = amountTextEdit.text.toString()
if (text == "") return@addTextChangedListener
product!!.amount = text.toInt()
}
saveProductButton.setOnClickListener { saveProductButton.setOnClickListener {
if (expiryDateOverShelfLife == null) { if (expiryDateOverShelfLife == null) {
Toast.makeText(this, "Please, choose and fill in shelf life or expiry date.", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Please, choose and fill in shelf life or expiry date.", Toast.LENGTH_SHORT).show()
return@setOnClickListener return@setOnClickListener
} }
if (dateOfProduction == 0.toLong()) { if (product!!.dateOfProduction == 0.toLong()) {
Toast.makeText(this, "Please, choose date of production.", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Please, choose date of production.", Toast.LENGTH_SHORT).show()
return@setOnClickListener return@setOnClickListener
} }
@ -142,53 +149,69 @@ class AddProductActivity : AppCompatActivity() {
evaluateDateOfExpiry(shelfLifeTextEdit.text.toString().toInt()) evaluateDateOfExpiry(shelfLifeTextEdit.text.toString().toInt())
} }
} else { } else {
if (dateOfExpiry == 0.toLong()) { if (product!!.dateOfExpiry == 0.toLong()) {
Toast.makeText(this, "Please, choose date of expiry.", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Please, choose date of expiry.", Toast.LENGTH_SHORT).show()
return@setOnClickListener return@setOnClickListener
} }
} }
if (amountTextEdit.text.toString() == "") { if (product!!.amount == 0) {
Toast.makeText(this, "Please, specify an amount of product.", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Please, specify an amount of product.", Toast.LENGTH_SHORT).show()
return@setOnClickListener return@setOnClickListener
} }
val abstractProduct = DBStorageController(this).findAbstractProductByBarcode(DBStorageController(this).readableDatabase, barcode) if (updatingExistentProduct) {
product = Product(0, abstractProduct!!.id, amountTextEdit.text.toString().toInt(), dateOfProduction, dateOfExpiry) DBStorageController(this).updateProduct(DBStorageController(this).writableDatabase, product!!)
} else {
DBStorageController(this).insertNewProduct(DBStorageController(this).writableDatabase, product!!) DBStorageController(this).insertNewProduct(DBStorageController(this).writableDatabase, product!!)
}
finish() finish()
} }
} }
fun evaluateDateOfExpiry(shelfLifeMonths: Int) { private fun update () {
if (dateOfProduction == 0.toLong() ) { 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<TextView>(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 return
} }
val c = Calendar.getInstance() val c = Calendar.getInstance()
c.timeInMillis = dateOfProduction * 1000 c.timeInMillis = product!!.dateOfProduction * 1000
c.add(Calendar.MONTH, shelfLifeMonths) c.add(Calendar.MONTH, shelfLifeMonths)
dateOfExpiry = c.timeInMillis / 1000 product!!.dateOfExpiry = c.timeInMillis / 1000
} }
fun findAndDisplayAbstractProductByBarcode(barcode: String) { private fun displayAbstractProduct(abstractProduct: AbstractProduct) {
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
}
abstractProductView.abstractProduct = abstractProduct abstractProductView.abstractProduct = abstractProduct
abstractProductView.update() abstractProductView.update()
} }

View File

@ -139,6 +139,11 @@ class MainActivity : AppCompatActivity() {
val categoriesFragment = fragment as CategoriesFragment val categoriesFragment = fragment as CategoriesFragment
categoriesFragment.updateSelected() categoriesFragment.updateSelected()
} }
"ShelfFragment" -> {
val shelfFragment = fragment as ShelfFragment
shelfFragment.updateSelected()
}
} }
true true
} }

View File

@ -1,5 +1,6 @@
package org.foxarmy.barcodescannerforemployees.fragments package org.foxarmy.barcodescannerforemployees.fragments
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.provider.BaseColumns import android.provider.BaseColumns
import android.view.LayoutInflater import android.view.LayoutInflater
@ -9,6 +10,7 @@ import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.ImageView import android.widget.ImageView
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.core.view.children import androidx.core.view.children
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.gridlayout.widget.GridLayout import androidx.gridlayout.widget.GridLayout
@ -16,6 +18,7 @@ import org.foxarmy.barcodescannerforemployees.AbstractProductContract
import org.foxarmy.barcodescannerforemployees.DBStorageController import org.foxarmy.barcodescannerforemployees.DBStorageController
import org.foxarmy.barcodescannerforemployees.ProductContract import org.foxarmy.barcodescannerforemployees.ProductContract
import org.foxarmy.barcodescannerforemployees.R import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.activities.AddProductActivity
import org.foxarmy.barcodescannerforemployees.databinding.FragmentShelfBinding import org.foxarmy.barcodescannerforemployees.databinding.FragmentShelfBinding
import org.foxarmy.barcodescannerforemployees.dataclasses.Product import org.foxarmy.barcodescannerforemployees.dataclasses.Product
import org.foxarmy.barcodescannerforemployees.views.ProductView import org.foxarmy.barcodescannerforemployees.views.ProductView
@ -49,6 +52,28 @@ class ShelfFragment : Fragment() {
return binding.root return binding.root
} }
fun updateSelected() {
val grv = view?.findViewById<GridLayout>(R.id.contentGridLayout)
var updated = false
for (view: ProductView in grv?.children!!.iterator() as Iterator<ProductView>) {
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() { private fun fillUpSortBySpinner() {
val sorts = mutableListOf("Name", "Category", "Freshness", "Date of production", "Date of expiry") val sorts = mutableListOf("Name", "Category", "Freshness", "Date of production", "Date of expiry")