Created
August 24, 2022 16:58
-
-
Save photizzo/4839e03a21ac158592bc12023b671fc7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package co.tractionapp.traction.main.pages.products | |
import android.app.Activity.RESULT_OK | |
import android.app.Dialog | |
import android.content.Intent | |
import android.os.Bundle | |
import android.os.Handler | |
import android.os.Looper | |
import android.view.* | |
import co.tractionapp.data.room.objects.TractionProductCategory | |
import co.tractionapp.data.room.objects.TractionProductVariants | |
import co.tractionapp.data.room.objects.TractionProducts | |
import co.tractionapp.domain.states.* | |
import co.tractionapp.traction.R | |
import co.tractionapp.traction.exts.message | |
import co.tractionapp.traction.exts.observe | |
import co.tractionapp.traction.exts.withViewModel | |
import co.tractionapp.traction.factory.interfaces.FactoryEventsAdapter | |
import co.tractionapp.traction.factory.models.UIField | |
import co.tractionapp.traction.factory.models.uiFields.* | |
import co.tractionapp.traction.factory.pageFactory.ProductFactory | |
import co.tractionapp.traction.factory.pageFactory.ProductFactory.Keys.CategoryKey | |
import co.tractionapp.traction.factory.pageFactory.ProductFactory.Keys.HasVariationKey | |
import co.tractionapp.traction.factory.pageFactory.ProductFactory.Keys.ItemNameKey | |
import co.tractionapp.traction.factory.pageFactory.ProductFactory.Keys.PriceKey | |
import co.tractionapp.traction.main.Constants | |
import co.tractionapp.traction.main.Constants.ITEM_NAME | |
import co.tractionapp.traction.main.Constants.SELLING_PRICE | |
import co.tractionapp.traction.main.pages.products.interfaces.CreateProductCallback | |
import co.tractionapp.traction.main.pages.products.vms.ProductCreateItemVM | |
import co.tractionapp.traction.main.pages.products.vms.ProductCreateVMFactory | |
import co.tractionapp.traction.main.pages.settings.enums.TourGuideEnum | |
import co.tractionapp.traction.main.pages.settings.support.TourGuideMap | |
import co.tractionapp.traction.main.sharedScreens.PagesFragment | |
import it.sephiroth.android.library.xtooltip.ClosePolicy | |
import it.sephiroth.android.library.xtooltip.Tooltip | |
import kotlinx.android.synthetic.main.dialog_barcode_action.view.* | |
import kotlinx.android.synthetic.main.item_contained_outline_button.* | |
import kotlinx.android.synthetic.main.page_item_preview.* | |
import kotlinx.android.synthetic.main.page_product_create.* | |
import pub.devrel.easypermissions.EasyPermissions | |
open class ProductCreateItem : PagesFragment(), EasyPermissions.PermissionCallbacks { | |
private var productsVM: ProductCreateItemVM? = null | |
private var tractionProducts: TractionProducts? = null | |
private var isEditProduct: Boolean = false | |
lateinit var variantInEdit: ProductVariantField | |
private var itemListener: CreateProductCallback? = null | |
private var handler: Handler? = null | |
private var productName: String? = null | |
private var productSellingPrice: String? = null | |
private var isCreateProductTour = false | |
companion object { | |
fun newInstance(tractionProducts: TractionProducts?, listener: CreateProductCallback): ProductCreateItem { | |
val arg = Bundle().apply { | |
putSerializable(Constants.DATA_KEY, tractionProducts) | |
} | |
return ProductCreateItem().apply { | |
setCreateProductListener(listener) | |
arguments = arg | |
} | |
} | |
} | |
val RC_STORAGE = 1 | |
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { | |
activity?.onBackPressed() | |
} | |
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) { | |
ui() | |
} | |
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { | |
return inflater.inflate(R.layout.page_product_create, container, false) | |
} | |
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | |
super.onViewCreated(view, savedInstanceState) | |
EasyPermissions.requestPermissions( | |
this, getString(R.string.rationale_storage), | |
RC_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE | |
, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA | |
) | |
} | |
private fun ui() { | |
arguments?.getSerializable("data")?.let { | |
tractionProducts = it as TractionProducts | |
isEditProduct = true | |
} | |
itemListener?.onSaveProductItem(factoryItemsAdapter) | |
isCreateProductTour = TourGuideMap.isKeyedTourActive(TourGuideEnum.PRODUCT_TOUR.name) | |
updateProductFromRecordSalesOrExistingProductList() | |
productsVM = withViewModel(ProductCreateVMFactory(tractionProducts)) { | |
observe(productsData, ::update) | |
observe(productCreate, ::productCreationUpdate) | |
observe(enableSaveBtn, ::saveBtnStateObs) | |
} | |
clickListeners() | |
recyclerAdapterListener() | |
} | |
private fun updateProductFromRecordSalesOrExistingProductList() { | |
activity?.let { | |
productName = it.intent.getStringExtra(ITEM_NAME) | |
productSellingPrice = it.intent.getStringExtra(SELLING_PRICE) | |
} | |
if(isEditProduct) { | |
tractionProducts = TractionProducts( | |
name = productName ?: tractionProducts!!.name, | |
price = productSellingPrice?.toDouble() ?: tractionProducts!!.price, | |
category = tractionProducts?.category ?: "", | |
costPrice = tractionProducts?.costPrice ?: 0.0, | |
description = tractionProducts?.description ?: "", | |
image = tractionProducts?.image ?: "", | |
stock = tractionProducts?.stock, | |
manage_stock = tractionProducts?.manage_stock ?: false, | |
in_stock = tractionProducts?.in_stock ?: false, | |
sku = tractionProducts?.sku, | |
variations = tractionProducts?.variations ?: false, | |
varieties = tractionProducts?.varieties ?: mutableListOf(), | |
combo = tractionProducts?.combo ?: false, | |
combos = tractionProducts?.combos ?: mutableListOf(), | |
store_stock = tractionProducts?.store_stock ?: mutableListOf() | |
) | |
} | |
} | |
private fun saveBtnStateObs(shouldEnableSaveBtn: Boolean?) { | |
shouldEnableSaveBtn?.let { | |
val createMain = this@ProductCreateItem.parentFragment as? ProductCreateMain | |
createMain?.btn_action_field?.let { btn -> | |
btn.isEnabled = it | |
} | |
} | |
} | |
private fun recyclerAdapterListener() { | |
factory_recycler.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { | |
override fun onGlobalLayout() { | |
if (isCreateProductTour) { | |
startProductItemCreateTour() | |
} | |
val itemInd = factoryItemsAdapter.fieldIndexWithKey(ItemNameKey) | |
val categoryInd = factoryItemsAdapter.fieldIndexWithKey(CategoryKey) | |
val priceInd = factoryItemsAdapter.fieldIndexWithKey(PriceKey) | |
if (itemInd != -1 && categoryInd != -1 && priceInd != -1) { | |
productsVM?.validCreateItemEnableSaveBtn(factoryItemsAdapter) | |
factory_recycler.viewTreeObserver.removeOnGlobalLayoutListener(this) | |
} | |
} | |
}) | |
} | |
private fun startProductItemCreateTour() { | |
val adcView = factoryItemsAdapter.fieldWithKey(ItemNameKey)?.fieldItemView() | |
adcView?.let { | |
showToolTip(it, R.string.enter_product_name_with_example, | |
closePolicy = ClosePolicy.TOUCH_ANYWHERE_CONSUME) | |
} | |
} | |
private fun clickListeners() { | |
setAdapterEvent(object : FactoryEventsAdapter() { | |
override fun onActionFieldClicked(uiFieldKey: String, checked: Boolean) { | |
when (uiFieldKey) { | |
HasVariationKey -> { | |
if (!factoryItemsAdapter.isOnBind()) { | |
productsVM?.switchFormBasedOnVariations( | |
factoryItemsAdapter, | |
tractionProducts, | |
checked | |
) | |
productsVM?.deleteCachedVariants() | |
} | |
productsVM?.validCreateItemEnableSaveBtn(factoryItemsAdapter) | |
} | |
ItemNameKey -> { | |
if (isCreateProductTour) { | |
val categoryIndex = factoryItemsAdapter.fieldIndexWithKey(CategoryKey) | |
val categoryView = factoryItemsAdapter.fieldWithKey(CategoryKey)?.fieldItemView() | |
factory_recycler.scrollToPosition(categoryIndex) | |
// tour tooltip | |
categoryView?.let { | |
showToolTip(it, R.string.select_item_category) | |
} | |
} | |
} | |
PriceKey -> { | |
if (isCreateProductTour) { | |
val lastIndex = factoryItemsAdapter.items().lastIndex | |
factory_recycler.scrollToPosition(lastIndex) | |
val createMain = | |
this@ProductCreateItem.parentFragment as? ProductCreateMain | |
createMain?.include8?.let { | |
showToolTip(it, R.string.click_on_save, Tooltip.Gravity.TOP) | |
} | |
} | |
} | |
} | |
} | |
override fun onItemClicked(uiField: UIField, params: Any) { | |
when (uiField) { | |
is ProductImageField -> { | |
showCameraSelectDialog() | |
} | |
is OutlineTextInputField -> { | |
tooltip?.dismiss() | |
selectCategory() | |
} | |
is RoundedCornerInputField -> { | |
productsVM?.validCreateItemEnableSaveBtn(factoryItemsAdapter) | |
} | |
is AmountRoundInputField -> { | |
productsVM?.validCreateItemEnableSaveBtn(factoryItemsAdapter) | |
} | |
is AddItemField -> { | |
if (uiField.key == ProductFactory.Keys.AddVariationItemKey) { | |
addProductVariant() | |
} else { | |
selectProduct() | |
} | |
} | |
is BarcodeField -> { | |
showBarcodeDialog() | |
} | |
is ProductVariantField -> { | |
variantInEdit = uiField | |
editProductVariant(variantInEdit.dataSource as TractionProductVariants) | |
} | |
} | |
} | |
}) | |
} | |
private fun showBarcodeDialog() { | |
val dialog = Dialog(requireContext(), android.R.style.Theme_Translucent).also { | |
it.requestWindowFeature(Window.FEATURE_NO_TITLE) | |
val view = LayoutInflater.from(context).inflate(R.layout.dialog_barcode_action, null, false).apply { | |
btn_generate_code.setOnClickListener { _ -> | |
showProgress() | |
productsVM?.generateBarcode() | |
it.dismiss() | |
} | |
btn_scan_code.setOnClickListener { _ -> | |
it.dismiss() | |
scanBarcode() | |
} | |
container.setOnClickListener { _ -> | |
it.dismiss() | |
} | |
} | |
it.setContentView(view) | |
} | |
dialog.show() | |
} | |
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
super.onActivityResult(requestCode, resultCode, data) | |
if (requestCode == REQUEST_CAPTURE_IMAGE && resultCode == RESULT_OK) { | |
handler = Handler(Looper.getMainLooper()) | |
itemListener?.onSaveProductItem(factoryItemsAdapter) ?: kotlin.run { | |
itemListener = this.parentFragment as ProductCreateMain | |
itemListener?.onSaveProductItem(factoryItemsAdapter) | |
} | |
handler?.postDelayed( | |
{ | |
productsVM?.updateProductImage(factoryItemsAdapter, photoPathUri.toString()) | |
}, 1000 | |
) | |
} else { | |
data?.let { | |
it.data?.let { | |
activity?.grantUriPermission(requireContext().packageName, it, Intent.FLAG_GRANT_READ_URI_PERMISSION) | |
val takeFlags = data.flags and Intent.FLAG_GRANT_READ_URI_PERMISSION | |
context?.contentResolver?.takePersistableUriPermission(it, takeFlags) | |
productsVM?.updateProductImage(factoryItemsAdapter, it.toString()) | |
} | |
} | |
} | |
if (requestCode == ADD_PRODUCT_VARIANT && resultCode == RESULT_OK) { | |
(data?.getSerializableExtra("data") as TractionProductVariants).let { | |
productsVM?.addProductVariantItemToList(factoryItemsAdapter, it) | |
} | |
} | |
if (requestCode == EDIT_PRODUCT_VARIANT && resultCode == RESULT_OK) { | |
(data?.getSerializableExtra("data") as TractionProductVariants).let { | |
val editedId = (variantInEdit.dataSource as TractionProductVariants).id | |
productsVM?.editProductVariantItemToList(factoryItemsAdapter, it, editedId) | |
} | |
} | |
if (requestCode == PICK_CATEGORY && resultCode == RESULT_OK) { | |
(data?.getSerializableExtra("data") as TractionProductCategory).let { | |
productsVM?.updateCategoryName(factoryItemsAdapter, it.name) | |
productsVM?.validCreateItemEnableSaveBtn(factoryItemsAdapter) | |
if (isCreateProductTour) { | |
val sellingPriceIndex = factoryItemsAdapter.fieldIndexWithKey(PriceKey) | |
val sellingPriceView = factoryItemsAdapter.fieldWithKey(PriceKey)?.fieldItemView() | |
factory_recycler.scrollToPosition(sellingPriceIndex) | |
sellingPriceView?.let { | |
showToolTip(it, R.string.enter_item_price, closePolicy = ClosePolicy.TOUCH_ANYWHERE_CONSUME) | |
} | |
} | |
} | |
} | |
if (requestCode == SCAN_BARCODE && resultCode == RESULT_OK) { | |
passBarcodeToView(data?.getStringExtra("data")!!) | |
} | |
} | |
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { | |
super.onRequestPermissionsResult(requestCode, permissions, grantResults) | |
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) | |
} | |
private fun productCreationUpdate(state: DataStates?) { | |
state?.let { | |
dismissProgress() | |
when (it) { | |
is ProductCreated -> activity?.onBackPressed() | |
is FailedNoBusiness -> context?.message("you do not have an active registered business") | |
is DataResponseError -> { | |
it.cause?.message?.let { | |
context?.message(it) | |
} | |
} | |
is BarcodeGenerated -> { | |
passBarcodeToView(it.data!!) | |
} | |
is FailedOperation -> { | |
context?.message(it.message) | |
} | |
else -> {} | |
} | |
} | |
} | |
private fun passBarcodeToView(barcode: String) { | |
productsVM?.updateBarcodeField(factoryItemsAdapter, barcode) | |
} | |
override fun onDestroyView() { | |
super.onDestroyView() | |
productsVM?.productsData?.removeObservers(this) | |
productsVM?.productCreate?.removeObservers(this) | |
tooltip?.dismiss() | |
handler?.removeCallbacksAndMessages(this) | |
handler = null | |
} | |
fun setCreateProductListener(listener: CreateProductCallback) { | |
itemListener = listener | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment