diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7dded68b..921e1813 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,8 +16,8 @@ android { applicationId = "es.verdnatura" minSdk = 26 targetSdk = 33 // se deja con target si no Play Protect la bloquea - versionCode = 397 //JAF 393 en informatica - versionName = "25.6" + versionCode = 405 + versionName = "25.12" // REvisor para reservas testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -149,36 +149,30 @@ android { //implementation(libs.koin.androidx.compose) // Compose - dependencies { - val composeBom = platform("androidx.compose:compose-bom:2024.10.01") - implementation(composeBom) - androidTestImplementation(composeBom) - - // Choose one of the following: - // Material Design 3 - implementation(libs.androidx.material3) - implementation(libs.androidx.ui) - // Android Studio Preview support - implementation(libs.androidx.ui.tooling.preview) - debugImplementation(libs.androidx.ui.tooling) - // UI Tests - androidTestImplementation(libs.androidx.ui.test.junit4) - debugImplementation(libs.androidx.ui.test.manifest) - // custom design system based on Foundation) - //implementation(libs.androidx.material.icons.core) - // Optional - Add full set of material icons - implementation(libs.androidx.material.icons.extended) - // Optional - Add window size utils - implementation(libs.androidx.adaptive) - implementation(libs.androidx.activity.compose) - implementation(libs.androidx.lifecycle.viewmodel.compose) - implementation(libs.lottie.compose) - - } + val composeBom = platform("androidx.compose:compose-bom:2024.10.01") + implementation(composeBom) + androidTestImplementation(composeBom) + // Choose one of the following: + // Material Design 3 + implementation(libs.androidx.material3) + implementation(libs.androidx.ui) + // Android Studio Preview support + implementation(libs.androidx.ui.tooling.preview) + debugImplementation(libs.androidx.ui.tooling) + // UI Tests + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.test.manifest) + // custom design system based on Foundation) + //implementation(libs.androidx.material.icons.core) + // Optional - Add full set of material icons + implementation(libs.androidx.material.icons.extended) + // Optional - Add window size utils + implementation(libs.androidx.adaptive) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.lifecycle.viewmodel.compose) + implementation(libs.lottie.compose) + testImplementation(libs.junit) } } -dependencies { - testImplementation(libs.junit) -} diff --git a/app/src/main/java/es/verdnatura/MobileApplication.kt b/app/src/main/java/es/verdnatura/MobileApplication.kt index fbe56783..d44480bb 100644 --- a/app/src/main/java/es/verdnatura/MobileApplication.kt +++ b/app/src/main/java/es/verdnatura/MobileApplication.kt @@ -7,6 +7,7 @@ import android.media.MediaPlayer import android.os.Bundle import android.os.Handler import android.os.Looper +import android.widget.Toast import es.verdnatura.dataStore.DataStoreLocal import es.verdnatura.di.viewModelModule import es.verdnatura.domain.ConstAndValues @@ -120,7 +121,8 @@ class MobileApplication : Application(), InteceptorListener { Color.RED } else { Color.BLUE - } + }, + duration = if (isError) Toast.LENGTH_LONG else Toast.LENGTH_SHORT ) } diff --git a/app/src/main/java/es/verdnatura/di/viewModelModule.kt b/app/src/main/java/es/verdnatura/di/viewModelModule.kt index dc421ade..f8df89e2 100644 --- a/app/src/main/java/es/verdnatura/di/viewModelModule.kt +++ b/app/src/main/java/es/verdnatura/di/viewModelModule.kt @@ -14,6 +14,7 @@ import es.verdnatura.presentation.view.feature.collection.fragment.CollectionVie import es.verdnatura.presentation.view.feature.controlvehiculo.fragment.ControlVehiculoViewModel import es.verdnatura.presentation.view.feature.delivery.viewmodels.DeliveryViewModel import es.verdnatura.presentation.view.feature.diadeventa.fragment.DayOfSaleViewModel +import es.verdnatura.presentation.view.feature.diadeventa.fragment.DayOfSaleViewModelCompose import es.verdnatura.presentation.view.feature.historicoarticulo.fragment.HistoricoArticuloViewModel import es.verdnatura.presentation.view.feature.historicoshelvinglog.fragment.ShelvingLogViewModel import es.verdnatura.presentation.view.feature.inventario.fragment.InventaryViewModel @@ -23,6 +24,7 @@ import es.verdnatura.presentation.view.feature.packingHolland.fragment.PackingHo import es.verdnatura.presentation.view.feature.paletizador.fragment.CmrExpeditionPalletViewModel import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionPalletDetailViewModel import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionScanSorterViewModel +import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionScanSorterViewModelCompose import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionScanViewModel import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionStateViewModel import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionTruckListViewModel @@ -36,6 +38,7 @@ import es.verdnatura.presentation.view.feature.sacador.fragment.SacadorViewModel import es.verdnatura.presentation.view.feature.sacador.fragment.showticket.ShowTicketViewModel import es.verdnatura.presentation.view.feature.ticket.fragment.TicketViewModel import es.verdnatura.presentation.view.feature.ubicador.fragment.UbicadorViewModel +import es.verdnatura.presentation.view.feature.workermistake.fragment.WorkerMistakeViewModel import org.koin.android.ext.koin.androidApplication import org.koin.android.ext.koin.androidContext import org.koin.androidx.viewmodel.dsl.viewModel @@ -43,9 +46,9 @@ import org.koin.dsl.module val viewModelModule = module { - /* viewModel { - WorkermistakeViewModel() - }*/ + viewModel { + WorkerMistakeViewModel(androidApplication()) + } // Login viewModel { @@ -60,6 +63,9 @@ val viewModelModule = module { viewModel { DayOfSaleViewModel(androidContext()) } + viewModel { + DayOfSaleViewModelCompose(androidApplication()) + } // Pasilleros / Item Card viewModel { @@ -107,6 +113,10 @@ val viewModelModule = module { ExpeditionScanSorterViewModel(androidContext()) } + viewModel { + ExpeditionScanSorterViewModelCompose(androidApplication()) + } + viewModel { CmrExpeditionPalletViewModel(androidContext()) diff --git a/app/src/main/java/es/verdnatura/domain/ConstAndValues.kt b/app/src/main/java/es/verdnatura/domain/ConstAndValues.kt index bc0f690d..12684a74 100644 --- a/app/src/main/java/es/verdnatura/domain/ConstAndValues.kt +++ b/app/src/main/java/es/verdnatura/domain/ConstAndValues.kt @@ -73,6 +73,8 @@ object ConstAndValues { const val MODELWORKERTYPEACTIVITY = "APP" const val FLINGTHRESHOLDVELOCITY = 2000f const val FLINGTHRESHOLDVERTICAL = 500f + const val SCANNER_THRESHOLD_SPEED: Int = 60 + const val HUMAN_CHARACTERS_SECOND: Int = 100 } diff --git a/app/src/main/java/es/verdnatura/domain/SalixCallback.kt b/app/src/main/java/es/verdnatura/domain/SalixCallback.kt index 96c802d7..3962fd34 100644 --- a/app/src/main/java/es/verdnatura/domain/SalixCallback.kt +++ b/app/src/main/java/es/verdnatura/domain/SalixCallback.kt @@ -50,7 +50,7 @@ abstract class SalixCallback(val context: Context) : Callback { } } - private fun defaultErrorHandler(t: Throwable) { + fun defaultErrorHandler(t: Throwable) { //println("ErrorSalixx${t.message}") // (nameofFunction((this)) + t.message).toast(context) (context as MobileApplication).messageToast( diff --git a/app/src/main/java/es/verdnatura/domain/SalixService.kt b/app/src/main/java/es/verdnatura/domain/SalixService.kt index f025d4a6..97edf1e3 100644 --- a/app/src/main/java/es/verdnatura/domain/SalixService.kt +++ b/app/src/main/java/es/verdnatura/domain/SalixService.kt @@ -210,6 +210,11 @@ interface SalixService { ): Call + @GET("Sips/findOne") + fun sipGetExtension( + @Query("filter") filter: String, + ): Call + @GET("Workers/Summary") fun getNameWorker( @Query("filter") filter: String @@ -403,7 +408,8 @@ interface SalixService { fun addSale( @Path("id") id: Number, @Query("quantity") quantity: Number, - @Query("barcode") barcode: String + @Query("barcode") barcode: String, + @Query("isAdded") isAdded: Boolean = true ): Call @POST("Collections/assign") @@ -892,6 +898,11 @@ interface SalixService { @Body parms: PackingSiteSalix ): Call + @GET("Tickets/{id}/exists") + fun ticketExists( + @Path("id") id: Number, + ): Call + @PUT("ItemBarCodes") fun barcodesEdit( @Body params: ItemBarCodeSalix @@ -1044,11 +1055,17 @@ interface SalixService { @Path("id") id: Number ): Call - @POST("ItemShelvingSales/itemShelvingSale_addByCollection") + @POST("Applications/itemShelvingSale_addByCollection/execute-proc") fun itemShelvingSaleAddByCollection( - @Body params: Any, + @Query("schema") schema: String = "vn", + @Query("params") params: Any? = null ): Call + /* @POST("ItemShelvingSales/itemShelvingSale_addByCollection") + fun itemShelvingSaleAddByCollection( + @Body params: Any, + ): Call*/ + @POST("ItemShelvings/getInventory") fun getInventoryParking( @Query("parkingFrom") parkingFrom: String, @Query("parkingTo") parkingTo: String diff --git a/app/src/main/java/es/verdnatura/domain/userCases/UserCases.kt b/app/src/main/java/es/verdnatura/domain/userCases/UserCases.kt index f9cc291d..16982e23 100644 --- a/app/src/main/java/es/verdnatura/domain/userCases/UserCases.kt +++ b/app/src/main/java/es/verdnatura/domain/userCases/UserCases.kt @@ -2,6 +2,7 @@ package es.verdnatura.domain.userCases import es.verdnatura.domain.SalixService import es.verdnatura.presentation.view.feature.packaging.model.NotificationQueue +import es.verdnatura.presentation.view.feature.pasillero.model.WorkerActionSalix import retrofit2.Call class GetItemFromBarcodeUseCase(private val salixService: SalixService) { @@ -25,3 +26,18 @@ class NotiticationUseCase(private val salixService: SalixService) { return salixService.notificationQueues(notificationQueue) } } + +class WorkerActivityUseCase(private val salixService: SalixService) { + fun addWorkerActivity(workerActionSalix: WorkerActionSalix): Call { + return salixService.workerActivityAdd(workerActionSalix) + } +} + +class OperatorUseCase(private val salixService: SalixService) { + fun updateOperator(workerFk: Number, update: HashMap): Call { + return salixService.updateOperator( + id = workerFk, + params = update + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/base/BaseFragment.kt b/app/src/main/java/es/verdnatura/presentation/base/BaseFragment.kt index ac212456..c0bec4c3 100644 --- a/app/src/main/java/es/verdnatura/presentation/base/BaseFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/base/BaseFragment.kt @@ -136,6 +136,8 @@ abstract class BaseFragment( R.drawable.ic_sign_ticket -> getString(R.string.signed) R.drawable.ic_send -> getString(R.string.sendDriverRoute) R.drawable.ic_add_multiple -> getString(R.string.addItemMultipleShelvings) + R.drawable.ic_clean_shelving -> getString(R.string.activityOrganize) + R.drawable.ic_booking -> getString(R.string.bookingNewSalesCollection) else -> { "" } diff --git a/app/src/main/java/es/verdnatura/presentation/common/PrinterDialogManager.kt b/app/src/main/java/es/verdnatura/presentation/common/PrinterDialogManager.kt index 84b6f52b..07eecfcd 100644 --- a/app/src/main/java/es/verdnatura/presentation/common/PrinterDialogManager.kt +++ b/app/src/main/java/es/verdnatura/presentation/common/PrinterDialogManager.kt @@ -4,13 +4,18 @@ import android.app.AlertDialog import android.content.Context import android.text.InputType import android.view.View +import android.view.inputmethod.EditorInfo import es.verdnatura.R import es.verdnatura.domain.toast +import es.verdnatura.presentation.view.component.CustomDialogInput import es.verdnatura.presentation.view.component.CustomDialogList class PrinterDialogManager(private val context: Context) { fun showPrintDialog( - item: Long, itemName: String, onPrintClick: (Long, String, Int?, Int) -> Unit + item: Long, + itemName: String, + onPrintClick: (Long, String, Int?, Int) -> Unit, + onPrintChange: (String) -> Unit ) { val customDialogList = CustomDialogList(context) customDialogList.getEditText().setRawInputType(InputType.TYPE_CLASS_NUMBER) @@ -23,7 +28,9 @@ class PrinterDialogManager(private val context: Context) { }.setOkTwoButton(context.getString(R.string.printBarcode)) { handlePrintClick(item, customDialogList, onPrintClick, "barcode") customDialogList.dismiss() - + //Tarea 7823 + }.setOkThreeButton(context.getString(R.string.changePrinter)) { + readQrPrinter(onPrintChange) }.setKoButton(context.getString(R.string.cancel)) { customDialogList.dismiss() }.setHintValueThree(context.getString(R.string.labelNumber)) @@ -32,6 +39,30 @@ class PrinterDialogManager(private val context: Context) { customDialogList.getFocusThree() } + private fun readQrPrinter(onPrintChange: (String) -> Unit) { + val customDialogInput = CustomDialogInput(context) + + customDialogInput.setTitle(context.getString(R.string.changePrinter)) + .setDescription(context.getString(R.string.scanQrPrinter)) + .setOkButton(context.getString(R.string.save)) { + onPrintChange(customDialogInput.getValue()) + customDialogInput.dismiss() + + }.setKoButton(context.getString(R.string.cancel)) { + customDialogInput.dismiss() + }.setValue("").show() + customDialogInput.getEditText().requestFocus() + customDialogInput.getEditText().setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0) { + onPrintChange(customDialogInput.getValue()) + println("printerrr ${customDialogInput.getValue()}") + customDialogInput.dismiss() + return@setOnEditorActionListener true + } + false + } + } + private fun handlePrintClick( item: Long, customDialogList: CustomDialogList, diff --git a/app/src/main/java/es/verdnatura/presentation/common/SalixBackItems.kt b/app/src/main/java/es/verdnatura/presentation/common/SalixBackItems.kt index c52ada88..7870751a 100644 --- a/app/src/main/java/es/verdnatura/presentation/common/SalixBackItems.kt +++ b/app/src/main/java/es/verdnatura/presentation/common/SalixBackItems.kt @@ -26,9 +26,9 @@ data class SaleTrackingSalix( ) -class PackingSiteSalix( - var ticketFk: Int, - var workerFk: Int +data class PackingSiteSalix( + val ticketFk: Number, + val workerFk: Number ) diff --git a/app/src/main/java/es/verdnatura/presentation/common/itemScanned.kt b/app/src/main/java/es/verdnatura/presentation/common/itemScanned.kt index 5e91d4c1..37314edf 100644 --- a/app/src/main/java/es/verdnatura/presentation/common/itemScanned.kt +++ b/app/src/main/java/es/verdnatura/presentation/common/itemScanned.kt @@ -55,10 +55,15 @@ fun itemScanValue(value: String, table: Array, field: String): Any { "more" -> return item.more } } + "expeditionPallet" -> { return item.id } + "printer" -> { + return item.id + } + } } throw Exception("QR no válido") diff --git a/app/src/main/java/es/verdnatura/presentation/composable/CustomToolbar.kt b/app/src/main/java/es/verdnatura/presentation/composable/CustomToolbar.kt index ccae1833..c3aab7db 100644 --- a/app/src/main/java/es/verdnatura/presentation/composable/CustomToolbar.kt +++ b/app/src/main/java/es/verdnatura/presentation/composable/CustomToolbar.kt @@ -2,6 +2,7 @@ package es.verdnatura.presentation.composable import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -14,13 +15,18 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.PlainTooltip import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.TooltipBox +import androidx.compose.material3.TooltipDefaults +import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -29,7 +35,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.onFocusEvent import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.colorResource @@ -45,15 +50,16 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import es.verdnatura.R +@OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomToolbar( title: String, subtitle: String? = null, showBackButton: Boolean = true, showSwitch: Boolean = false, - iconList: List = emptyList(), + iconList: List = emptyList(), onBackClick: () -> Unit = {}, - onSwitchChange: (Boolean) -> Unit = {} + onSwitchChange: (Boolean) -> Unit = {}, ) { Column( modifier = Modifier @@ -66,8 +72,9 @@ fun CustomToolbar( .fillMaxWidth() .height(56.dp), verticalAlignment = CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween - ) { + ) { if (showBackButton) { IconButton( onClick = { onBackClick() }, @@ -81,6 +88,7 @@ fun CustomToolbar( } } Text( + modifier = Modifier.weight(1f), text = title, color = Color.White, fontSize = dimensionResource(id = R.dimen.title).value.sp, @@ -96,22 +104,40 @@ fun CustomToolbar( fontSize = dimensionResource(id = R.dimen.subtitle).value.sp ) } - } - if (iconList.isNotEmpty()) { - LazyRow { - items(iconList) { iconRes -> - IconButton(onClick = { /* Acción del icono */ }) { - Icon( - painter = painterResource(id = iconRes), - contentDescription = "Icon", - tint = Color.White - ) + if (iconList.isNotEmpty()) { + LazyRow( + horizontalArrangement = Arrangement.End, // Esto asegura que los iconos estén a la derecha + ) { + items(iconList) { iconToolBar -> + TooltipBox( + positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(), + tooltip = { + PlainTooltip { + Text(iconToolBar.toolTip) + } + }, + state = rememberTooltipState() + ) { + IconButton( + onClick = { iconToolBar.onClickIcon() }, + ) { + + Icon( + painter = painterResource(id = iconToolBar.idRes), + contentDescription = iconToolBar.toolTip, + tint = Color.White + ) + } + } } } } + } + + if (showSwitch) { var switchState by remember { mutableStateOf(false) } Switch( @@ -131,6 +157,14 @@ fun CustomToolbar( ) } +data class IconToolBar( + val idRes: Int, + val toolTip: String = "", + val tint: Color = Color.White, + val onClickIcon: () -> Unit, + + ) + @Composable fun ScanLineTextSearch( value: String, @@ -153,17 +187,23 @@ fun ScanLineTextSearch( textAlign = TextAlign.Center ), placeholder = { - Text( - text = stringResource(id = R.string.Escaneaetiqueta), - textAlign = TextAlign.Center, - color = Color.White, - modifier = Modifier.fillMaxWidth() - ) + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + Text( + text = stringResource(id = R.string.Escaneaetiqueta), + textAlign = TextAlign.Center, + color = Color.White, + modifier = Modifier.fillMaxWidth() + ) + } }, singleLine = true, keyboardActions = KeyboardActions( onDone = { onImeAction() + keyboardController?.hide() } ), @@ -182,13 +222,12 @@ fun ScanLineTextSearch( modifier = modifier .fillMaxWidth(fraction = 0.67f) .border(2.dp, Color.White, RoundedCornerShape(8.dp)) - .height(54.dp) - .padding(bottom = 4.dp) - .onFocusEvent { + .height(52.dp) + /* .onFocusEvent { if (it.isFocused) { keyboardController?.hide() } - } + }*/ ) } @@ -202,7 +241,12 @@ fun PreviewToolbar() { subtitle = "10/20", showBackButton = true, showSwitch = true, - iconList = listOf(R.drawable.ic_launcher_foreground, R.drawable.ic_launcher_foreground), + iconList = listOf( + IconToolBar( + R.drawable.ic_parking_ui, "", tint = Color.Blue, + onClickIcon = { } + ) + ), onBackClick = { /* Acción de volver atrás */ }, onSwitchChange = { /* Acción del switch */ } ) @@ -212,7 +256,7 @@ fun PreviewToolbar() { @Composable fun PreviewScanLineTextSearch() { ScanLineTextSearch( - value = "Escanea etiqueta", + value = stringResource(R.string.scanLabel), onValueChange = {}, onImeAction = {}) } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/LottieLoadingAnimation.kt b/app/src/main/java/es/verdnatura/presentation/composable/LottieLoadingAnimation.kt similarity index 94% rename from app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/LottieLoadingAnimation.kt rename to app/src/main/java/es/verdnatura/presentation/composable/LottieLoadingAnimation.kt index eb03b272..aae98753 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/LottieLoadingAnimation.kt +++ b/app/src/main/java/es/verdnatura/presentation/composable/LottieLoadingAnimation.kt @@ -1,4 +1,4 @@ -package es.verdnatura.presentation.view.feature.buscaritem.fragment +package es.verdnatura.presentation.composable import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn diff --git a/app/src/main/java/es/verdnatura/presentation/composable/ui/VerdnaturaColors.kt b/app/src/main/java/es/verdnatura/presentation/composable/ui/VerdnaturaColors.kt new file mode 100644 index 00000000..62c6fe29 --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/composable/ui/VerdnaturaColors.kt @@ -0,0 +1,72 @@ +package es.verdnatura.presentation.composable.ui + +import androidx.compose.ui.graphics.Color + +object VerdnaturaColors { + + val OrangeSalix = Color(0xFFEC8916) + val BlackCustomDialog = Color(0xFF1A1A1A) + val BlackTextInput = Color(0xFF666666) + val White = Color(0xFFFFFFFF) + + // Colores principales + val ColorPrimary = Color(0xFFF7931E) + val ColorPrimaryDark = Color(0xFF8B4200) + + // Negros + /* val Black = Color(0xFF000000) + val Black1 = Color(0xFF1D1D1D) + val Black2 = Color(0xFF171717) + val Black3 = Color(0xFF292929) + val Black4 = Color(0xFF242424) + val Black5 = Color(0xFF323232) + val Black6 = Color(0xFF333333) + val Black7 = Color(0xFF282828) + val Black8 = Color(0xFF1A1A1A) + val BlackCustomDialog = Color(0xFF464446) + val Black8Alpha6 = Color(0x991A1A1A) // Con transparencia + + // Grises + val WarmGrey = Color(0xFF707070) + val BrownGrey = Color(0xFF8F8F8F) + val BrownGreyLight = Color(0xFFB8ADAD) + + // Colores vivos + val Red = Color(0xFFE74C3C) + val WarmBrown = Color(0xFF8B4200) + val PumpkinOrange = Color(0xFFF7931E) + val PumpkinLight = Color(0xFFF77956) + val PinkSalix = Color(0xFFFF99CC) + val SunflowerYellow = Color(0xFFFFD400) + val DarkSkyBlue = Color(0xFF4AB4E6) + val DarkGreenVerdnatura = Color(0xFFA3D131) + val DarkMint = Color(0xFF50BE87) + val DarkMintLight = Color(0xFF80BE87) + val DarkMintLightPrecontrolled = Color(0xFFB8DABA) + val LightTeal = Color(0xFFB8ECD6) + val White = Color(0xFFFFFFFF) + val RedSalix = Color(0xFFFB5252) + val OrangeSalix = Color(0xFFEC8916) + + // Fondos + val BackgroundItemPicker = Color(0xFF4D4D4D) + val BackgroundSubtitleSettings = Color(0xFF1A1A1A) + val BackgroundItemsMenus = Color(0xFF333333) + + // Colores SALIX + val SalixSuccessLight = Color(0xFFA3D131) + val ColorHeader = Color(0xFF3D3D3D) + val ColorMenuHeader = Color(0xFF3D3D3D) + val ColorBg = Color(0xFF222222) + val ColorBgDark = Color(0xFF222222) + val ColorActive = Color(0xFF666666) + val ColorActiveFont = Color(0xFFFFFFFF) + val ColorBgPanel = Color(0xFF3C3B3B) + val ColorMain = ColorPrimary + val ColorMarginal = Color(0xFF222222) + val ColorSuccess = Color(0xFFA3D131) + val ColorNotice = Color(0xFF32B1CE) + val ColorAlert = Color(0xFFFA3939) + val ColorPink = Color(0xFFFF99CC) + val ColorYellow = Color(0xFFFFFF00)*/ +} \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/composable/ui/defaultComponents.kt b/app/src/main/java/es/verdnatura/presentation/composable/ui/defaultComponents.kt new file mode 100644 index 00000000..9914448e --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/composable/ui/defaultComponents.kt @@ -0,0 +1,168 @@ +package es.verdnatura.presentation.composable.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@Composable +fun DefaultButtonCustomDialog( + text: String, + onClick: () -> Unit = {}, + enabled: Boolean = true, + leadingIcon: @Composable (() -> Unit)? = null +) { + Button( + modifier = Modifier.fillMaxWidth(), + onClick = onClick, + enabled = enabled, + contentPadding = PaddingValues( + start = if (leadingIcon == null) 16.dp else 8.dp, + end = 16.dp + ), + shape = MaterialTheme.shapes.small, + colors = ButtonDefaults.buttonColors( + containerColor = VerdnaturaColors.ColorPrimary, + contentColor = VerdnaturaColors.White + ) + ) { + if (leadingIcon != null) { + leadingIcon() + } + + Text( + text = text.uppercase(), + fontSize = 14.sp, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } +} + +@Composable +fun TitleTextCustomDialog( + title: String, +) { + Text( + text = title, + style = MaterialTheme.typography.titleLarge.copy( + fontWeight = FontWeight.Bold + ), + color = VerdnaturaColors.White, + textAlign = TextAlign.Center, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp) + ) +} + +@Composable +fun DescriptionTextCustomDialog( + description: String, +) { + Text( + text = description, + color = VerdnaturaColors.White, + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.padding(bottom = 8.dp) + ) +} + +@Composable +fun ScanTextCustomDialog( + value: TextFieldValue, + onValueChange: (TextFieldValue) -> Unit, + hint: String, + onEnterPressed: (String) -> Unit = {}, + focusRequester: FocusRequester +) { + val keyboardController = LocalSoftwareKeyboardController.current + + TextField( + value = value, + onValueChange = onValueChange, + label = { + Text( + text = hint, + textAlign = TextAlign.Center, + color = Color.White, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + ) + }, + modifier = Modifier + .fillMaxWidth() + .focusRequester(focusRequester) + .border(1.dp, Color.White, shape = MaterialTheme.shapes.small) + .background(Color.Transparent) + .height(VerdnaturaDimens.minHeight), + textStyle = CustomTextStyle, + keyboardOptions = + KeyboardOptions.Default.copy( + imeAction = ImeAction.Done, + keyboardType = KeyboardType.Number + ), + singleLine = true, + keyboardActions = KeyboardActions( + onDone = { + onEnterPressed(value.text) + onValueChange(TextFieldValue("")) + keyboardController?.hide() + } + ), + colors = TextFieldDefaults.colors( + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + focusedTextColor = VerdnaturaColors.White, + unfocusedTextColor = VerdnaturaColors.White + ) + ) + LaunchedEffect(Unit) { + focusRequester.requestFocus() + } +} + +@Preview(showBackground = true) +@Composable +fun PreviewCustomTextField() { + val sampleText = remember { mutableStateOf(TextFieldValue("Texto de ejemplo")) } + val focusRequester = remember { FocusRequester() } + ScanTextCustomDialog( + value = sampleText.value, + onValueChange = { sampleText.value = it }, + hint = "Escribe algo...", + onEnterPressed = { text -> println("Texto ingresado: $text") }, + focusRequester = focusRequester + ) +} \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/composable/ui/dimens.kt b/app/src/main/java/es/verdnatura/presentation/composable/ui/dimens.kt new file mode 100644 index 00000000..de3b3bdd --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/composable/ui/dimens.kt @@ -0,0 +1,23 @@ +package es.verdnatura.presentation.composable.ui + +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +object VerdnaturaDimens { + + /* val h1 = 96.sp + val h2 = 60.sp + val h3 = 48.sp + val h4 = 34.sp + val h5 = 24.sp + val h6 = 20.sp + val h7 = 18.sp + val h9 = 14.sp*/ + + // Text sizes + val fontSizeCustomDialogs = 16.sp + + // Height Scan Text + val minHeight = 48.dp + +} \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/composable/ui/themes.kt b/app/src/main/java/es/verdnatura/presentation/composable/ui/themes.kt new file mode 100644 index 00000000..2d3c356b --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/composable/ui/themes.kt @@ -0,0 +1,10 @@ +package es.verdnatura.presentation.composable.ui + +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign + +val CustomTextStyle = TextStyle( + color = VerdnaturaColors.White, + fontSize = VerdnaturaDimens.fontSizeCustomDialogs, + textAlign = TextAlign.Center +) \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/commom/SearchableAdapter.kt b/app/src/main/java/es/verdnatura/presentation/view/commom/SearchableAdapter.kt index eb9bdf47..561e7def 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/commom/SearchableAdapter.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/commom/SearchableAdapter.kt @@ -16,7 +16,8 @@ import es.verdnatura.domain.toast class SearchableAdapter( private var listElements: MutableList, private var context: Context, - private val onItemClick: (NameWithId) -> Unit, + private val listColorElements: List = listOf(), + private val onItemClick: (NameWithId) -> Unit ) : RecyclerView.Adapter() { private var listElementsFiltered = listElements.toMutableList() @@ -48,6 +49,13 @@ class SearchableAdapter( } catch (ex: Exception) { ex.message?.toast(context) } + if (listColorElements.isNotEmpty()) { + if (nameWithId.id in listColorElements) { + nameText.setTextColor(Color.BLACK) + } else { + nameText.setTextColor(Color.GRAY) + } + } } } diff --git a/app/src/main/java/es/verdnatura/presentation/view/component/CustomDialogList.kt b/app/src/main/java/es/verdnatura/presentation/view/component/CustomDialogList.kt index 94b41569..2b1ce6fa 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/component/CustomDialogList.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/component/CustomDialogList.kt @@ -96,6 +96,13 @@ class CustomDialogList(context: Context) : Dialog(context, R.style.DialogTheme) return this } + fun setOkThreeButton(text: String, onButtonClicked: () -> Unit): CustomDialogList { + binding.customDialogButtonOkThree.visibility = View.VISIBLE + binding.customDialogButtonOkThree.text = text + binding.customDialogButtonOkThree.setOnClickListener { onButtonClicked() } + return this + } + fun setKoButton(text: String, onButtonClicked: () -> Unit): CustomDialogList { binding.customDialogButtonKo.visibility = View.VISIBLE binding.customDialogButtonKo.text = text diff --git a/app/src/main/java/es/verdnatura/presentation/view/component/CustomDialogListComposable.kt b/app/src/main/java/es/verdnatura/presentation/view/component/CustomDialogListComposable.kt new file mode 100644 index 00000000..1d0dcf39 --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/component/CustomDialogListComposable.kt @@ -0,0 +1,130 @@ +package es.verdnatura.presentation.view.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import es.verdnatura.presentation.composable.ui.DefaultButtonCustomDialog +import es.verdnatura.presentation.composable.ui.DescriptionTextCustomDialog +import es.verdnatura.presentation.composable.ui.ScanTextCustomDialog +import es.verdnatura.presentation.composable.ui.TitleTextCustomDialog +import es.verdnatura.presentation.composable.ui.VerdnaturaColors + +@Composable +fun CustomDialogListComposable( + title: String = "", + description: String = "", + buttonOkText: String = "", + onOkClick: () -> Unit = {}, + showRecyclerView: Boolean = true, + recyclerViewItems: List = listOf(), + onItemSelected: (Any) -> Unit = {}, + hintOne: String = "", + showTextInput: Boolean = true, + onEnterPressed: (String) -> Unit = {} +) { + var valueOne by remember { mutableStateOf(TextFieldValue()) } + val showDialog = remember { mutableStateOf(true) } + val keyboardController = LocalSoftwareKeyboardController.current + val focusRequester = remember { FocusRequester() } + + if (showDialog.value) { + Dialog( + onDismissRequest = { showDialog.value = false }, + ) { + + Column( + modifier = Modifier + .background(VerdnaturaColors.BlackCustomDialog) + .padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + if (title.isNotEmpty()) { + TitleTextCustomDialog(title) + } + if (description.isNotEmpty()) { + DescriptionTextCustomDialog(description) + } + + if (showTextInput) + ScanTextCustomDialog( + value = valueOne, + onValueChange = { valueOne = it }, + hint = hintOne, + onEnterPressed = onEnterPressed, + focusRequester = focusRequester + ) + + Spacer(modifier = Modifier.height(8.dp)) + + if (showRecyclerView && recyclerViewItems.isNotEmpty()) { + LazyColumn( + modifier = Modifier.wrapContentWidth(align = Alignment.CenterHorizontally) + ) { + items(recyclerViewItems) { item -> + HorizontalDivider(thickness = 1.dp, color = Color.DarkGray) + Text( + text = item.toString(), + style = MaterialTheme.typography.bodyLarge, + color = VerdnaturaColors.White, + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + .clickable { + onItemSelected(item.toString()) + } + .align(Alignment.CenterHorizontally) + ) + } + } + } + + DefaultButtonCustomDialog(buttonOkText, onClick = { + onOkClick() + keyboardController?.hide() + }) + + } + } + } +} + +@Preview +@Composable +fun PreviewCustomDialogList() { + + CustomDialogListComposable( + title = "Custom Dialog Title", + description = "This is a description.", + buttonOkText = "OK", + onOkClick = { /* Handle OK click */ }, + showRecyclerView = true, + recyclerViewItems = listOf(1, 2, 3), + onItemSelected = { item -> println("Item selected: $item") }, + hintOne = "Hint for input one", + + ) +} diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/ajustes/fragment/AjustesFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/ajustes/fragment/AjustesFragment.kt index 1d3548f7..35f69558 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/ajustes/fragment/AjustesFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/ajustes/fragment/AjustesFragment.kt @@ -1,5 +1,6 @@ package es.verdnatura.presentation.view.feature.ajustes.fragment +import android.annotation.SuppressLint import android.app.AlertDialog import android.content.Intent import android.content.pm.PackageInfo @@ -86,46 +87,77 @@ class AjustesFragment : super.init() } - private fun setSearchable(listNames: MutableList) { + private fun setSearchable( + listNames: MutableList, + type: String = "sector", + listColorsElements: List = listOf() + ) { val adapter = SearchableAdapter( listElements = listNames, - context = requireContext() + context = requireContext(), + listColorElements = listColorsElements, ) { elementSelected -> - sectorListVO.forEach { - if (it.id == elementSelected.id) { - runBlocking { - mobileApplication.dataStoreApp.editDataStoreKey( - PRINTERNAME, getString(R.string.noprinter) - ) - mobileApplication.dataStoreApp.editDataStoreKey(PRINTERFK, -1) - mobileApplication.dataStoreApp.editDataStoreKey( - SECTORDESCRIP, it.description - ) - mobileApplication.dataStoreApp.editDataStoreKey( - SECTORFK, it.id - ) - it.warehouseFk?.let { it1 -> - mobileApplication.dataStoreApp.editDataStoreKey( - WAREHOUSEFK, it1 + when (type) { + "sector" -> { + sectorListVO.forEach { + if (it.id == elementSelected.id) { + runBlocking { + mobileApplication.dataStoreApp.editDataStoreKey( + PRINTERNAME, getString(R.string.noprinter) + ) + mobileApplication.dataStoreApp.editDataStoreKey(PRINTERFK, -1) + mobileApplication.dataStoreApp.editDataStoreKey( + SECTORDESCRIP, it.description + ) + mobileApplication.dataStoreApp.editDataStoreKey( + SECTORFK, it.id + ) + it.warehouseFk?.let { it1 -> + mobileApplication.dataStoreApp.editDataStoreKey( + WAREHOUSEFK, it1 + ) + } + } + viewModel.settingsItem[0].sectorFk = it.id + viewModel.settingsItem[0].selected = it.description + viewModel.workerUpdateOperatorSalix( + "sector", mobileApplication.userId!!, it.id, null ) + settingsAdapter!!.notifyItemChanged(0) + return@forEach } } - viewModel.settingsItem[0].sectorFk = it.id - viewModel.settingsItem[0].selected = it.description - viewModel.workerUpdateOperatorSalix( - "sector", mobileApplication.userId!!, it.id, null - ) - settingsAdapter!!.notifyItemChanged(0) - return@forEach + } + + "printer" -> { + println("selected $elementSelected") + val printer = printersList.find { it.name == elementSelected.name } + println("selected printer $elementSelected") + if (printer != null) { + if (printer.sector?.backupPrinterFk == printer.id) { + showWarningPrinter(printer.name, printer.id) + } else { + savePrinter(printer.name, printer.id) + } + } + printersList.clear() } } + val searchView = + binding.searchableRecyclerView.findViewById( + R.id.search_view + ) + searchView?.setQuery("", false) binding.searchableRecyclerView.visibility = View.GONE } binding.searchableRecyclerView.setAdapter(adapter, listNames) binding.searchableRecyclerView.visibility = View.VISIBLE - binding.searchableRecyclerView.setSearchHint(getString(R.string.sectorSearch)) + binding.searchableRecyclerView.setSearchHint( + if (type == "sector") getString(R.string.sectorSearch) else + getString(R.string.printerSearch) + ) ma.hideKeyboard(binding.searchableRecyclerView) } @@ -148,7 +180,7 @@ class AjustesFragment : listIcons.add(iconInfo) listIcons.add(iconLogout) // listIcons.add(iconPhone) - // listIcons.add(iconSettings) + //listIcons.add(iconSettings) binding.mainToolbar.toolbarIcons.adapter = ToolBarAdapterTooltip(listIcons, object : OnOptionsSelectedListener { @@ -216,13 +248,20 @@ class AjustesFragment : "phoneNumber", "sip:651353889@pbx.verdnatura.es" ) + /* intentIncoming.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) startActivity(intentIncoming)*/ val intent = Intent("org.linphone.CALLING") + intent.setClassName( + "org.linphone.incomingcall", + "org.linphone.incomingcall.IncomingCallActivity" + ) intent.putExtra("server", "pbx.verdnatura.es") intent.putExtra("username", "1007") - intent.putExtra("password", "delatorre.1234") + intent.putExtra("password", "*******") intent.putExtra("phoneNumber", "sip:651353889@pbx.verdnatura.es") + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) + startActivity(intent) requireContext().sendBroadcast(intent) } @@ -265,11 +304,7 @@ class AjustesFragment : getString(R.string.closeSession) -> ma.onMyBackPressed() getString(R.string.printerLabel) -> { messagePrinter = getString(R.string.SelectPrinter) - viewModel.printerGet( - mobileApplication.dataStoreApp.readDataStoreKey( - SECTORFK - ) - ) + viewModel.printerGet() } getString(R.string.vehicleControl) -> ma.onPasillerosItemClickListener( @@ -313,7 +348,7 @@ class AjustesFragment : event.getContentIfNotHandled().notNull { messagePrinter = getString(R.string.SelectPrinter) + "\n" + getString(R.string.printerRemoved) - viewModel.printerGet(mobileApplication.dataStoreApp.readDataStoreKey(SECTORFK)) + viewModel.printerGet() } } @@ -375,20 +410,53 @@ class AjustesFragment : } } loadPrintersList.observe(viewLifecycleOwner) { event -> - event.getContentIfNotHandled().notNull { it -> + event.getContentIfNotHandled()?.let { it -> if (it.list.isNotEmpty()) { val listPrinters: ArrayList = ArrayList() - it.list.forEach { - listPrinters.add(it.name) + printersList.clear() + + + printersList.addAll(it.list.sortedWith(compareBy( + { printer -> + when { + printer.sector?.id == mobileApplication.dataStoreApp.readDataStoreKey( + SECTORFK + ) -> 0 + + printer.sector?.id != null -> 1 + else -> 2 + } + }, + { printer -> printer.name } + ))) + + printersList.forEach { printer -> + listPrinters.add(printer.name) } + val array = arrayOfNulls(listPrinters.size) - printersList = it.list - showDialogForAll(listPrinters.toArray(array), messagePrinter ?: "") + // showDialogForAll(listPrinters.toArray(array), messagePrinter ?: "") + //Tarea7823 + val listColorsElements = printersList.mapIndexed { _, printer -> + if (printer.sector?.id == mobileApplication.dataStoreApp.readDataStoreKey( + SECTORFK + ) + ) printer.id else null + }.filterNotNull() + + setSearchable(printersList.map { + NameWithId( + id = it.id, + name = it.name + ) + } as MutableList, + type = "printer", + listColorsElements = listColorsElements) } else { viewModel.settingsItem[2].selected = getString(R.string.noprinter) - settingsAdapter!!.notifyItemChanged(2) + settingsAdapter?.notifyItemChanged(2) customDialog.setTitle(getString(R.string.printers)) .setDescription(getString(R.string.Noprinters)) .setOkButton(getString(R.string.Close)) { @@ -396,7 +464,6 @@ class AjustesFragment : handleUserCall() }.show() } - } } loadTrainList.observe(viewLifecycleOwner) { event -> @@ -421,14 +488,19 @@ class AjustesFragment : super.observeViewModel() } + @SuppressLint("NotifyDataSetChanged") private fun getUserData() { loginViewModel = LoginViewModel(requireActivity().applicationContext) handleUserCall() loginViewModel.handleUserResponse.observe(this@AjustesFragment) { iti -> - runBlocking { mobileApplication.dataStoreApp.saveWorkerData(iti) } + runBlocking { + mobileApplication.dataStoreApp.saveWorkerData(iti) + setSettings() + binding.setttingsItems.adapter!!.notifyDataSetChanged() + } } - setSettings() + } private fun handleUserCall() { @@ -496,12 +568,26 @@ class AjustesFragment : val positionPrinterEmergency = printersList.indexOfFirst { printer -> printer.sector?.backupPrinterFk == printer.id } - if (position == positionPrinterEmergency) { - textView.setTextColor(Color.RED) - } else { - textView.setTextColor(Color.BLACK) - } + val positions = printersList.mapIndexed { index, printer -> + if (printer.sector?.id == mobileApplication.dataStoreApp.readDataStoreKey( + SECTORFK + ) + ) index else null + }.filterNotNull() + when (position) { + positionPrinterEmergency -> { + textView.setTextColor(Color.RED) + } + + in positions -> { + textView.setTextColor(Color.BLACK) + } + + else -> { + textView.setTextColor(Color.GRAY) + } + } return view } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/ajustes/fragment/AjustesViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/ajustes/fragment/AjustesViewModel.kt index 8ac8ca71..6a4e9367 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/ajustes/fragment/AjustesViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/ajustes/fragment/AjustesViewModel.kt @@ -156,9 +156,10 @@ class AjustesViewModel(val context: Context) : BaseViewModel(context) { }) } - fun printerGet(sectorFk: Int) { + fun printerGet() { + //Tarea 7823*/ salix.getprinters( - """{"fields":["id","name","sectorFk"],"where":{"sectorFk":$sectorFk,"isLabeler":{"neq":false}},"include": [ { "relation": "sector", "scope": { "fields": ["backupPrinterFk"]}}]}""" + """{"fields":["id","name","sectorFk"],"where":{"isLabeler":{"neq":false}},"include": [ { "relation": "sector", "scope": { "fields": ["backupPrinterFk"]}}]}""" ).enqueue(object : SalixCallback>(context) { override fun onSuccess(response: Response>) { _printerList.value = response.body()?.let { PrintersList(it) } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/articulo/fragment/ItemCardFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/articulo/fragment/ItemCardFragment.kt index 1633c35d..5f213021 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/articulo/fragment/ItemCardFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/articulo/fragment/ItemCardFragment.kt @@ -25,6 +25,7 @@ import es.verdnatura.presentation.common.OnOptionsSelectedListener import es.verdnatura.presentation.common.PrinterDialogManager import es.verdnatura.presentation.common.ToolBarAdapterTooltip import es.verdnatura.presentation.common.hideKeyboard +import es.verdnatura.presentation.common.itemScanIsQr import es.verdnatura.presentation.common.itemScanValue import es.verdnatura.presentation.common.loadUrl import es.verdnatura.presentation.composable.ImageViewActivityComposable @@ -40,6 +41,7 @@ import es.verdnatura.presentation.view.feature.articulo.model.ItemCardRowVO import es.verdnatura.presentation.view.feature.articulo.model.ItemCardVO import es.verdnatura.presentation.view.feature.articulo.model.ItemPackingType import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO +import kotlinx.coroutines.runBlocking import org.json.JSONObject class ItemCardFragment( @@ -133,10 +135,36 @@ class ItemCardFragment( val printerDialogManager = PrinterDialogManager(requireContext()) printerDialogManager.showPrintDialog( buyToPrint ?: itemInfoG!!.id.toLong(), - itemInfoG?.longName ?: "" - ) { id, labelType, copies, packing -> - printItem(id, labelType, copies, packing) - } + itemInfoG?.longName ?: "", + onPrintClick = { id, labelType, copies, packing -> + printItem(id, labelType, copies, packing) + }, + onPrintChange = { text -> + if (itemScanIsQr(text)) { + val labeler = itemScanValue( + text, + arrayOf("printer"), + "id" + ).toString().toInt() + viewModel.operatorUpdate( + workerFk = mobileApplication.userId!!, + labelerFK = labeler + ) + runBlocking { + mobileApplication.dataStoreApp.editDataStoreKey( + PRINTERFK, + labeler + ) + } + } else { + ma.messageWithSound( + getString(R.string.qrPrinterNotvalid), + isPlayed = true, + isError = true, + isToasted = false + ) + } + }) } else ma.messageWithSound( getString(R.string.errorPrintBuy), isError = true, @@ -273,7 +301,7 @@ class ItemCardFragment( } binding.itemcardImage.setOnClickListener { - //JETPACKCOMPOSE + //JETPACKCOMPOSE // val i = Intent(activity, ImageViewActivity::class.java) val i = Intent(activity, ImageViewActivityComposable::class.java) i.putExtra(getString(R.string.url), urlLarge) @@ -343,6 +371,17 @@ class ItemCardFragment( buyToPrint = it } } + + loadChangePrinterResponse.observe(viewLifecycleOwner) { event -> + event.getContentIfNotHandled().notNull { + runBlocking { + mobileApplication.dataStoreApp.editDataStoreKey( + PRINTERFK, + it + ) + } + } + } } } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/articulo/fragment/ItemCardViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/articulo/fragment/ItemCardViewModel.kt index 55789b6e..940cdcd7 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/articulo/fragment/ItemCardViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/articulo/fragment/ItemCardViewModel.kt @@ -8,6 +8,7 @@ import es.verdnatura.domain.SalixCallback import es.verdnatura.domain.formatWithQuotes import es.verdnatura.domain.userCases.GetItemFromBarcodeUseCase import es.verdnatura.domain.userCases.GetItemPrintItemUseCase +import es.verdnatura.domain.userCases.OperatorUseCase import es.verdnatura.presentation.base.BaseViewModel import es.verdnatura.presentation.common.Event import es.verdnatura.presentation.common.ItemBarCodeSalix @@ -27,6 +28,7 @@ class ItemCardViewModel(var context: Context) : BaseViewModel(context) { private val getItemFromBarcodeUseCase = GetItemFromBarcodeUseCase(salix) private val printItemUseCase = GetItemPrintItemUseCase(salix) + private val operatorUseCase = OperatorUseCase(salix) private val _itemCard by lazy { MutableLiveData() } val itemCard: LiveData @@ -54,6 +56,10 @@ class ItemCardViewModel(var context: Context) : BaseViewModel(context) { val buyUltimateResponse: LiveData = _buyUltimateResponse val loadBuyUltimateResponse: LiveData> = _buyUltimateResponse.map { Event(it) } + private val _changePrinterResponse by lazy { MutableLiveData() } + val changePrinterResponse: LiveData = _changePrinterResponse + val loadChangePrinterResponse: LiveData> = _changePrinterResponse.map { Event(it) } + fun getItemCard( itemFk: Number, warehouseFk: Int, @@ -69,6 +75,18 @@ class ItemCardViewModel(var context: Context) : BaseViewModel(context) { }) } + fun operatorUpdate(workerFk: Number, labelerFK: Number) { + + operatorUseCase.updateOperator(workerFk = workerFk, hashMapOf("labelerFk" to labelerFK)) + .enqueue(object : SalixCallback(context) { + override fun onSuccess(response: Response) { + super.onSuccess(response) + _changePrinterResponse.value = labelerFK.toInt() + } + + }) + } + fun printItem( reportName: String, printerFk: Int, diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/adapter/LocationAdapter.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/adapter/LocationAdapter.kt index 0adf9ac9..ffd68273 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/adapter/LocationAdapter.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/adapter/LocationAdapter.kt @@ -35,7 +35,7 @@ class LocationAdapter( ) } holder.binding.root.setOnLongClickListener { - items[position].shelving.parking.sector.description.toast( + items[position].shelving.parking!!.sector.description.toast( holder.binding.root.context, Toast.LENGTH_SHORT ) diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemComposeViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemComposeViewModel.kt index 6cf2b38c..a8e4509f 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemComposeViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemComposeViewModel.kt @@ -11,7 +11,8 @@ import retrofit2.Response data class UiState( val itemFk: String? = null, - val items: List = emptyList() + val items: List = emptyList(), + val isLoading: Boolean = false ) class BuscarItemComposeViewModel(var application: android.app.Application) : @@ -21,23 +22,8 @@ class BuscarItemComposeViewModel(var application: android.app.Application) : private val _uiState = MutableStateFlow(UiState()) val uiState = _uiState.asStateFlow() - /* private val _itemFk = MutableStateFlow(null) - val itemFk = _itemFk.asStateFlow()*/ - - /* private val _itemShelvingsList = MutableStateFlow(null) - val itemShelvingsList = _itemShelvingsList.asStateFlow()*/ - - /*val loadItemShelvingsList = _itemShelvingsList.map { - it?.let { Event(it) } - }.stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(5000), - initialValue = null - )*/ - fun getIdFromCodeSalix(code: String) { - _uiState.update { it.copy(itemFk = code) } - //_itemFk.value = code + _uiState.update { it.copy(itemFk = code, isLoading = true) } getItemFromBarcodeUseCase.execute(code) .enqueue(object : SalixCallback(application.applicationContext) { override fun onSuccess(response: Response) { @@ -45,7 +31,13 @@ class BuscarItemComposeViewModel(var application: android.app.Application) : itemshelvingsGet(id) } } - }) + + override fun onError(t: Throwable) { + super.onError(t) + _uiState.update { it.copy(isLoading = false) } + } + } + ) } fun itemshelvingsGet(itemFk: Any) { @@ -57,10 +49,14 @@ class BuscarItemComposeViewModel(var application: android.app.Application) : .enqueue(object : SalixCallback>(application.applicationContext) { override fun onSuccess(response: Response>) { response.body()?.let { list -> - //_itemShelvingsList.value = ItemShelvingsList(list) - _uiState.update { it.copy(items = list) } + _uiState.update { it.copy(items = list, isLoading = false) } } } + + override fun onError(t: Throwable) { + super.onError(t) + _uiState.update { it.copy(isLoading = false) } + } }) } } \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemFragment.kt index 2e884ec1..0e985fd0 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemFragment.kt @@ -91,6 +91,7 @@ class BuscarItemFragment( false ) } catch (ex: Exception) { + println("errorrrr ${ex.message}") ma.messageWithSound( message = ex.message.toString(), isError = true, diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemFragmentCompose.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemFragmentCompose.kt index 8ce30617..419c4b29 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemFragmentCompose.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemFragmentCompose.kt @@ -5,11 +5,8 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue import androidx.compose.ui.platform.ComposeView import androidx.fragment.app.Fragment -import androidx.lifecycle.compose.collectAsStateWithLifecycle import es.verdnatura.R import es.verdnatura.domain.toast import es.verdnatura.presentation.common.OnPasillerosItemClickListener @@ -29,9 +26,7 @@ class BuscarItemFragmentCompose( override fun onAttach(context: Context) { super.onAttach(context) - if (context is OnPasillerosItemClickListener) pasillerosItemClickListener = context - } override fun onCreateView( @@ -39,14 +34,24 @@ class BuscarItemFragmentCompose( ): View { return ComposeView(requireContext()).apply { setContent { - SetView() + BuscarItemScreen( + viewModel = viewModel, + onBackClick = { (context as MainActivity).onMyBackPressed() }, + onItemLongClick = { sector -> sector.toast(requireContext()) }, + onItemClick = { shelving -> + pasillerosItemClickListener?.onPasillerosItemClickListener( + PasillerosItemVO(title = R.string.titleUbicator), + shelving + ) + }, + title = getString(R.string.getubication) + ) } } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - itemFk?.let { viewModel.getIdFromCodeSalix(it.toString()) } @@ -66,53 +71,4 @@ class BuscarItemFragmentCompose( ) } - @Composable - private fun SetView() { - val uiState by viewModel.uiState.collectAsStateWithLifecycle() - - LocationScreen( - items = uiState.items.map { - LocationItem( - parking = it.shelving.parking.code, - matricula = it.shelving.code, - visible = it.visible.toString(), - reserve = it.available.toString(), - priority = it.shelving.priority.toString(), - fecha = it.created, - sector = it.shelving.parking.sector.description - ) - }, - onTextChange = { input -> - viewModel.getIdFromCodeSalix(input) - }, - titleToolBar = if (uiState.items.isNotEmpty()) { - getString( - R.string.itemsTotal, - uiState.itemFk, - getString(R.string.visibleTotal), - uiState.items.sumOf { it.visible } - ) - } else getString(R.string.getubication), - onBackClick = { (context as MainActivity).onMyBackPressed() }, - onLongClick = { item -> item.sector.toast(requireContext()) }, - onClick = { item -> - pasillerosItemClickListener?.onPasillerosItemClickListener( - PasillerosItemVO(title = R.string.titleUbicator), - item.matricula - ) - } - ) - } - } - -/* -class BuscarItemViewModelFactory(private val context: Application) : ViewModelProvider.Factory { - override fun create(modelClass: Class): T { - if (modelClass.isAssignableFrom(BuscarItemComposeViewModel::class.java)) { - @Suppress("UNCHECKED_CAST") - return BuscarItemComposeViewModel(context) as T - } - throw IllegalArgumentException("Unknown ViewModel class") - } -}*/ diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemViewModel.kt index cf73ce8e..f12d2de6 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/BuscarItemViewModel.kt @@ -42,7 +42,12 @@ class BuscarItemViewModel(val context: Context) : BaseViewModel(context) { ) .enqueue(object : SalixCallback>(context) { override fun onSuccess(response: Response>) { - _itemShelvingsList.value = response.body()?.let { ItemShelvingsList(it) } + _itemShelvingsList.value = response.body()?.let { + val filteredList = it.filter { itemShelving -> + itemShelving.shelving.parking != null + } + ItemShelvingsList(filteredList) + } } }) diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/LocationScreen.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/LocationScreen.kt index 3cbffbf1..a43c9375 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/LocationScreen.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/fragment/LocationScreen.kt @@ -22,24 +22,195 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.onFocusEvent import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import es.verdnatura.R import es.verdnatura.presentation.composable.CustomToolbar +import es.verdnatura.presentation.composable.LottieLoadingAnimation import es.verdnatura.presentation.composable.ScanLineTextSearch @Composable +fun BuscarItemScreen( + viewModel: BuscarItemComposeViewModel, + onBackClick: () -> Unit, + onItemLongClick: (sector: String) -> Unit, + onItemClick: (matricula: String) -> Unit, + title: String +) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + + val locationItems = uiState.items + .filter { it.shelving.parking != null } + .map { + LocationItem( + parking = it.shelving.parking!!.code, + matricula = it.shelving.code, + visible = it.visible.toString(), + reserve = it.available.toString(), + priority = it.shelving.priority.toString(), + fecha = it.created, + sector = it.shelving.parking.sector.description + ) + } + + LocationScreenContent( + items = locationItems, + isLoading = uiState.isLoading, + titleToolBar = if (uiState.itemFk != null) { + LocalContext.current.getString( + R.string.itemsTotal, + uiState.itemFk, + LocalContext.current.getString(R.string.visibleTotal), + uiState.items + .filter { it.shelving.parking != null } + .sumOf { it.visible } + ) + } else title, + onTextChange = { input -> viewModel.getIdFromCodeSalix(input) }, + onBackClick = onBackClick, + onLongClick = onItemLongClick, + onClick = onItemClick, + modifier = Modifier + ) +} + +@Composable +private fun LocationScreenContent( + items: List, + isLoading: Boolean, + titleToolBar: String, + onTextChange: (String) -> Unit, + onBackClick: () -> Unit, + onLongClick: (String) -> Unit, + onClick: (String) -> Unit, + modifier: Modifier +) { + var searchText by remember { mutableStateOf("") } + val focusRequester = remember { FocusRequester() } + val keyboardController = LocalSoftwareKeyboardController.current + + val onImeAction: () -> Unit = { + onTextChange(searchText) + searchText = "" + keyboardController?.hide() + } + Box( + modifier = modifier + .fillMaxSize() + .background(Color.Black) + ) { + Column( + modifier = modifier + .fillMaxSize() + .background(Color.Black) + + ) { + + CustomToolbar( + title = titleToolBar, + subtitle = "", + showBackButton = true, + showSwitch = false, + iconList = listOf(), + onBackClick = onBackClick, + onSwitchChange = { }, + + ) + Spacer(modifier = Modifier.height(8.dp)) + + + ScanLineTextSearch( + value = searchText, + onValueChange = { + searchText = it + }, + onImeAction, + modifier = Modifier + .focusRequester(focusRequester) + .onFocusEvent { + if (it.isFocused) { + keyboardController?.hide() // Asegura que el teclado no se abra + } + } + ) + LaunchedEffect(Unit) { + focusRequester.requestFocus() + keyboardController?.hide() + } + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp), + horizontalArrangement = Arrangement.Start + ) { + listOf( + R.string.parking, + R.string.Matrícula, + R.string.Visible, + R.string.reserve, + R.string.priority, + R.string.date + ).forEach { textRes -> + Text( + text = stringResource(id = textRes), + color = Color.White, + fontSize = 14.sp, + modifier = Modifier.weight(1f) + ) + } + } + + HorizontalDivider(thickness = 1.dp, color = Color.White) + LazyColumn( + modifier = Modifier.fillMaxSize() + ) { + + items(items) { item -> + + LocationRow( + item = item, + onLongClick = { selectedItem -> + onLongClick(selectedItem.sector) + }, + onClick = { selectedItem -> + onClick(selectedItem.matricula) + }, + ) + HorizontalDivider(thickness = 1.dp, color = Color.White) + } + } + } + if (isLoading) { + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.Black.copy(alpha = 0.7f)), + contentAlignment = Alignment.Center + ) { + LottieLoadingAnimation(true) + } + } + + } +} + +// Como estaba + +/*@Composable fun LocationScreen( - //viewModel: BuscarItemComposeViewModel = viewModel(), // Falta ver de arreglar con koin o viewmodel → No necesario, en el Fragment observa + //viewModel: ViewModel?, // Falta ver de arreglar con koin o viewmodel → No necesario, en el Fragment observa items: List, onTextChange: (String) -> Unit, titleToolBar: String, @@ -48,6 +219,7 @@ fun LocationScreen( onLongClick: (LocationItem) -> Unit, onClick: (LocationItem) -> Unit ) { + var searchText by remember { mutableStateOf("") } val focusRequester = remember { FocusRequester() } val keyboardController = LocalSoftwareKeyboardController.current @@ -117,7 +289,7 @@ fun LocationScreen( R.string.Visible, R.string.reserve, R.string.priority, - R.string.Fecha + R.string.date ).forEach { textRes -> Text( text = stringResource(id = textRes), @@ -151,7 +323,7 @@ fun LocationScreen( } } } - +*/ @OptIn(ExperimentalFoundationApi::class) @Composable fun LocationRow( @@ -189,11 +361,10 @@ data class LocationItem( ) // Vista previa -@Preview(showBackground = true) +/*@Preview(showBackground = true) @Composable fun PreviewLocationScreen() { LocationScreen( - // viewModel = null, items = listOf( LocationItem("P1", "1234ABC", "Sí", "No", "Alta", "12/02/2025", "previa"), LocationItem("P2", "5678DEF", "No", "Sí", "Baja", "13/02/2025", "previa") @@ -204,4 +375,4 @@ fun PreviewLocationScreen() { onLongClick = {}, onClick = {}) -} +}*/ diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/model/ItemLocationVO.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/model/ItemLocationVO.kt index 429b1156..2500ec56 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/model/ItemLocationVO.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/buscaritem/model/ItemLocationVO.kt @@ -16,7 +16,7 @@ data class ItemShelvings( } data class Shelving( - val code: String, val priority: Int, val parking: Parking + val code: String, val priority: Int, val parking: Parking? ) data class Parking( diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/PlacementAdapter.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/PlacementAdapter.kt index e32768eb..b95935c8 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/PlacementAdapter.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/PlacementAdapter.kt @@ -1,28 +1,31 @@ package es.verdnatura.presentation.view.feature.collection.adapter import android.content.Context +import android.graphics.Paint import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import es.verdnatura.R import es.verdnatura.databinding.ItemPlacementRowBinding +import es.verdnatura.domain.ConstAndValues.CONTROLADOR import es.verdnatura.presentation.common.OnPasillerosItemClickListener import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO import es.verdnatura.presentation.view.feature.sacador.model.PlacementVO -class PlacementAdapter ( +class PlacementAdapter( private val items: List, - private val onPasillerosItemClickListener: OnPasillerosItemClickListener -): RecyclerView.Adapter () { + private val onPasillerosItemClickListener: OnPasillerosItemClickListener, + private val type: String? = null +) : RecyclerView.Adapter() { var context: Context? = null override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AjustesItemHolder { this.context = parent.context return AjustesItemHolder( - ItemPlacementRowBinding.inflate(LayoutInflater.from(parent.context),parent,false) + ItemPlacementRowBinding.inflate(LayoutInflater.from(parent.context), parent, false) ) } - override fun getItemCount() =items.size + override fun getItemCount() = items.size override fun onBindViewHolder(holder: AjustesItemHolder, position: Int) { holder.bind(items[position]) @@ -30,19 +33,26 @@ class PlacementAdapter ( inner class AjustesItemHolder( val binding: ItemPlacementRowBinding - ) : RecyclerView.ViewHolder(binding.root){ + ) : RecyclerView.ViewHolder(binding.root) { fun bind(placement: PlacementVO) { binding.apply { - if (placement.placement.isNullOrEmpty()) - placement.placement = placement.parking - if (placement.visible.isNullOrEmpty()) - placement.visible = "("+placement.stockTotal+")" + if (placement.placement.isNullOrEmpty()) placement.placement = placement.parking + if (placement.visible.isNullOrEmpty()) placement.visible = + "(" + placement.stockTotal + ")" this.item = placement itemRootLayout.setOnClickListener { - onPasillerosItemClickListener.onPasillerosItemClickListener(PasillerosItemVO(title = - R.string.titleUbicator),placement.shelving) + onPasillerosItemClickListener.onPasillerosItemClickListener( + PasillerosItemVO( + title = R.string.titleUbicator + ), placement.shelving + ) } + if (type == CONTROLADOR) { + placementcode.paintFlags = placementcode.paintFlags or Paint.UNDERLINE_TEXT_FLAG + placementcode.paintFlags = placementcode.paintFlags or Paint.UNDERLINE_TEXT_FLAG + } + } } } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapter.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapter.kt index 7ee0a2de..8df46bb7 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapter.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapter.kt @@ -3,6 +3,7 @@ package es.verdnatura.presentation.view.feature.collection.adapter import android.content.Context import android.content.res.ColorStateList import android.graphics.Color +import android.graphics.Paint import android.graphics.drawable.Drawable import android.view.LayoutInflater import android.view.View @@ -84,7 +85,7 @@ class SaleAdapter( itemArticlePlacements.apply { layoutManager = childLayoutManager - adapter = PlacementAdapter(sale.placements, onPasillerosItemClickListener) + adapter = PlacementAdapter(sale.placements, onPasillerosItemClickListener, type) } //CLICK EVENTS @@ -422,13 +423,15 @@ class SaleAdapter( itemTicketColor.setOnClickListener { onTicketColorClickListener?.onTicketColorListener(sale) } - if (type == SACADOR || type == CONTROLADOR) { + if (type == CONTROLADOR) { itemTicketColor.tooltipText = context!!.getString(R.string.filterLevelColor) + ticketFk.paintFlags = ticketFk.paintFlags or Paint.UNDERLINE_TEXT_FLAG + itemArticleItemFk.paintFlags = + itemArticleItemFk.paintFlags or Paint.UNDERLINE_TEXT_FLAG } - /* ticketFk.paintFlags = ticketFk.paintFlags or Paint.UNDERLINE_TEXT_FLAG - itemArticleItemFk.paintFlags = - itemArticleItemFk.paintFlags or Paint.UNDERLINE_TEXT_FLAG*/ + + this.sale = sale diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapterReserve.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapterReserve.kt index 024f74c3..5e8ffbbb 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapterReserve.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapterReserve.kt @@ -18,7 +18,6 @@ import es.verdnatura.databinding.SaleRowFragmentReserveBinding import es.verdnatura.domain.ConstAndValues.PREITEMPICKERTEST import es.verdnatura.domain.ConstAndValues.PREPARED import es.verdnatura.domain.ConstAndValues.SACADOR -import es.verdnatura.domain.toast import es.verdnatura.presentation.common.OnAddItemClickListener import es.verdnatura.presentation.common.OnMistakeClickListener import es.verdnatura.presentation.common.OnPackingClickSaleListener @@ -63,13 +62,15 @@ class SaleAdapterReserve( override fun onBindViewHolder(holder: AjustesItemHolder, position: Int) { this.position = position - holder.bind(items[position]) + val item = items[position] + val calculatedValues = precalculateDisplayValues(item) + holder.bind(item, calculatedValues) } inner class AjustesItemHolder( val binding: SaleRowFragmentReserveBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(sale: Sale) { + fun bind(sale: Sale, calculatedValues: Pair) { binding.apply { println("type $type ") println("type isExpanded $isExpanded") @@ -222,49 +223,23 @@ class SaleAdapterReserve( previous.text = "PREV:${sale.saleGroupFk}" } - val result: Int - val textToConcat: String + binding.txtQuantityReserved.text = calculatedValues.first + if (sale.totalItemShelving > 1) { + binding.txtQuantityReserved.text = calculatedValues.first + binding.txtQuantity.text = calculatedValues.second + binding.txtReserveToComplete.text = + "${sale.currentItemShelving}/${sale.totalItemShelving}" + binding.txtReserveToComplete.visibility = VISIBLE + binding.txtQuantity.text = + "${sale.reservedQuantity}" + } else { + binding.txtQuantity.text = + if (sale.itemShelvingFk == 0 && sale.itemShelvingSaleFk == 0) { + "${sale.saleQuantity}" + } else "${sale.reservedQuantity}" + binding.txtReserveToComplete.visibility = GONE - try { - - result = sale.reservedQuantity % (sale.packing ?: (sale.saleQuantity + 1)) - textToConcat = if (result != 0) { - "${sale.reservedQuantity / (sale.grouping ?: 1)} x ${sale.grouping ?: "1"}" - } else { - "${sale.reservedQuantity / (sale.packing ?: 1)} pack de ${sale.packing ?: "1"}" - } - binding.txtQuantityReserved.text = textToConcat - - val textToConcat2: String - - val result2: Int = - sale.accumulatedQuantity % (sale.packing ?: (sale.saleQuantity + 1)) - textToConcat2 = if (result2 != 0) { - "${(sale.saleQuantity - sale.accumulatedQuantity) / (sale.grouping ?: 1)} x ${sale.grouping ?: "1"}" - } else { - "${(sale.saleQuantity - sale.accumulatedQuantity) / (sale.packing ?: 1)} pack de ${sale.packing ?: "1"}" - } - - - if (sale.totalItemShelving > 1) { - binding.txtQuantityReserved.text = textToConcat - binding.txtQuantity.text = textToConcat2 - binding.txtReserveToComplete.text = - "${sale.currentItemShelving}/${sale.totalItemShelving}" - binding.txtReserveToComplete.visibility = VISIBLE - binding.txtQuantity.text = - "${sale.reservedQuantity}" - } else { - binding.txtQuantity.text = "${sale.reservedQuantity}" - binding.txtReserveToComplete.visibility = GONE - - } - - } catch (ex: Exception) { - ex.message!!.toast(context) } - - binding.txtReserveToComplete.text = "${sale.currentItemShelving}/${sale.totalItemShelving}" @@ -362,4 +337,30 @@ class SaleAdapterReserve( } } + private fun precalculateDisplayValues(sale: Sale): Pair { + try { + val result = sale.reservedQuantity % (sale.packing ?: (sale.saleQuantity + 1)) + val textToConcat = if (result != 0) { + "${sale.reservedQuantity / (sale.grouping ?: 1)} x ${sale.grouping ?: "1"}" + } else { + "${sale.reservedQuantity / (sale.packing ?: 1)} pack de ${sale.packing ?: "1"}" + } + + val result2 = sale.accumulatedQuantity % (sale.packing ?: (sale.saleQuantity + 1)) + val textToConcat2 = if (result2 != 0) { + "${(sale.saleQuantity - sale.accumulatedQuantity) / (sale.grouping ?: 1)} x ${sale.grouping ?: "1"}" + } else { + "${(sale.saleQuantity - sale.accumulatedQuantity) / (sale.packing ?: 1)} pack de ${sale.packing ?: "1"}" + } + return if (sale.itemShelvingSaleFk == 0 && sale.itemShelvingFk == 0) Pair( + "-", + "0" + ) else { + Pair(textToConcat, textToConcat2) + } + } catch (ex: Exception) { + return Pair("Error", "Error") + } + } + } \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapterReserveSacador.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapterReserveSacador.kt index 07a01334..0e30bca0 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapterReserveSacador.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/adapter/SaleAdapterReserveSacador.kt @@ -18,7 +18,6 @@ import es.verdnatura.databinding.SaleRowFragmentReserveSacadorBinding import es.verdnatura.domain.ConstAndValues.PREITEMPICKERTEST import es.verdnatura.domain.ConstAndValues.PREPARED import es.verdnatura.domain.ConstAndValues.SACADOR -import es.verdnatura.domain.toast import es.verdnatura.presentation.common.OnAddItemClickListener import es.verdnatura.presentation.common.OnMistakeClickListener import es.verdnatura.presentation.common.OnPackingClickSaleListener @@ -61,15 +60,19 @@ class SaleAdapterReserveSacador( override fun getItemCount() = items.size - override fun onBindViewHolder(holder: AjustesItemHolder, position: Int) { + override fun onBindViewHolder(holder: AjustesItemHolder, position: Int) {/* this.position = position + holder.bind(items[position])*/ this.position = position - holder.bind(items[position]) + val item = items[position] + val calculatedValues = precalculateDisplayValues(item) + holder.bind(item, calculatedValues) + } inner class AjustesItemHolder( val binding: SaleRowFragmentReserveSacadorBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(sale: Sale) { + fun bind(sale: Sale, calculatedValues: Pair) { binding.apply { val childLayoutManagerV = @@ -219,50 +222,23 @@ class SaleAdapterReserveSacador( previous.text = "PREV:${sale.saleGroupFk}" } + binding.txtQuantityReserved.text = calculatedValues.first + if (sale.totalItemShelving > 1) { + binding.txtQuantityReserved.text = calculatedValues.first + binding.txtQuantity.text = calculatedValues.second + binding.txtReserveToComplete.text = + "${sale.currentItemShelving}/${sale.totalItemShelving}" + binding.txtReserveToComplete.visibility = VISIBLE + binding.txtQuantity.text = "${sale.reservedQuantity}" + } else { + binding.txtQuantity.text = + if (sale.itemShelvingFk == 0 && sale.itemShelvingSaleFk == 0) { + "${sale.saleQuantity}" + } else "${sale.reservedQuantity}" + binding.txtReserveToComplete.visibility = GONE - val result: Int - val textToConcat: String - - try { - - result = sale.reservedQuantity % (sale.packing ?: (sale.saleQuantity + 1)) - textToConcat = if (result != 0) { - "${sale.reservedQuantity / (sale.grouping ?: 1)} x ${sale.grouping ?: "1"}" - } else { - "${sale.reservedQuantity / (sale.packing ?: 1)} pack de ${sale.packing ?: "1"}" - } - binding.txtQuantityReserved.text = textToConcat - - val textToConcat2: String - - val result2: Int = - sale.accumulatedQuantity % (sale.packing ?: (sale.saleQuantity + 1)) - textToConcat2 = if (result2 != 0) { - "${(sale.saleQuantity - sale.accumulatedQuantity) / (sale.grouping ?: 1)} x ${sale.grouping ?: "1"}" - } else { - "${(sale.saleQuantity - sale.accumulatedQuantity) / (sale.packing ?: 1)} pack de ${sale.packing ?: "1"}" - } - - - if (sale.totalItemShelving > 1) { - binding.txtQuantityReserved.text = textToConcat - binding.txtQuantity.text = textToConcat2 - binding.txtReserveToComplete.text = - "${sale.currentItemShelving}/${sale.totalItemShelving}" - binding.txtReserveToComplete.visibility = VISIBLE - binding.txtQuantity.text = - "${sale.reservedQuantity}" - } else { - binding.txtQuantity.text = "${sale.reservedQuantity}" - binding.txtReserveToComplete.visibility = GONE - - } - - } catch (ex: Exception) { - ex.message!!.toast(context) } - binding.txtReserveToComplete.text = "${sale.currentItemShelving}/${sale.totalItemShelving}" @@ -290,8 +266,11 @@ class SaleAdapterReserveSacador( } else { if (sale.stateCode != null && sale.stateCode == "PREVIOUS_CONTROLLED") { getColor( - context!!, R.color.verdnatura_dark_mint_light - ) + context!!, + R.color.verdnatura_dark_mint_light_precontrolled + )/* getColor( + context!!, R.color.verdnatura_dark_sky_blue + )*/ } else { getColor( context!!, R.color.verdnatura_black @@ -339,7 +318,6 @@ class SaleAdapterReserveSacador( } - this.sale = sale } @@ -360,4 +338,30 @@ class SaleAdapterReserveSacador( } } + private fun precalculateDisplayValues(sale: Sale): Pair { + try { + val result = sale.reservedQuantity % (sale.packing ?: (sale.saleQuantity + 1)) + val textToConcat = if (result != 0) { + "${sale.reservedQuantity / (sale.grouping ?: 1)} x ${sale.grouping ?: "1"}" + } else { + "${sale.reservedQuantity / (sale.packing ?: 1)} pack de ${sale.packing ?: "1"}" + } + + val result2 = sale.accumulatedQuantity % (sale.packing ?: (sale.saleQuantity + 1)) + val textToConcat2 = if (result2 != 0) { + "${(sale.saleQuantity - sale.accumulatedQuantity) / (sale.grouping ?: 1)} x ${sale.grouping ?: "1"}" + } else { + "${(sale.saleQuantity - sale.accumulatedQuantity) / (sale.packing ?: 1)} pack de ${sale.packing ?: "1"}" + } + println("reserva sale $sale") + return if (sale.itemShelvingSaleFk == 0 && sale.itemShelvingFk == 0) Pair( + "-", + "0" + ) else { + Pair(textToConcat, textToConcat2) + } + } catch (ex: Exception) { + return Pair("Error", "Error") + } + } } \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionCheckerViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionCheckerViewModel.kt index 092a82c0..278cf96f 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionCheckerViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionCheckerViewModel.kt @@ -22,12 +22,14 @@ import es.verdnatura.presentation.view.feature.collection.mapper.map import es.verdnatura.presentation.view.feature.sacador.model.CollectionVO import es.verdnatura.presentation.view.feature.sacador.model.MistakeTypeListVO import es.verdnatura.presentation.view.feature.sacador.model.MistakeTypeVO +import es.verdnatura.presentation.view.feature.ticket.fragment.TicketViewModel import es.verdnatura.presentation.view.feature.workermistake.model.SaleMistakeSalix import retrofit2.Response class CollectionCheckerViewModel(val context: Context) : BaseViewModel(context) { private val getItemFromBarcodeUseCase = GetItemFromBarcodeUseCase(salix) private val collectionViewModelChecker = CollectionViewModel(context) + private val ticketViewModel = TicketViewModel(context) //var isPaused: Boolean = false @@ -366,4 +368,8 @@ class CollectionCheckerViewModel(val context: Context) : BaseViewModel(context) ) } + fun ticketAdvance(ticketFk: Number, workerFk: Number) { + ticketViewModel.ticketExits(ticketFk, workerFk) + } + } \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentChecker.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentChecker.kt index 7493fcae..7a39b71e 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentChecker.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentChecker.kt @@ -20,6 +20,7 @@ import es.verdnatura.databinding.FragmentCollectionBinding import es.verdnatura.domain.ConstAndValues import es.verdnatura.domain.ConstAndValues.CONTROLADOR import es.verdnatura.domain.ConstAndValues.PRINTERNAME +import es.verdnatura.domain.ConstAndValues.SECTORFK import es.verdnatura.domain.notNull import es.verdnatura.domain.showToastCenterWithBackground import es.verdnatura.domain.toast @@ -54,7 +55,6 @@ import es.verdnatura.presentation.view.feature.sacador.model.PlacementVO import es.verdnatura.presentation.view.feature.sacador.model.SaleVO import org.json.JSONObject -// FALTA TESTEAR REVISORES DESPUÉS DE CAMPAÑA Y VER HOLDPOSITION @Suppress("UNUSED_ANONYMOUS_PARAMETER") class CollectionFragmentChecker( var collection: CollectionVO = CollectionVO(0), var type: String = CONTROLADOR @@ -124,6 +124,7 @@ class CollectionFragmentChecker( if (collection.tickets.isNotEmpty()) { createCollectionList() } + super.init() } @@ -138,7 +139,7 @@ class CollectionFragmentChecker( binding.mainToolbar.toolbarSubtitle.visibility = VISIBLE binding.mainToolbar.toolbarIcons.visibility = VISIBLE binding.mainToolbar.backButton.visibility = VISIBLE - binding.previaButton.visibility = INVISIBLE + binding.mainToolbar.toolbarTitle.text = if (collection.collectionFk == 0) getString(R.string.review) else collection.collectionFk.toString() @@ -167,10 +168,11 @@ class CollectionFragmentChecker( listIcons.add(iconWorker) listIcons.add(iconAdd) binding.previaButton.setOnClickListener { - showPrevia() + showDialog(isAdvanceTicket = false) + } + binding.ticketAdvanceButton.setOnClickListener { + showDialog(isAdvanceTicket = true) } - - binding.mainToolbar.toolbarIcons.adapter = ToolBarAdapterTooltip(listIcons, object : OnOptionsSelectedListener { override fun onOptionsItemSelected(item: Drawable) { @@ -210,11 +212,20 @@ class CollectionFragmentChecker( } } - private fun showPrevia() { + private fun showDialog(isAdvanceTicket: Boolean) { customDialogList.getEditText().setRawInputType(TYPE_CLASS_NUMBER) - customDialogList.setTitle(getString(R.string.scanPreviousTicket)) + customDialogList.setTitle( + if (isAdvanceTicket) getString(R.string.ticketAdvance) else getString( + R.string.scanPreviousTicket + ) + ) .setOkButton(getString(R.string.end)) { - takeActionPrevia(customDialogList) + if (customDialogList.getValue().isNotEmpty()) { + takeAction(customDialogList, isAdvanceTicket) + } else { + ma.hideKeyboard(customDialogList.getEditText()) + customDialogList.dismiss() + } }.setValue("").show() @@ -226,7 +237,8 @@ class CollectionFragmentChecker( if (customDialogList.getValue().isNotEmpty()) { isScanned = event != null && event.action == ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER - takeActionPrevia(customDialogList) + takeAction(customDialogList, isAdvanceTicket) + ma.hideKeyboard(customDialogList.getEditText()) } customDialogList.setValue("") ma.hideKeyboard(customDialogList.getEditText()) @@ -237,14 +249,18 @@ class CollectionFragmentChecker( hideKeyboard() } - private fun takeActionPrevia(customDialogList: CustomDialogList) { + private fun takeAction(customDialogList: CustomDialogList, isAdvanceTicket: Boolean) { ma.hideKeyboard(customDialogList.getEditText()) try { - val saleGroupScanned = itemScanValue( - customDialogList.getValue(), arrayOf("saleGroup"), "id" + val itemScanned = itemScanValue( + customDialogList.getValue(), if (isAdvanceTicket) { + arrayOf("ticket") + } else arrayOf("saleGroup"), "id" ).toString() - markPrevia(saleGroupScanned) + if (isAdvanceTicket) { + viewModel.ticketAdvance(itemScanned.toInt(), mobileApplication.userId!!) + } else markPrevia(itemScanned) customDialogList.dismiss() } catch (ex: Exception) { ma.messageWithSound( @@ -360,6 +376,7 @@ class CollectionFragmentChecker( if (it.tickets.isNotEmpty()) { collection = it binding.previaButton.visibility = VISIBLE + binding.ticketAdvanceButton.visibility = VISIBLE binding.fragmentSacadorCollections.visibility = VISIBLE createCollectionList() } else { @@ -368,6 +385,7 @@ class CollectionFragmentChecker( getString(R.string.summaryCount, 0, 0) binding.fragmentSacadorCollections.visibility = INVISIBLE binding.previaButton.visibility = INVISIBLE + binding.ticketAdvanceButton.visibility = INVISIBLE } } else { customDialog.setTitle(getString(R.string.error)) @@ -555,17 +573,48 @@ class CollectionFragmentChecker( observations.takeIf { it.isNotBlank() }?.plus(" ${ticket.observations}") ?: "" } - if (!buttonPushedGetCollection) { - sales = salesList.sortedWith(compareBy { it.picked }) - myGroupList = groupSaleGroup(salesList).sortedWith(compareBy { it.picked }) + val isOnReservationMode = mobileApplication.dataStoreApp.readDataStoreKey( + ConstAndValues.RESERVATIONMODE + ) || (mobileApplication.dataStoreApp.readDataStoreKey( + ConstAndValues.SECTORISONRESERVATIONMODE + ) == true) + + sales = if (isOnReservationMode) { + salesList.filter { + it.sectorFk == mobileApplication.dataStoreApp.readDataStoreKey(SECTORFK) + }.sortedWith(compareBy({ it.saleOrder })) } else { - sales = salesList.sortedWith( + salesList.filter { + it.sectorFk == mobileApplication.dataStoreApp.readDataStoreKey(SECTORFK) + }.sortedWith(compareBy({ it.picked })) + } + + if (!buttonPushedGetCollection) { + println("Reorden lineas sin boton pulsado") + sales = + if (!isOnReservationMode) salesList.sortedWith(compareBy { it.picked }) else salesList.sortedWith( + compareBy { it.pickedOrder }) + myGroupList = + if (!isOnReservationMode) groupSaleGroup(salesList).sortedWith(compareBy { it.picked }) else groupSaleGroup( + salesList + ).sortedWith(compareBy { it.pickedOrder }) + + for (m in myGroupList) { + println("Linea ${m.itemFk}-${m.pickedOrder} ") + } + } else { + sales = if (!isOnReservationMode) salesList.sortedWith( compareBy({ it.isControlled }, { it.picked }) + ) else salesList.sortedWith( + compareBy({ it.isControlled }, { it.pickedOrder }) ) //para la nueva revisión : hay que poner el saleOrder si no no podrán revisar correctamente - myGroupList = groupSaleGroup(salesList).sortedWith( + println("Reorden lineas con boton pulsado") + myGroupList = if (!isOnReservationMode) groupSaleGroup(salesList).sortedWith( compareBy({ it.isControlled }, { it.picked }) + ) else groupSaleGroup(salesList).sortedWith( + compareBy({ it.isControlled }, { it.pickedOrder }) ) } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPicker.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPicker.kt index 6bc2d787..081910b8 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPicker.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPicker.kt @@ -1,6 +1,7 @@ package es.verdnatura.presentation.view.feature.collection.fragment import android.content.Context +import android.graphics.PorterDuff import android.graphics.drawable.Drawable import android.media.MediaPlayer import android.os.Build @@ -18,6 +19,7 @@ import android.view.inputmethod.InputMethodManager import android.widget.ImageView import android.widget.Toast import androidx.annotation.RequiresApi +import androidx.core.content.ContextCompat import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -62,6 +64,8 @@ import es.verdnatura.presentation.view.feature.articulo.model.BarcodeVO import es.verdnatura.presentation.view.feature.collection.ItemVO import es.verdnatura.presentation.view.feature.collection.adapter.SaleAdapter import es.verdnatura.presentation.view.feature.main.activity.MainActivity +import es.verdnatura.presentation.view.feature.pasillero.model.CleanAction +import es.verdnatura.presentation.view.feature.pasillero.model.CodeWorkerAction import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO import es.verdnatura.presentation.view.feature.sacador.model.CollectionVO import es.verdnatura.presentation.view.feature.sacador.model.MistakeTypeVO @@ -69,6 +73,7 @@ import es.verdnatura.presentation.view.feature.sacador.model.PlacementSupplyList import es.verdnatura.presentation.view.feature.sacador.model.PlacementSupplyVO import es.verdnatura.presentation.view.feature.sacador.model.PlacementVO import es.verdnatura.presentation.view.feature.sacador.model.SaleVO +import kotlinx.coroutines.runBlocking import org.json.JSONObject @Suppress("UNUSED_ANONYMOUS_PARAMETER") @@ -134,6 +139,7 @@ class CollectionFragmentPicker( private var isVerifiedCollection = false private var hasFilterByLevel = false + private lateinit var iconClean: ImageView companion object { fun newInstance(collection: CollectionVO, type: String) = @@ -207,8 +213,8 @@ class CollectionFragmentPicker( collection.collectionFk.let { binding.mainToolbar.toolbarTitle.text = collection.collectionFk.toString() } - val listIcons: ArrayList = ArrayList() + val iconPrint = ImageView(context) iconPrint.setImageResource(R.drawable.ic_print_black_24dp) val iconAdd = ImageView(context) @@ -221,6 +227,9 @@ class CollectionFragmentPicker( iconPhone.setImageResource(R.drawable.phone_call) val iconParking = ImageView(context) iconParking.setImageResource(R.drawable.ic_local_parking_black_24dp) + iconClean = ImageView(context) + iconClean.setImageResource(R.drawable.ic_clean_shelving) + val iconUpdate = ImageView(context) iconUpdate.setImageResource(R.drawable.ic_autorenew_black_24dp) @@ -231,7 +240,7 @@ class CollectionFragmentPicker( iconPhone.tooltipText = getTooltip(R.drawable.phone_call) iconParking.tooltipText = getTooltip(R.drawable.ic_local_parking_black_24dp) iconUpdate.tooltipText = getTooltip(R.drawable.ic_autorenew_black_24dp) - + iconClean.tooltipText = getTooltip(R.drawable.ic_clean_shelving) } listIcons.add(iconPrint) if (type == CONTROLADOR) { @@ -246,6 +255,8 @@ class CollectionFragmentPicker( listIcons.add(iconAdd) if (type == SACADOR) { + //Tarea 8624 + listIcons.add(iconClean) listIcons.add(iconUpdate) listIcons.remove(iconWorker) } @@ -260,6 +271,7 @@ class CollectionFragmentPicker( override fun onOptionsItemSelected(item: Drawable) { when (item) { + iconClean.drawable -> clean() iconPrint.drawable -> print() iconAdd.drawable -> addItem() iconWorker.drawable -> showUser() @@ -272,9 +284,86 @@ class CollectionFragmentPicker( } } + }) binding.mainToolbar.toolbarIcons.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false) + updateIconColor() + } + + private fun updateIconColor() { + val newColor = + ContextCompat.getColor( + requireContext(), + if (mobileApplication.dataStoreApp.readDataStoreKey("SHELVINGACTION") + .isNotBlank() + ) R.color.verdnatura_orange_salix else R.color.verdnatura_white + ) + iconClean.setColorFilter(newColor, PorterDuff.Mode.SRC_IN) + binding.mainToolbar.toolbarIcons.adapter?.notifyDataSetChanged() + + } + + private fun addWorkerActivity(codeWorkerAction: CodeWorkerAction, shelving: String) { + viewModel.addWorkerActivity( + CleanAction( + codeWorkerAction = codeWorkerAction, + shelving = shelving.uppercase(), + description = shelving.uppercase() + ) + ) + } + + private fun clean() { + + val shelving = mobileApplication.dataStoreApp.readDataStoreKey( + "SHELVINGACTION" + ) + if ( + shelving.isNotBlank() + ) { + addWorkerActivity( + CodeWorkerAction.SHELVING_CLEAN_STOP, + shelving = shelving + ) + + } else { + customDialogInput.setTitle(getString(R.string.titleCleanShelving)) + .setDescription(getString(R.string.descripOrganize)) + .setOkButton(getString(R.string.organize)) { + ma.hideKeyboard(customDialogInput.getEditText()) + actionOrganizeClean(customDialogInput.getValue()) + + }.setKoButton(getString(R.string.cancel)) { + customDialogInput.dismiss() + }.setValue("").show() + customDialogInput.getEditText().requestFocus() + customDialogInput.getEditText().setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0 || actionId == 5) { + + actionOrganizeClean(customDialogInput.getValue()) + return@setOnEditorActionListener true + } + false + } + } + } + + private fun actionOrganizeClean(input: String) { + if (input.isShelving()) { + addWorkerActivity( + CodeWorkerAction.SHELVING_CLEAN_START, + shelving = input + ) + } else { + ma.messageWithSound( + message = getString(R.string.errorInput), + isError = true, + isPlayed = true, + isToasted = true + ) + } + customDialogInput.dismiss() } private fun updateScreen() { @@ -331,9 +420,7 @@ class CollectionFragmentPicker( ma.hideKeyboard(customDialogList.getEditText()) try { val saleGroupScanned = itemScanValue( - customDialogList.getValue(), - arrayOf("saleGroup"), - "id" + customDialogList.getValue(), arrayOf("saleGroup"), "id" ).toString() isScanned = event != null && event.action == KeyEvent.ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER @@ -464,7 +551,22 @@ class CollectionFragmentPicker( @RequiresApi(Build.VERSION_CODES.O) override fun observeViewModel() { + with(viewModel) { + loadResponseActivity.observe(viewLifecycleOwner) { event -> + event.getContentIfNotHandled().notNull { + + println("shelvinAction ${it}") + runBlocking { + mobileApplication.dataStoreApp.editDataStoreKey( + "SHELVINGACTION", + if (it.codeWorkerAction == CodeWorkerAction.SHELVING_CLEAN_START) it.shelving else "" + ) + } + + updateIconColor() + } + } collectionTicketList.observe(viewLifecycleOwner, Observer { if (!it.isError) { @@ -929,8 +1031,7 @@ class CollectionFragmentPicker( } - saleAdapter = SaleAdapter( - myGroupList as MutableList, + saleAdapter = SaleAdapter(myGroupList as MutableList, pasillerosItemClickListener!!, object : OnQuantityClickListener { @@ -1010,8 +1111,7 @@ class CollectionFragmentPicker( override fun onTicketColorListener(sale: SaleVO) { } - } - ) + }) lm = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) @@ -1039,7 +1139,7 @@ class CollectionFragmentPicker( } printObservations(observations) - if (!isVerifiedCollection) { + if (!isVerifiedCollection && mobileApplication.userId != 19591) { binding.fragmentSacadorCollections.visibility = View.INVISIBLE verifyCollection() } @@ -1916,6 +2016,7 @@ class CollectionFragmentPicker( if (listPlacementSupply.size == 1) { ticketSelected = listPlacementSupply[0].code!!.toInt() } + customDialogList = CustomDialogList(requireContext()) customDialogList.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) customDialogList.getEditTextTwo().inputType = InputType.TYPE_CLASS_NUMBER customDialogList.getEditText().setRawInputType(InputType.TYPE_CLASS_NUMBER) @@ -2347,18 +2448,15 @@ class CollectionFragmentPicker( } if (isTicket) { val labelDialogHelper = LabelDialogHelper(requireContext()) - labelDialogHelper.showLabelDialog( - onItemSelected = { labelCount -> - viewModel.collectionStickerPrint( - collectionFk = collection.collectionFk, - labelCount = labelCount - ) + labelDialogHelper.showLabelDialog(onItemSelected = { labelCount -> + viewModel.collectionStickerPrint( + collectionFk = collection.collectionFk, labelCount = labelCount + ) - (getString(R.string.Imprimiendo) + mobileApplication.dataStoreApp.readDataStoreKey( - PRINTERNAME - )).toast(requireContext()) - } - ) + (getString(R.string.Imprimiendo) + mobileApplication.dataStoreApp.readDataStoreKey( + PRINTERNAME + )).toast(requireContext()) + }) } else { viewModel.collectionStickerPrint( collectionFk = collection.collectionFk, null diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPickerPreviousNewInterface.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPickerPreviousNewInterface.kt index 89d8bab1..b7091cd9 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPickerPreviousNewInterface.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPickerPreviousNewInterface.kt @@ -342,6 +342,7 @@ class CollectionFragmentPickerPreviousNewInterface( lm!!.scrollToPositionWithOffset(positionConfirm, 0) //lm!!.scrollToPositionWithOffset(storedBackPosition + 1, 0) setTotalLines() + saleAdapter!!.notifyItemChanged(positionConfirm) } else { updateScreen() } @@ -364,8 +365,7 @@ class CollectionFragmentPickerPreviousNewInterface( } } loadResponseReserveAddPrevOK.observe(viewLifecycleOwner) { event -> - event.getContentIfNotHandled().notNull { - } + event.getContentIfNotHandled().notNull {} } loadSetStateResponse.observe(viewLifecycleOwner) { event -> event.getContentIfNotHandled().notNull { @@ -401,119 +401,139 @@ class CollectionFragmentPickerPreviousNewInterface( binding.mainToolbar.toolbarTitle.text = collection.collectionFk.toString() collection.map(requireContext()) - val salesList: ArrayList = ArrayList() - tickets = ArrayList() - var observations = "" - val myPickingFrom = mobileApplication.dataStoreApp.readDataStoreKey("PICKING_FROM") - val myPickingTo = mobileApplication.dataStoreApp.readDataStoreKey("PICKING_TO") - collection.tickets.forEach { ticket -> + val sectorFk = mobileApplication.dataStoreApp.readDataStoreKey(SECTORFK) + if (collection.sectorFk != null && collection.sectorFk != sectorFk) { - if (observations.isNotEmpty()) observations = observations + " " + ticket.observations - ticket.sales.forEach { sale -> + ma.messageWithSound( + getString(R.string.cambia_el_sector_vas_a_preparar_una_previa_que_no_es_de_tu_sector), + isError = true, + isPlayed = true, + isToasted = false + ) + } else { - if (hasPickingOrder) { - if (sale.pickingOrder != null && sale.pickingOrder in myPickingFrom..myPickingTo) { - salesList.add(sale) - } - } else { - salesList.add(sale) - } + val salesList: ArrayList = ArrayList() - } - } - // sales = salesList.sortedWith(compareBy { it.pickingOrderPrevia }.thenBy { it.itemFk }) - //quitar comentarios FALTA AGRUPAR LAS PREVIAS + tickets = ArrayList() + var observations = "" + val myPickingFrom = mobileApplication.dataStoreApp.readDataStoreKey("PICKING_FROM") + val myPickingTo = mobileApplication.dataStoreApp.readDataStoreKey("PICKING_TO") + collection.tickets.forEach { ticket -> - when (type) { - PREITEMPICKERTEST -> { - myGroupList = - salesList.sortedWith(compareBy { it.pickingOrder }.thenBy { it.itemFk }) - } + if (observations.isNotEmpty()) observations = + observations + " " + ticket.observations + ticket.sales.forEach { sale -> - SACADOR -> { - myGroupList = - groupSaleGroup(salesList).sortedWith(compareBy { it.pickingOrder }.thenBy { it.itemFk }) - } - - } - - - saleAdapter = SaleAdapterReserve(myGroupList, pasillerosItemClickListener!!, - - object : OnSaleClickSaleListener { - override fun onSaleClick(sale: Sale) { - - println("sale ${sale.saleFk} ${sale.itemFk} ${sale.isPicked}") - val position = - myGroupList.indexOfFirst { it.itemShelvingSaleFk == sale.itemShelvingSaleFk } - if (position > -1 && !myGroupList[position].isParent) { - if (sale.isPicked == 1) { - unMarkLine(position, myGroupList[position]) - } else { - showScanner(position, sale) + if (hasPickingOrder) { + if (sale.pickingOrder != null && sale.pickingOrder in myPickingFrom..myPickingTo) { + salesList.add(sale) } } else { - //TODO desmarcamos una linea de previa ? + salesList.add(sale) } } + } + // sales = salesList.sortedWith(compareBy { it.pickingOrderPrevia }.thenBy { it.itemFk }) + //quitar comentarios FALTA AGRUPAR LAS PREVIAS - }, object : OnMistakeClickListener { - override fun onMistakeClickListener(sale: SaleVO) { + when (type) { + PREITEMPICKERTEST -> { + myGroupList = + salesList.sortedWith(compareBy { it.pickingOrder }.thenBy { it.itemFk }) } - }, object : OnPackingClickSaleListener { - override fun onPackingClick(sale: Sale) { - if (!sale.code.isNullOrEmpty()) ma.onPasillerosItemClickListener( - PasillerosItemVO( - title = R.string.titleUbicator, - ), entryPoint = sale.code - ) + SACADOR -> { + myGroupList = + groupSaleGroup(salesList).sortedWith(compareBy { it.pickingOrder }.thenBy { it.itemFk }) } - }, object : OnTicketClickSaleListener { - override fun onTicketClickListener(sale: Sale) { - val entryPoint = Gson().toJson( - mutableMapOf( - "entryPoint" to sale.ticketFk, "web" to "${ - mobileApplication.dataStoreApp.readDataStoreKey( - BASEURLSALIX - ) - }/#!/ticket/${sale.ticketFk}/sale" + + } + + + saleAdapter = SaleAdapterReserve(myGroupList, pasillerosItemClickListener!!, + + object : OnSaleClickSaleListener { + override fun onSaleClick(sale: Sale) { + + println("sale ${sale.saleFk} ${sale.itemFk} ${sale.isPicked}") + val position = + myGroupList.indexOfFirst { it.itemShelvingSaleFk == sale.itemShelvingSaleFk } + if (position > -1 && !myGroupList[position].isParent) { + if (sale.isPicked == 1) { + unMarkLine(position, myGroupList[position]) + } else { + + if (sale.itemShelvingSaleFk == 0 && sale.itemShelvingFk == 0 && sale.code.isNullOrEmpty()) + showManagement(sale) + else { + showScanner(position, sale) + } + + } + } else { + //TODO desmarcamos una linea de previa ? + } + + } + + }, object : OnMistakeClickListener { + override fun onMistakeClickListener(sale: SaleVO) { + } + }, object : OnPackingClickSaleListener { + override fun onPackingClick(sale: Sale) { + + if (!sale.code.isNullOrEmpty()) ma.onPasillerosItemClickListener( + PasillerosItemVO( + title = R.string.titleUbicator, + ), entryPoint = sale.code ) - ) - ma.onPasillerosItemClickListener( - PasillerosItemVO( - title = R.string.titleWebViewer, - ), entryPoint = entryPoint - ) - } - }, onReserveSaleClick = object : OnSaleReserveClickListener { - override fun onSaleReserveListener(sale: Sale) { - showDeleteItemShelving(sale) - } + } + }, object : OnTicketClickSaleListener { + override fun onTicketClickListener(sale: Sale) { + val entryPoint = Gson().toJson( + mutableMapOf( + "entryPoint" to sale.ticketFk, "web" to "${ + mobileApplication.dataStoreApp.readDataStoreKey( + BASEURLSALIX + ) + }/#!/ticket/${sale.ticketFk}/sale" + ) + ) + ma.onPasillerosItemClickListener( + PasillerosItemVO( + title = R.string.titleWebViewer, + ), entryPoint = entryPoint + ) + } + }, onReserveSaleClick = object : OnSaleReserveClickListener { + override fun onSaleReserveListener(sale: Sale) { + showDeleteItemShelving(sale) + } - }, onAddItemClickListener = object : OnAddItemClickListener { + }, onAddItemClickListener = object : OnAddItemClickListener { - override fun onAddItemClickListener(sale: Sale) { - customDialogAddItemFromSale(sale) - } + override fun onAddItemClickListener(sale: Sale) { + customDialogAddItemFromSale(sale) + } - }, type = type - ) + }, type = type + ) - lm = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) - binding.fragmentSacadorCollections.adapter = saleAdapter - binding.fragmentSacadorCollections.layoutManager = lm + lm = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) + binding.fragmentSacadorCollections.adapter = saleAdapter + binding.fragmentSacadorCollections.layoutManager = lm - setTotalLines() - setListPosition() - setScrollListener(lm!!) - printObservations(observations) - if (!isVerifiedCollection && type == PREPARED) { - binding.fragmentSacadorCollections.visibility = View.INVISIBLE - verifyCollection() + setTotalLines() + setListPosition() + setScrollListener(lm!!) + printObservations(observations) + if (!isVerifiedCollection && type == PREPARED) { + binding.fragmentSacadorCollections.visibility = View.INVISIBLE + verifyCollection() + } } } @@ -739,10 +759,7 @@ class CollectionFragmentPickerPreviousNewInterface( AbsoluteSizeSpan( TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16f, resources.displayMetrics) .toInt(), true - ), - 0, - item.toString().length, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ), 0, item.toString().length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ) try { @@ -759,10 +776,9 @@ class CollectionFragmentPickerPreviousNewInterface( customDialogList.dismiss() scanRequest() - }.setHintValue(getString(R.string.quantitySelect)) - .setTextSize(20f) - .setValue(totalReserved.toString()) - .setHintValueTwo(getString(R.string.scanItem)).setValueTwo("").show() + }.setHintValue(getString(R.string.quantitySelect)).setTextSize(20f) + .setValue(totalReserved.toString()).setHintValueTwo(getString(R.string.scanItem)) + .setValueTwo("").show() customDialogList.getEditTextTwo().setOnEditorActionListener { v, actionId, event -> if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0 || actionId == 5) { @@ -1101,10 +1117,14 @@ class CollectionFragmentPickerPreviousNewInterface( println("No hay salegroup") } } - if (distinctSaleGroups.isNotEmpty()) - distinctSaleGroups.forEach { saleGroup -> + try { + if (distinctSaleGroups.isNotEmpty()) distinctSaleGroups.forEach { saleGroup -> setStateSaleGroup(saleGroup, stateCodeId!!) } + } catch (ex: Exception) { + + } + } } @@ -1321,4 +1341,40 @@ class CollectionFragmentPickerPreviousNewInterface( } } + + private fun showManagement(sale: Sale) { + customDialogThreeButtons = CustomDialogThreeButtons(requireContext()) + customDialogThreeButtons.setCustomDialogValue(View.GONE) + customDialogThreeButtons.setTitle("Gestionar línea artículo ${sale.itemFk}") + .setDescription("Selecciona RESERVAR para añadir reserva y que muestre ubicación") + .setOkButton("Reservar") { + viewModel.itemShelvingSaleAddByCollection(collection.collectionFk) + closeCustomDialogManagement(binding.scanInput, customDialogThreeButtons) + }/*.setOkButtonTwo("Poner a cero la cantidad") { + viewModel.collectionIncreaseQuantitySalix(sale.saleFk, "0") + closeCustomDialogManagement(binding.scanInput, customDialogThreeButtons) + }*/ + .setKoButton(getString(R.string.cancel)) { + closeCustomDialogManagement(binding.scanInput, customDialogThreeButtons) + }.setValue("").show() + + /* customDialogThreeButtons.getEditText().setOnEditorActionListener { v, actionId, event -> + if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0) { + findSaleAction(index, sale) + return@setOnEditorActionListener false + } + false + }*/ + customDialogThreeButtons.getEditText().requestFocus() + } + + private fun closeCustomDialogManagement( + scanInput: EditText, + customDialogInput: CustomDialogThreeButtons + ) { + requireContext().hideKeyboard(customDialogInput.getEditText()) + scanInput.requestFocus() + customDialogInput.dismiss() + scanInput.requestFocus() + } } \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPickerPreviousNewInterfaceSacador.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPickerPreviousNewInterfaceSacador.kt index 887ca4ec..a872c7c6 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPickerPreviousNewInterfaceSacador.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPickerPreviousNewInterfaceSacador.kt @@ -1,6 +1,7 @@ package es.verdnatura.presentation.view.feature.collection.fragment import android.content.Context +import android.graphics.PorterDuff import android.graphics.drawable.Drawable import android.media.MediaPlayer import android.os.Bundle @@ -21,6 +22,7 @@ import android.view.inputmethod.InputMethodManager import android.widget.EditText import android.widget.ImageView import android.widget.Toast +import androidx.core.content.ContextCompat import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.gson.Gson @@ -32,6 +34,7 @@ import es.verdnatura.domain.ConstAndValues.PREPARED import es.verdnatura.domain.ConstAndValues.PRINTERNAME import es.verdnatura.domain.ConstAndValues.SACADOR import es.verdnatura.domain.ConstAndValues.SECTORFK +import es.verdnatura.domain.isShelving import es.verdnatura.domain.notNull import es.verdnatura.domain.showToastCenterWithBackground import es.verdnatura.domain.toast @@ -61,6 +64,8 @@ import es.verdnatura.presentation.view.feature.collection.ItemVO import es.verdnatura.presentation.view.feature.collection.adapter.SaleAdapterReserveSacador import es.verdnatura.presentation.view.feature.collection.mapper.map import es.verdnatura.presentation.view.feature.main.activity.MainActivity +import es.verdnatura.presentation.view.feature.pasillero.model.CleanAction +import es.verdnatura.presentation.view.feature.pasillero.model.CodeWorkerAction import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO import es.verdnatura.presentation.view.feature.sacador.model.CollectionTicket import es.verdnatura.presentation.view.feature.sacador.model.Sale @@ -115,6 +120,7 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( private var isVerifiedCollection = false private var stateCodeId: Number? = null private var stateCodePreparedId: Number? = null + private lateinit var iconClean: ImageView companion object { fun newInstance( @@ -178,22 +184,38 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( iconUpdate.setImageResource(R.drawable.ic_autorenew_black_24dp) val iconPrint = ImageView(context) iconPrint.setImageResource(R.drawable.ic_print_black_24dp) + val iconReserve = ImageView(context) + iconReserve.setImageResource(R.drawable.ic_booking) + iconClean = ImageView(context) + iconClean.setImageResource(R.drawable.ic_clean_shelving) + iconAdd.tooltipText = getTooltip(R.drawable.ic_playlist_add_black_24dp) iconParking.tooltipText = getTooltip(R.drawable.ic_local_parking_black_24dp) iconUpdate.tooltipText = getTooltip(R.drawable.ic_autorenew_black_24dp) iconPrint.tooltipText = getTooltip(R.drawable.ic_print_black_24dp) + iconReserve.tooltipText = getTooltip(R.drawable.ic_booking) + iconClean.tooltipText = getTooltip(R.drawable.ic_clean_shelving) + listIcons.add(iconAdd) listIcons.add(iconUpdate) if (type == PREPARED) listIcons.add(iconPrint) else listIcons.add(iconParking) + // listIcons.add(iconReserve) + listIcons.add(iconClean) binding.mainToolbar.toolbarIcons.adapter = ToolBarAdapterTooltip(listIcons, object : OnOptionsSelectedListener { override fun onOptionsItemSelected(item: Drawable) { when (item) { + iconClean.drawable -> clean() + iconReserve.drawable -> { + println("collection to reserve${collection.collectionFk} ") + viewModel.itemShelvingSaleAddByCollection(collection.collectionFk) + } + iconPrint.drawable -> print() iconAdd.drawable -> addItem() iconUpdate.drawable -> updateScreen() @@ -210,6 +232,68 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false) } + private fun clean() { + + val shelving = mobileApplication.dataStoreApp.readDataStoreKey( + "SHELVINGACTION" + ) + if ( + shelving.isNotBlank() + ) { + addWorkerActivity( + CodeWorkerAction.SHELVING_CLEAN_STOP, + shelving = shelving + ) + + } else { + customDialogInput.setTitle(getString(R.string.titleCleanShelving)) + .setDescription(getString(R.string.descripOrganize)) + .setOkButton(getString(R.string.organize)) { + ma.hideKeyboard(customDialogInput.getEditText()) + actionOrganizeClean(customDialogInput.getValue()) + + }.setKoButton(getString(R.string.cancel)) { + customDialogInput.dismiss() + }.setValue("").show() + customDialogInput.getEditText().requestFocus() + customDialogInput.getEditText().setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0 || actionId == 5) { + + actionOrganizeClean(customDialogInput.getValue()) + return@setOnEditorActionListener true + } + false + } + } + } + + private fun addWorkerActivity(codeWorkerAction: CodeWorkerAction, shelving: String) { + viewModel.addWorkerActivity( + CleanAction( + codeWorkerAction = codeWorkerAction, + shelving = shelving.uppercase(), + description = shelving.uppercase() + ) + ) + } + + private fun actionOrganizeClean(input: String) { + if (input.isShelving()) { + addWorkerActivity( + CodeWorkerAction.SHELVING_CLEAN_START, + shelving = input + ) + } else { + ma.messageWithSound( + message = getString(R.string.errorInput), + isError = true, + isPlayed = true, + isToasted = true + ) + } + customDialogInput.dismiss() + } + private fun updateScreen() { viewModel.collectionTicketGetSalix( collection.collectionFk, print = false @@ -277,15 +361,42 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( } } + private fun updateIconColor() { + val newColor = + ContextCompat.getColor( + requireContext(), + if (mobileApplication.dataStoreApp.readDataStoreKey("SHELVINGACTION") + .isNotBlank() + ) R.color.verdnatura_orange_salix else R.color.verdnatura_white + ) + iconClean.setColorFilter(newColor, PorterDuff.Mode.SRC_IN) + binding.mainToolbar.toolbarIcons.adapter?.notifyDataSetChanged() + + } + override fun observeViewModel() { with(viewModel) { + loadResponseActivity.observe(viewLifecycleOwner) { event -> + event.getContentIfNotHandled().notNull { + + println("shelvinAction ${it}") + runBlocking { + mobileApplication.dataStoreApp.editDataStoreKey( + "SHELVINGACTION", + if (it.codeWorkerAction == CodeWorkerAction.SHELVING_CLEAN_START) it.shelving else "" + ) + } + + updateIconColor() + } + } loadCollectionTicketSalix.observe(viewLifecycleOwner) { event -> event.getContentIfNotHandled().notNull { if (!it.isError) { - if (it.tickets.isNotEmpty()) { + if (it.tickets.size > 0) { collection = it createCollectionList() @@ -314,6 +425,12 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( } } + loadItemShelvingSaleAddByCollection.observe(viewLifecycleOwner) { event -> + event.getContentIfNotHandled().notNull { + updateScreen() + } + } + loadFindItemShelvingResponse.observe(viewLifecycleOwner) { event -> event.getContentIfNotHandled().notNull { @@ -336,6 +453,13 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( } + loadIncQuantity.observe(viewLifecycleOwner) { event -> + event.getContentIfNotHandled().notNull { + updateScreen() + } + + } + loadPicked.observe(viewLifecycleOwner) { event -> event.getContentIfNotHandled().notNull { if (it) { @@ -344,6 +468,7 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( lm!!.scrollToPositionWithOffset(positionConfirm, 0) //lm!!.scrollToPositionWithOffset(storedBackPosition + 1, 0) setTotalLines() + saleAdapter!!.notifyItemChanged(positionConfirm) } else { updateScreen() } @@ -406,18 +531,27 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( private fun createCollectionList() { binding.mainToolbar.toolbarTitle.text = collection.collectionFk.toString() - collection.map(requireContext()) + val allSalesAreNullOrEmpty = collection.tickets.all { it.sales.isNullOrEmpty() } + if (allSalesAreNullOrEmpty) { + ma.messageWithSound( + message = "No se han podido reservas líneas a la colección del/os ticket/s: ${collection.tickets?.map { it.ticketFk }} \n Revisa tu sector si estás en previas", + isError = true, + isPlayed = false, + isToasted = false + ) + } + val salesList: ArrayList = ArrayList() tickets = ArrayList() var observations = "" val myPickingFrom = mobileApplication.dataStoreApp.readDataStoreKey("PICKING_FROM") val myPickingTo = mobileApplication.dataStoreApp.readDataStoreKey("PICKING_TO") - collection.tickets.forEach { ticket -> + collection.tickets?.forEach { ticket -> if (observations.isNotEmpty()) observations = observations + " " + ticket.observations - ticket.sales.forEach { sale -> + ticket.sales?.forEach { sale -> if (hasPickingOrder) { if (sale.pickingOrder != null && sale.pickingOrder in myPickingFrom..myPickingTo) { @@ -457,7 +591,11 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( if (sale.isPicked == 1) { unMarkLine(position, myGroupList[position]) } else { - showScanner(position, sale) + if (sale.itemShelvingSaleFk == 0 && sale.itemShelvingFk == 0 && sale.code.isNullOrEmpty()) + showManagement(sale) + else { + showScanner(position, sale) + } } } else { //TODO desmarcamos una linea de previa ? ya se desmarca el salegroup @@ -551,6 +689,7 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( storedPosition = lm.findFirstVisibleItemPosition() super.onScrolled(recyclerView, dx, dy) } + }) } @@ -672,12 +811,12 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( quantityConfirm = quantity runBlocking { - val sectorFk = mobileApplication.dataStoreApp.readDataStoreKey(SECTORFK) + // val sectorFk = mobileApplication.dataStoreApp.readDataStoreKey(SECTORFK) viewModel.itemShelvingSaleSetQuantity( myGroupList[position].itemShelvingSaleFk, quantity, isItemShelvingSaleEmpty = isItemShelvingSaleEmpty, - sectorFk = if (sectorFk == -1) null else sectorFk, + sectorFk = null, shelvingFk = myGroupList[position].code!! ) } @@ -1148,6 +1287,45 @@ class CollectionFragmentPickerPreviousNewInterfaceSacador( customDialogInput.getEditText().requestFocus() } + //Falta ver si ponemos a cero la linea como la representamos , qué nos indica que + // está cogida ?? No tiene itemShelvinSale + // PONEMOS ISPICKED A 1 + private fun showManagement(sale: Sale) { + customDialogThreeButtons = CustomDialogThreeButtons(requireContext()) + customDialogThreeButtons.setCustomDialogValue(View.GONE) + customDialogThreeButtons.setTitle("Gestionar línea artículo ${sale.itemFk}") + .setDescription("Selecciona RESERVAR para añadir reserva y que muestre ubicación") + .setOkButton("Reservar") { + viewModel.itemShelvingSaleAddByCollection(collection.collectionFk) + closeCustomDialogManagement(binding.scanInput, customDialogThreeButtons) + }/*setOkButtonTwo("Poner a cero la cantidad") { + viewModel.collectionIncreaseQuantitySalix(sale.saleFk, "0") + closeCustomDialogManagement(binding.scanInput, customDialogThreeButtons) + }.*/ + .setKoButton(getString(R.string.cancel)) { + closeCustomDialogManagement(binding.scanInput, customDialogThreeButtons) + }.setValue("").show() + + /* customDialogThreeButtons.getEditText().setOnEditorActionListener { v, actionId, event -> + if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0) { + findSaleAction(index, sale) + return@setOnEditorActionListener false + } + false + }*/ + customDialogThreeButtons.getEditText().requestFocus() + } + + private fun closeCustomDialogManagement( + scanInput: EditText, + customDialogInput: CustomDialogThreeButtons + ) { + requireContext().hideKeyboard(customDialogInput.getEditText()) + scanInput.requestFocus() + customDialogInput.dismiss() + scanInput.requestFocus() + } + private fun findSaleAction(index: Int, sale: Sale) { if (customDialogInput.getValue().isNotEmpty()) { findSale(customDialogInput.getValue(), index, sale) diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPreChecker.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPreChecker.kt index 1303d8ad..c610b0d3 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPreChecker.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionFragmentPreChecker.kt @@ -688,20 +688,22 @@ class CollectionFragmentPreChecker( }) - responseIncQuantity.observe(viewLifecycleOwner, Observer { + loadIncQuantity.observe(viewLifecycleOwner) { event -> + event.getContentIfNotHandled().notNull { - if (it.isError) { - ma.messageWithSound(it.errorMessage, isError = true, true) + if (it.isError) { + ma.messageWithSound(it.errorMessage, isError = true, true) - } else { - if (!goBack) { - incresaseSuccesful() } else { - goBack = false + if (!goBack) { + incresaseSuccesful() + } else { + goBack = false + } } - } - }) + } + } responseSaleMistakeAdd.observe(viewLifecycleOwner, Observer { diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionViewModel.kt index 2bc710e8..33d59c3c 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/CollectionViewModel.kt @@ -13,6 +13,7 @@ import es.verdnatura.domain.getMessageFromAllResponse import es.verdnatura.domain.nameofFunction import es.verdnatura.domain.toast import es.verdnatura.domain.userCases.GetItemFromBarcodeUseCase +import es.verdnatura.domain.userCases.WorkerActivityUseCase import es.verdnatura.presentation.base.BaseViewModel import es.verdnatura.presentation.common.Event import es.verdnatura.presentation.common.ItemShelving @@ -23,6 +24,8 @@ import es.verdnatura.presentation.common.TicketState import es.verdnatura.presentation.view.feature.collection.ItemVO import es.verdnatura.presentation.view.feature.collection.SalixSaleQuantity import es.verdnatura.presentation.view.feature.collection.mapper.map +import es.verdnatura.presentation.view.feature.pasillero.model.CleanAction +import es.verdnatura.presentation.view.feature.pasillero.model.WorkerActionSalix import es.verdnatura.presentation.view.feature.sacador.model.CollectionTicket import es.verdnatura.presentation.view.feature.sacador.model.CollectionVO import es.verdnatura.presentation.view.feature.sacador.model.ItemShelvingSale @@ -37,6 +40,7 @@ import retrofit2.Response class CollectionViewModel(val context: Context) : BaseViewModel(context) { private val getItemFromBarcodeUseCase = GetItemFromBarcodeUseCase(salix) + private val getWokerActivityUseCase = WorkerActivityUseCase(salix) private val contextApp = context private val _responseState by lazy { MutableLiveData() } @@ -233,6 +237,16 @@ class CollectionViewModel(val context: Context) : BaseViewModel(context) { val loadSetStateResponse: LiveData> = _setStateResponse.map { Event(it) } + private val _responseActivity by lazy { MutableLiveData() } + val responseActivity: LiveData = _responseActivity + val loadResponseActivity: LiveData> = + _responseActivity.map { Event(it) } + + private val _itemShelvingSaleAddByCollection by lazy { MutableLiveData() } + val itemShelvingSaleAddByCollection: LiveData = _itemShelvingSaleAddByCollection + val loadItemShelvingSaleAddByCollection: LiveData> = + _itemShelvingSaleAddByCollection.map { Event(it) } + fun getSales( collectionFk: Number, print: String, source: String @@ -876,13 +890,20 @@ class CollectionViewModel(val context: Context) : BaseViewModel(context) { }) } - fun getIdFromCodeSalix(code: String) { - getItemFromBarcodeUseCase.execute(code).enqueue(object : SalixCallback(context) { - override fun onSuccess(response: Response) { - _responseCode.value = response.body() + fun addWorkerActivity(activity: CleanAction) { + getWokerActivityUseCase.addWorkerActivity( + WorkerActionSalix( + code = activity.codeWorkerAction.toString(), + description = activity.description + ) + ) + .enqueue(object : SalixCallback(context) { + override fun onSuccess(response: Response) { + println("shelvinAction onResposne${activity}") + _responseActivity.value = activity - } - }) + } + }) } fun saleGroupUpdateState(saleGroup: Number, codeState: Number) { @@ -1126,4 +1147,23 @@ class CollectionViewModel(val context: Context) : BaseViewModel(context) { }) } + fun getIdFromCodeSalix(code: String) { + getItemFromBarcodeUseCase.execute(code).enqueue(object : SalixCallback(context) { + override fun onSuccess(response: Response) { + _responseCode.value = response.body() + + } + }) + } + + fun itemShelvingSaleAddByCollection(collection: Number) { + salix.itemShelvingSaleAddByCollection(params = collection) + .enqueue( + object : + SalixCallback(context) { + override fun onSuccess(response: Response) { + _itemShelvingSaleAddByCollection.value = true + } + }) + } } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/ShowTicketFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/ShowTicketFragment.kt index eedd3c29..8b8ef533 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/ShowTicketFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/fragment/ShowTicketFragment.kt @@ -22,6 +22,7 @@ import es.verdnatura.presentation.common.OnPackingClickListener import es.verdnatura.presentation.common.OnPasillerosItemClickListener import es.verdnatura.presentation.common.OnQuantityClickListener import es.verdnatura.presentation.common.OnSaleClickListener +import es.verdnatura.presentation.common.OnTicketColorListener import es.verdnatura.presentation.common.ToolBarAdapterTooltip import es.verdnatura.presentation.common.hideKeyboard import es.verdnatura.presentation.common.itemScanValue @@ -43,6 +44,7 @@ class CollectionShowTicketFragment( private var lastScanned: Int = 0 private var buttonPushedGetCollection = false + private var hasFilterByLevel = false companion object { fun newInstance(collection: CollectionVO, type: String) = @@ -300,6 +302,18 @@ class CollectionShowTicketFragment( override fun onPackingClick(sale: SaleVO) { } + }, onTicketColorClickListener = object : OnTicketColorListener { + override fun onTicketColorListener(sale: SaleVO) { + hasFilterByLevel = !hasFilterByLevel + + if (hasFilterByLevel) { + if (buttonPushedGetCollection) { + saleAdapter!!.updateSales(salesList.filter { it.level == sale.level } as MutableList) + } + } else { + createCollectionList() + } + } }) lm = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/mapper/CollectionMapper.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/mapper/CollectionMapper.kt index 527aa648..d51875d7 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/collection/mapper/CollectionMapper.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/collection/mapper/CollectionMapper.kt @@ -20,7 +20,6 @@ fun CollectionVO.map(context: Context): CollectionVO { it.ticketFk = ticket.ticketFk it.level = ticket.level it.rgb = ticket.rgb - it.salePersonFk = ticket.salesPersonFk it.agencyName = ticket.agencyName it.isNew = it.isAdded == "1" it.code = it.cel3 @@ -65,22 +64,24 @@ fun CollectionVO.map(context: Context): CollectionVO { fun CollectionTicket.map(context: Context): CollectionTicket { try { - this.tickets.forEach { ticket -> - ticket.sales.forEach { - it.level = ticket.level ?: "" - it.rgb = ticket.rgb ?: "" + val allSalesAreNullOrEmpty = tickets.all { it.sales.isNullOrEmpty() } + if (!allSalesAreNullOrEmpty) { + this.tickets?.forEach { ticket -> + ticket.sales?.forEach { + it.level = ticket.level ?: "" + it.rgb = ticket.rgb ?: "" + } } - } + } } catch (e: Exception) { this.isError = true - if (this.tickets.isNullOrEmpty()) { + if (this.tickets.isEmpty()) { this.errorMessage = context.getString(R.string.collectionNoTicketsError) } else { this.errorMessage = context.getString(R.string.collectionErrorBuilding) + context.getString(R.string.reviewSector) } - } return this } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/controlvehiculo/fragment/ControlVehiculoUsuarioFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/controlvehiculo/fragment/ControlVehiculoUsuarioFragment.kt index f914490d..e4612b00 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/controlvehiculo/fragment/ControlVehiculoUsuarioFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/controlvehiculo/fragment/ControlVehiculoUsuarioFragment.kt @@ -52,7 +52,6 @@ class ControlVehiculoUsuarioFragment( if (userFk == vUserFK) { val androidId: String = mobileApplication.dataStoreApp.readDataStoreKey(ANDROID_ID) - // viewModel.machineGetWorkerPlate(mobileApplication.userId!!) viewModel.deviceProductionGetnameDevice( androidId ) @@ -64,7 +63,6 @@ class ControlVehiculoUsuarioFragment( binding.userInformation.visibility = INVISIBLE binding.nameVehiclecontrol.visibility = INVISIBLE binding.userImage.setOnClickListener { binding.mainToolbar.backButton.performClick() } - // viewModel.machineGetWorkerPlate(mobileApplication.userId!!) binding.nameVehiclecontrol.visibility = VISIBLE viewModel.getNameWorker(userFk) } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/fragments/LoadUnloadFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/fragments/LoadUnloadFragment.kt index 70dc0a26..62fd78af 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/fragments/LoadUnloadFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/fragments/LoadUnloadFragment.kt @@ -4,7 +4,8 @@ import android.content.Context import android.content.Intent import android.graphics.drawable.Drawable import android.os.Bundle -import android.view.KeyEvent +import android.text.Editable +import android.text.TextWatcher import android.view.View import android.view.inputmethod.EditorInfo import android.widget.ImageView @@ -16,6 +17,8 @@ import androidx.recyclerview.widget.LinearLayoutManager import es.verdnatura.R import es.verdnatura.databinding.FragmentExpeditionLoadunloadDeliveryBinding import es.verdnatura.db.DeliveryDatabase +import es.verdnatura.domain.ConstAndValues.HUMAN_CHARACTERS_SECOND +import es.verdnatura.domain.ConstAndValues.SCANNER_THRESHOLD_SPEED import es.verdnatura.domain.toDateString import es.verdnatura.domain.toast import es.verdnatura.presentation.base.BaseFragment @@ -44,9 +47,10 @@ class LoadUnloadFragment( private var title: String = "", private var state: String = "", private var entryPoint: String, - private var clientTicketList: ArrayList? + private var clientTicketList: ArrayList?, + private var startInputTime: Long = 0L, -) : BaseFragment( + ) : BaseFragment( DeliveryViewModel::class ), OnBackPressedListener { @@ -85,6 +89,24 @@ class LoadUnloadFragment( } } }) + + binding.scanInput.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + + } + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + if (before == 0 && count > 0) { + startInputTime = System.currentTimeMillis() + } + + } + }) + } override fun getLayoutId(): Int = R.layout.fragment_expedition_loadunload_delivery @@ -179,30 +201,16 @@ class LoadUnloadFragment( private fun setExpeditionsState(list: MutableList, state: String) { scanning(false) - /* val mlist = mutableListOf() - for (l in list) { - mlist.add( - ExpeditionSalix( - expeditionFk = l.id, - stateCode = if (l.code != state && l.code != "FOUND" && l.code != "DELIVERED") { - if (state == "ON DELIVERY") "NOT SCANNED" else "LOST" - } else { - l.code - }, - isScanned = l.isScanned - ) - ) - }*/ val mlistPosition = mutableListOf() for (l in list) { mlistPosition.add( ExpeditionSalixPosition( expeditionFk = l.id, stateCode = if (l.code == "FOUND") (l.code) else { - if (state == "ON DELIVERY" && l.code != "ON DELIVERY" && l.code != "DELIVERED" && l.code != "LOST" && l.code != "PENDING") { + if (state == "ON DELIVERY" && l.code != "ON DELIVERY" && l.code != "DELIVERED" && l.code != "LOST" && l.code != "PENDING" && l.code != "STORED") { "NOT SCANNED" } else { - if (state == "DELIVERED" && l.code != "DELIVERED") "PENDING" else l.code + if (state == "DELIVERED" && l.code != "DELIVERED" && l.code != "STORED") "PENDING" else l.code } }, isScanned = l.isScanned, @@ -277,8 +285,12 @@ class LoadUnloadFragment( if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0 || actionId == EditorInfo.IME_ACTION_NEXT) { if (!binding.scanInput.text.isNullOrEmpty()) { + + val totalTime = (System.currentTimeMillis() - startInputTime) + val charsPerSecond = (binding.scanInput.text!!.length * 1000.0) / totalTime val isScanned = - event != null && event.action == KeyEvent.ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER + charsPerSecond > HUMAN_CHARACTERS_SECOND && totalTime < SCANNER_THRESHOLD_SPEED + //Tarea 8152 // showconfirmExpedition(binding.scanInput.text.toString().toInt(), isScanned) try { diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/fragments/SummaryFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/fragments/SummaryFragment.kt index a77964fb..d080935c 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/fragments/SummaryFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/fragments/SummaryFragment.kt @@ -1,7 +1,9 @@ package es.verdnatura.presentation.view.feature.delivery.fragments import android.graphics.drawable.Drawable -import android.view.KeyEvent +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher import android.view.View import android.view.inputmethod.EditorInfo import android.widget.ImageView @@ -11,6 +13,8 @@ import androidx.recyclerview.widget.RecyclerView import com.google.gson.Gson import es.verdnatura.R import es.verdnatura.databinding.FragmentExpeditionSummaryBinding +import es.verdnatura.domain.ConstAndValues.HUMAN_CHARACTERS_SECOND +import es.verdnatura.domain.ConstAndValues.SCANNER_THRESHOLD_SPEED import es.verdnatura.domain.toast import es.verdnatura.presentation.base.BaseFragment import es.verdnatura.presentation.common.AdapterCallback @@ -44,6 +48,7 @@ class SummaryFragment( private var routeSelected = 0 private var isScanning = false private var positionSelected = -1 + private var startInputTime: Long = 0L override fun getPosition(): Int { return positionSelected @@ -67,6 +72,26 @@ class SummaryFragment( } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.scanInput.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + + } + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + if (before == 0 && count > 0) { + startInputTime = System.currentTimeMillis() + } + + } + }) + } + override fun onResume() { if (binding.mainToolbar.toolbarTitle.text != getString(R.string.titleDeliverySummary)) { binding.scanInput.isEnabled = true @@ -151,10 +176,10 @@ class SummaryFragment( val listExpedition = list.filter { it.addressFk == address }.map { l -> ExpeditionSalixPosition( expeditionFk = l.id, stateCode = if (l.code == "FOUND") (l.code) else { - if (state == "ON DELIVERY" && l.code != "ON DELIVERY" && l.code != "DELIVERED" && l.code != "LOST") { + if (state == "ON DELIVERY" && l.code != "ON DELIVERY" && l.code != "DELIVERED" && l.code != "LOST" && l.code != "PENDING" && l.code != "STORED") { "NOT SCANNED" } else { - if (state == "DELIVERED" && l.code != "DELIVERED") "LOST" else l.code + if (state == "DELIVERED" && l.code != "DELIVERED" && l.code != "STORED") "PENDING" else l.code } }, isScanned = l.isScanned, scanOrder = l.scanOrder @@ -200,8 +225,12 @@ class SummaryFragment( if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0) { if (!binding.scanInput.text.isNullOrEmpty()) { isScanning = true + /* val isScanned = + event != null && event.action == KeyEvent.ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER*/ + val totalTime = (System.currentTimeMillis() - startInputTime) + val charsPerSecond = (binding.scanInput.text!!.length * 1000.0) / totalTime val isScanned = - event != null && event.action == KeyEvent.ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER + charsPerSecond > HUMAN_CHARACTERS_SECOND && totalTime < SCANNER_THRESHOLD_SPEED try { markExpedition( binding.scanInput.text.toString().toInt(), @@ -233,14 +262,6 @@ class SummaryFragment( found = true exped.code = state exped.isScanned = isScanned - - println( - "scanOrder markExpedition${ - myList.filter { it.addressFk == addressFkSelected } - .filter { it.code == state }.size - }" - ) - exped.scanOrder = myList.filter { it.addressFk == addressFkSelected } .filter { it.code == state }.size break diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/model/ClientTicket.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/model/ClientTicket.kt index 77c5e4b1..d23f5bd9 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/model/ClientTicket.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/delivery/model/ClientTicket.kt @@ -24,7 +24,10 @@ data class ClientTicketSalix( var postalCode: String, var city: String, var warehouseName: String?, - var salePersonPhone: String?, + @SerializedName( + value = "salePersonPhone", + alternate = ["departmentPhone"] + ) var salePersonPhone: String?, @SerializedName(value = "ticketObservation", alternate = ["observationDelivery"]) var observationDelivery: String?, var observationDropOff: String?, diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/DayOfSaleFragmentCompose.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/DayOfSaleFragmentCompose.kt new file mode 100644 index 00000000..0bcdd0e9 --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/DayOfSaleFragmentCompose.kt @@ -0,0 +1,137 @@ +package es.verdnatura.presentation.view.feature.diadeventa.fragment + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.inputmethod.EditorInfo +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.platform.ComposeView +import androidx.fragment.app.Fragment +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import es.verdnatura.R +import es.verdnatura.presentation.common.OnPasillerosItemClickListener +import es.verdnatura.presentation.composable.IconToolBar +import es.verdnatura.presentation.view.component.CustomDialog +import es.verdnatura.presentation.view.component.CustomDialogList +import es.verdnatura.presentation.view.feature.diadeventa.adapter.DayOfSaleAdapter +import es.verdnatura.presentation.view.feature.main.activity.MainActivity +import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO +import org.koin.androidx.viewmodel.ext.android.viewModel + +class DayOfSaleFragmentCompose( + var title: String = "" +) : Fragment() { + private val viewModel: DayOfSaleViewModelCompose by viewModel() + + private lateinit var customDialogList: CustomDialogList + private lateinit var customDialog: CustomDialog + private var adapter: DayOfSaleAdapter? = null + private var itemScan = "" + private var pasillerosItemClickListener: OnPasillerosItemClickListener? = null + + companion object { + fun newInstance(title: String) = DayOfSaleFragmentCompose(title) + } + + override fun onAttach(context: Context) { + if (context is OnPasillerosItemClickListener) pasillerosItemClickListener = context + super.onAttach(context) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View { + return ComposeView(requireContext()).apply { + setContent { + SetView() + } + } + } + + @Composable + private fun SetView() { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + + val columnActions = listOf<(List) -> Unit>( + // { item -> println("Producto seleccionado: ${item[0]}") }, // Acción para la primera columna + // { item -> println("Stock: ${item[1]}") }, // Acción para la segunda columna + // { item -> println("Visible: ${item[2]}") } // Acción para la tercera columna + ) + + GenericListScreen( + uiState.items.map { item -> + listOf( + item.itemFk?.toString() ?: "", + item.longName ?: "", + item.dated, + item.visible?.toString() ?: "", + item.stock?.toString() ?: "" + ) + }, + columnActions = columnActions, + headers = listOf( + getString(R.string.itemfk), + getString(R.string.name), + getString(R.string.date), + getString(R.string.visible), + getString(R.string.stock) + ), + onTextChange = { input -> + viewModel.itemShelvingGetSaleDate(input) + }, + titleToolBar = + if (uiState.shelvingCode.isNullOrEmpty()) title else title + " " + uiState.shelvingCode, + onBackClick = { (context as MainActivity).onMyBackPressed() }, + onLongClick = { }, + onClick = { item -> openSearchItemFragment(item[0]) }, + listIconToolBar = listOf( + IconToolBar( + idRes = R.drawable.ic_local_parking_black_24dp, + toolTip = getString(R.string.allowParking), + onClickIcon = { showParking() }, + ) + ) + ) + } + + private fun showParking() { + + customDialogList = CustomDialogList(requireContext()) + customDialogList.setTitle(getString(R.string.showParking)) + .setOkButton(getString(R.string.close)) { + + customDialogList.dismiss() + }.setValue("").show() + + customDialogList.getEditText().requestFocus() + customDialogList.getEditText().setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0 || actionId == 5) { + if (customDialogList.getValue().isNotEmpty()) { + viewModel.setParking( + parking = customDialogList.getValue(), + scanItem = itemScan + ) + + customDialogList.dismiss() + } + customDialogList.setValue("") + return@setOnEditorActionListener true + } + false + } + + } + + private fun openSearchItemFragment(item: String) { + pasillerosItemClickListener!!.onPasillerosItemClickListener( + PasillerosItemVO( + title = + R.string.titleItemConsult + ), item + ) + } +} + diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/DayOfSaleViewModelCompose.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/DayOfSaleViewModelCompose.kt new file mode 100644 index 00000000..bbf2eedd --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/DayOfSaleViewModelCompose.kt @@ -0,0 +1,53 @@ +package es.verdnatura.presentation.view.feature.diadeventa.fragment + +import es.verdnatura.domain.SalixCallback +import es.verdnatura.domain.formatWithQuotes +import es.verdnatura.presentation.base.BaseViewModelCompose +import es.verdnatura.presentation.view.feature.diadeventa.model.ItemShelvingSaleDate +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import retrofit2.Response + +data class UiState( + val shelvingCode: String? = null, + val items: List = emptyList() +) + +class DayOfSaleViewModelCompose(var application: android.app.Application) : + BaseViewModelCompose(application) { + + private val _uiState = MutableStateFlow(UiState()) + val uiState = _uiState.asStateFlow() + + fun itemShelvingGetSaleDate(vShelvingFK: String) { + _uiState.update { it.copy(shelvingCode = vShelvingFK) } + salix.itemShelvingGetSaleDate(params = listOf(vShelvingFK).formatWithQuotes()) + .enqueue(object : + SalixCallback>(application.applicationContext) { + + override fun onSuccess(response: Response>) { + + response.body()?.let { list -> + _uiState.update { it.copy(items = list) } + + } + + } + }) + } + + fun setParking(scanItem: String, parking: String) { + salix.setParking(arrayListOf(scanItem, parking).formatWithQuotes()) + .enqueue(object : SalixCallback(application.applicationContext) {}) + } + +} + + + + + + + + diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/GenericListScreen.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/GenericListScreen.kt new file mode 100644 index 00000000..489c9a85 --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/diadeventa/fragment/GenericListScreen.kt @@ -0,0 +1,215 @@ +package es.verdnatura.presentation.view.feature.diadeventa.fragment + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.onFocusEvent +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.core.content.ContextCompat +import es.verdnatura.R +import es.verdnatura.presentation.composable.CustomToolbar +import es.verdnatura.presentation.composable.IconToolBar +import es.verdnatura.presentation.composable.LottieLoadingAnimation +import es.verdnatura.presentation.composable.ScanLineTextSearch +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +@Composable +fun GenericListScreen( + items: List>, // Lista de listas de strings para los datos + headers: List,// Lista de encabezados + columnActions: List<(List) -> Unit>, // Lista de acciones + onTextChange: (String) -> Unit, + titleToolBar: String, + onBackClick: () -> Unit = {}, + onLongClick: (List) -> Unit, + onClick: (List) -> Unit, + listIconToolBar: List = listOf() +) { + var searchText by remember { mutableStateOf("") } + val focusRequester = remember { FocusRequester() } + val keyboardController = LocalSoftwareKeyboardController.current + var showLoading by remember { mutableStateOf(false) } + + val onImeAction: () -> Unit = { + onTextChange(searchText) + searchText = "" + keyboardController?.hide() + } + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.Black) + ) { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.Black) + ) { + if (showLoading) { + LottieLoadingAnimation(true) + } + CustomToolbar( + title = titleToolBar, + subtitle = "", + showBackButton = true, + showSwitch = false, + iconList = listIconToolBar, + onBackClick = onBackClick, + onSwitchChange = { } + ) + Spacer(modifier = Modifier.height(8.dp)) + + ScanLineTextSearch( + value = searchText, + onValueChange = { + searchText = it + showLoading = true + }, + onImeAction, + modifier = Modifier + .focusRequester(focusRequester) + .onFocusEvent { + if (it.isFocused) { + keyboardController?.hide() + } + } + ) + LaunchedEffect(Unit) { + focusRequester.requestFocus() + keyboardController?.hide() + } + + // Encabezados + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + headers.forEach { text -> + Text( + text = text, + color = Color.White, + fontSize = 14.sp, + modifier = Modifier.weight(1f) + ) + } + } + + HorizontalDivider(thickness = 1.dp, color = Color.White) + + LazyColumn(modifier = Modifier.fillMaxSize()) { + items(items) { item -> + GenericRow( + values = item, + onLongClick = { onLongClick(item) }, + onClick = { onClick(item) }, + columnActions = columnActions + ) + HorizontalDivider(thickness = 1.dp, color = Color.White) + } + } + showLoading = false + } + } +} + +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun GenericRow( + values: List, + onLongClick: () -> Unit, + onClick: () -> Unit, + columnActions: List<(List) -> Unit> +) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp) + .combinedClickable(onClick = onClick, onLongClick = onLongClick), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + values.forEachIndexed { index, value -> + val sdf = SimpleDateFormat(stringResource(R.string.dateFormat), Locale.getDefault()) + val currentDate = sdf.format(Date()) + + val context = LocalContext.current // Accediendo al contexto + + val customOrange = ContextCompat.getColor(context, R.color.verdnatura_pumpkin_orange) + val customWhite = ContextCompat.getColor(context, R.color.verdnatura_white) + val color = if (value == currentDate) Color(customOrange) else Color(customWhite) + + Text( + text = value, + color = color, + textAlign = TextAlign.Center, + modifier = Modifier + .weight(1f) + .then(if (index < columnActions.size) Modifier.clickable { + columnActions[index](values) + } else Modifier) + .align(Alignment.CenterVertically) + .padding(4.dp) + ) + + } + } +} + +@Composable +fun TextDayOfSale( + values: List, + value: String, + index: Int, + columnActions: List<(List) -> Unit> +) { + val sdf = SimpleDateFormat(stringResource(R.string.dateFormat), Locale.getDefault()) + val currentDate = sdf.format(Date()) + + val context = LocalContext.current + val customOrange = ContextCompat.getColor(context, R.color.verdnatura_pumpkin_orange) + val customWhite = ContextCompat.getColor(context, R.color.verdnatura_white) + val color = if (value == currentDate) Color(customOrange) else Color(customWhite) + + Text( + text = value, + color = color, + modifier = Modifier + .then(if (index < columnActions.size) Modifier.clickable { + columnActions[index](values) + } else Modifier) + ) +} \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/historicoarticulo/adapter/HistoricoAdapter.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/historicoarticulo/adapter/HistoricoAdapter.kt index 223d251a..75bf2a70 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/historicoarticulo/adapter/HistoricoAdapter.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/historicoarticulo/adapter/HistoricoAdapter.kt @@ -44,7 +44,7 @@ class HistoricoAdapter( historicoDate.setBackgroundColor( ContextCompat.getColor( - historicoDate.context, if (currentDate == item.shipped) { + historicoDate.context, if (item.shipped.contains(currentDate)) { R.color.verdnatura_pumpkin_orange } else { R.color.verdnatura_black_5 diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/historicoarticulo/fragment/HistoricoArticuloFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/historicoarticulo/fragment/HistoricoArticuloFragment.kt index 815c8e7f..71fa8c35 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/historicoarticulo/fragment/HistoricoArticuloFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/historicoarticulo/fragment/HistoricoArticuloFragment.kt @@ -13,6 +13,7 @@ import es.verdnatura.R.color.verdnatura_white import es.verdnatura.databinding.FragmentHistoricoBinding import es.verdnatura.domain.ConstAndValues.WAREHOUSEFK import es.verdnatura.domain.notNull +import es.verdnatura.domain.toast import es.verdnatura.presentation.base.BaseFragment import es.verdnatura.presentation.common.OnClientHistoricItemClickListener import es.verdnatura.presentation.common.OnOptionsSelectedListener @@ -193,23 +194,27 @@ class HistoricoArticuloFragment( listHistoric.add(it) } } - listHistoric.sortWith { item1, item2 -> - val compareShipped = item1.shipped.compareTo(item2.shipped) - //comentar con ivanm - if (compareShipped == 0) { - if (item1.order == null && item2.order == null) { - item2.balance!!.compareTo(item1.balance!!) // Comparar por balance cuando ambos órdenes son nulos - } else if (item1.order == null) { - -1 - } else if (item2.order == null) { - 1 - } else { - item2.order!!.compareTo(item1.order!!) // Invertir el orden - } - } else { - compareShipped - } - } + /* listHistoric.sortWith { item1, item2 -> + + val date1 = item1.shipped.split(" ")[0] + val date2 = item2.shipped.split(" ")[0] + + val compareShipped = date1.compareTo(date2) + //comentar con ivanm + if (compareShipped == 0) { + if (item1.order == null && item2.order == null) { + item2.balance!!.compareTo(item1.balance!!) // Comparar por balance cuando ambos órdenes son nulos + } else if (item1.order == null) { + -1 + } else if (item2.order == null) { + 1 + } else { + item2.order!!.compareTo(item1.order!!) // Invertir el orden + } + } else { + compareShipped + } + }*/ adapter = HistoricoAdapter(listHistoric, object : OnClientHistoricItemClickListener { override fun onClientHistoricItemClickListener(item: ItemHistoricoVO) { @@ -320,13 +325,22 @@ class HistoricoArticuloFragment( private fun navigateToToday(it: ItemHistoricoListVO) { var positionToday = 0 - val sdf = SimpleDateFormat(getString(R.string.dateFormat), Locale.getDefault()) - val currentDate = sdf.format(Date()) + + val inputFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) + val outputFormat = SimpleDateFormat(getString(R.string.dateFormat), Locale.getDefault()) + val currentDate = outputFormat.format(Date()) for (item in it.list) { - if (currentDate == item.shipped) { - break + try { + val shippedDate = inputFormat.parse(item.shipped) + val formattedShippedDate = shippedDate?.let { date -> outputFormat.format(date) } + if (currentDate == formattedShippedDate) { + break + } + } catch (e: Exception) { + getString(R.string.errorOrderList).toast(requireContext()) } + positionToday += 1 } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/main/activity/MainActivity.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/main/activity/MainActivity.kt index 4289e0b5..fcf5b92b 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/main/activity/MainActivity.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/main/activity/MainActivity.kt @@ -56,7 +56,7 @@ import es.verdnatura.presentation.view.feature.articulo.fragment.ItemProposalFra import es.verdnatura.presentation.view.feature.boxPicking.BoxPickingFragment import es.verdnatura.presentation.view.feature.buffer.fragment.BufferFragment import es.verdnatura.presentation.view.feature.buffer.fragment.BufferLoadFragment -import es.verdnatura.presentation.view.feature.buscaritem.fragment.BuscarItemFragment +import es.verdnatura.presentation.view.feature.buscaritem.fragment.BuscarItemFragmentCompose import es.verdnatura.presentation.view.feature.category.ChangeCategoryFragment import es.verdnatura.presentation.view.feature.claim.fragment.reubication.fragment.ReubicationCollectionFragment import es.verdnatura.presentation.view.feature.claim.fragment.reubication.fragment.ReubicationFragment @@ -79,7 +79,7 @@ import es.verdnatura.presentation.view.feature.delivery.fragments.SalaryCompleme import es.verdnatura.presentation.view.feature.delivery.fragments.SummaryFragment import es.verdnatura.presentation.view.feature.delivery.fragments.TicketsFragment import es.verdnatura.presentation.view.feature.delivery.model.ClientTicketSalix -import es.verdnatura.presentation.view.feature.diadeventa.fragment.DayOfSaleFragment +import es.verdnatura.presentation.view.feature.diadeventa.fragment.DayOfSaleFragmentCompose import es.verdnatura.presentation.view.feature.historicoarticulo.fragment.HistoricoArticuloFragment import es.verdnatura.presentation.view.feature.historicoshelvinglog.fragment.ShelvingLogFragment import es.verdnatura.presentation.view.feature.historicoshelvinglog.model.LogType @@ -99,7 +99,7 @@ import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionPa import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionPalletFragment import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionPreparedStateFragment import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionScanFragment -import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionScanSorterFragment +import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionScanSorterFragmentCompose import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionStateFragment import es.verdnatura.presentation.view.feature.paletizador.fragment.ExpeditionTruckListFragment import es.verdnatura.presentation.view.feature.paletizador.fragment.PalletScanFragment @@ -133,7 +133,7 @@ import es.verdnatura.presentation.view.feature.ticket.fragment.TicketAdvanceFrag import es.verdnatura.presentation.view.feature.ubicador.fragment.AutomaticAddItemFragment import es.verdnatura.presentation.view.feature.ubicador.fragment.UbicadorFragment import es.verdnatura.presentation.view.feature.workermistake.fragment.PackingMistakeFragment -import es.verdnatura.presentation.view.feature.workermistake.fragment.WorkermistakeFragment +import es.verdnatura.presentation.view.feature.workermistake.fragment.WorkermistakeFragmentCompose import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -575,7 +575,8 @@ class MainActivity : BaseActivity(), OnPasillerosItemClickL } getString(R.string.titleScanExpedition) -> { - addFragmentOnTop(ExpeditionScanSorterFragment.newInstance(itemTitle)) + //addFragmentOnTop(ExpeditionScanSorterFragment.newInstance(itemTitle)) + addFragmentOnTop(ExpeditionScanSorterFragmentCompose.newInstance(itemTitle)) } getString(R.string.titleBufferManegement) -> { @@ -605,7 +606,8 @@ class MainActivity : BaseActivity(), OnPasillerosItemClickL } getString(R.string.titleDayOfSale) -> { - addFragmentOnTop(DayOfSaleFragment(itemTitle)) + //addFragmentOnTop(DayOfSaleFragment(itemTitle)) + addFragmentOnTop(DayOfSaleFragmentCompose(itemTitle)) } getString(R.string.titleShowTicket) -> { @@ -627,18 +629,8 @@ class MainActivity : BaseActivity(), OnPasillerosItemClickL getString(R.string.titleItemSearch) -> { //JETPACKCOMPOSE - /* addFragmentOnTop( - BuscarItemFragmentCompose.newInstance( - if (entryPoint == "") { - null - } else { - entryPoint.toInt() - } - ) - )*/ - addFragmentOnTop( - BuscarItemFragment.newInstance( + BuscarItemFragmentCompose.newInstance( if (entryPoint == "") { null } else { @@ -646,6 +638,16 @@ class MainActivity : BaseActivity(), OnPasillerosItemClickL } ) ) + + /* addFragmentOnTop( + BuscarItemFragment.newInstance( + if (entryPoint == "") { + null + } else { + entryPoint.toInt() + } + ) + )*/ } getString(R.string.titleHistorical) -> { @@ -757,7 +759,8 @@ class MainActivity : BaseActivity(), OnPasillerosItemClickL } getString(R.string.titleWorkerMistake) -> { - addFragmentOnTop(WorkermistakeFragment.newInstance(itemTitle)) + //addFragmentOnTop(WorkermistakeFragment.newInstance(itemTitle)) + addFragmentOnTop(WorkermistakeFragmentCompose.newInstance(itemTitle)) } getString(R.string.deleteExpedition) -> { diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/paletizador/fragment/ExpeditionScanSorterFragmentCompose.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/paletizador/fragment/ExpeditionScanSorterFragmentCompose.kt new file mode 100644 index 00000000..b4f9a141 --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/paletizador/fragment/ExpeditionScanSorterFragmentCompose.kt @@ -0,0 +1,82 @@ +package es.verdnatura.presentation.view.feature.paletizador.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.activity.OnBackPressedCallback +import androidx.activity.OnBackPressedDispatcher +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.platform.ComposeView +import androidx.fragment.app.Fragment +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import es.verdnatura.R +import es.verdnatura.presentation.common.OnBackPressedListener +import es.verdnatura.presentation.view.component.CustomDialogListComposable +import es.verdnatura.presentation.view.feature.main.activity.MainActivity +import org.koin.androidx.viewmodel.ext.android.viewModel + +class ExpeditionScanSorterFragmentCompose( + var title: String = "" +) : Fragment(), OnBackPressedListener { + private val viewModel: ExpeditionScanSorterViewModelCompose by viewModel() + private lateinit var backDispatcher: OnBackPressedDispatcher + + companion object { + fun newInstance(title: String) = ExpeditionScanSorterFragmentCompose(title) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View { + val composeView = ComposeView(requireContext()) + + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, + object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + (activity as? MainActivity)?.onMyBackPressed() + } + }) + + composeView.setContent { + SetComposableView() + } + + return composeView + } + + @Composable + private fun SetComposableView() { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + CustomDialogListComposable( + title = getString(R.string.expeditionNoSorter), + onOkClick = { (context as MainActivity).onMyBackPressed() }, + showRecyclerView = true, + buttonOkText = getString(R.string.end), + recyclerViewItems = uiState.items, + onEnterPressed = { text -> + if (text.isNotEmpty()) try { + viewModel.expeditionScan(text.toLong()) + } catch (ex: Exception) { + (context as MainActivity).messageWithSound( + message = getString(R.string.errorInput), + isPlayed = true, + isToasted = true, + isError = true + ) + } + } + + ) + } + + override fun onBackPressedHandled(): Boolean { + return true + } + + override fun onDestroyView() { + super.onDestroyView() + (activity as? MainActivity)?.onMyBackPressed() + } +} diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/paletizador/fragment/ExpeditionScanSorterViewModelCompose.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/paletizador/fragment/ExpeditionScanSorterViewModelCompose.kt new file mode 100644 index 00000000..32a7176a --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/paletizador/fragment/ExpeditionScanSorterViewModelCompose.kt @@ -0,0 +1,44 @@ +package es.verdnatura.presentation.view.feature.paletizador.fragment + +import es.verdnatura.domain.SalixCallback +import es.verdnatura.presentation.base.BaseViewModelCompose +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import retrofit2.Response + +data class UiState( + var items: MutableList = mutableListOf(), + val isLoading: Boolean = false +) + +class ExpeditionScanSorterViewModelCompose(var application: android.app.Application) : + BaseViewModelCompose(application) { + + private val _uiState = MutableStateFlow(UiState()) + val uiState = _uiState.asStateFlow() + + fun expeditionScan(vExpeditionId: Number) { + salix.expeditionScan(params = arrayListOf(vExpeditionId)) + .enqueue(object : SalixCallback(application.applicationContext) { + override fun onSuccess(response: Response) { + super.onSuccess(response) + + _uiState.update { currentState -> + currentState.copy( + items = currentState.items.toMutableList().apply { add(vExpeditionId) }, + isLoading = false + ) + } + + } + + override fun onError(t: Throwable) { + super.onError(t) + _uiState.update { it.copy(isLoading = false) } + } + + }) + } + +} \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/pasillero/fragment/PasilleroViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/pasillero/fragment/PasilleroViewModel.kt index 98ef724b..102fe886 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/pasillero/fragment/PasilleroViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/pasillero/fragment/PasilleroViewModel.kt @@ -289,13 +289,13 @@ class PasilleroViewModel(context: Context) : BaseViewModel(context) { ) ) - //a quitar - _pasillerositem.add( - PasillerosItemVO( - R.drawable.ic_picker_ui, R.string.titlePickers, R.string.titlePickersDescrip + //solo para hacer pruebas en los dos sistemas + /* _pasillerositem.add( + PasillerosItemVO( + R.drawable.ic_picker_ui, R.string.titlePickers, R.string.titlePickersDescrip - ) - ) + ) + )*/ } else { _pasillerositem.add( @@ -574,14 +574,6 @@ class PasilleroViewModel(context: Context) : BaseViewModel(context) { ) ) - _pasillerositem.add( - PasillerosItemVO( - R.drawable.car_info, - R.string.titleHistoricalVehicle, - R.string.titleHistVehicleDescrip - ) - ) - } fun workerActivityAdd( diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/pasillero/model/PasillerosItemVO.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/pasillero/model/PasillerosItemVO.kt index 3cab305f..32ea0440 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/pasillero/model/PasillerosItemVO.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/pasillero/model/PasillerosItemVO.kt @@ -7,10 +7,18 @@ class PasillerosItemVO( ) data class WorkerActionSalix( - val code: String, val model: String = ConstAndValues.MODELWORKERTYPEACTIVITY + val code: String, + val model: String = ConstAndValues.MODELWORKERTYPEACTIVITY, + val description: String = "" ) enum class CodeWorkerAction { - CLAIM, DELIVERY, ON_CHECKING, ON_PREPARATION, PREVIOUS, PALLETIZING, STOP, STORAGE + CLAIM, DELIVERY, ON_CHECKING, ON_PREPARATION, PREVIOUS, PALLETIZING, STOP, STORAGE, SHELVING_CLEAN_START, SHELVING_CLEAN_STOP -} \ No newline at end of file +} + +data class CleanAction( + val codeWorkerAction: CodeWorkerAction, + val shelving: String, + val description: String +) \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/presacador/mapper/SaleMapper.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/presacador/mapper/SaleMapper.kt index 38b0ac82..80919b5d 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/presacador/mapper/SaleMapper.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/presacador/mapper/SaleMapper.kt @@ -3,14 +3,14 @@ package es.verdnatura.presentation.view.feature.presacador.mapper import es.verdnatura.presentation.view.feature.presacador.model.PreSacadorItemVO import es.verdnatura.presentation.view.feature.sacador.model.SaleVO -fun PreSacadorItemVO.toSale() : SaleVO { +fun PreSacadorItemVO.toSale(): SaleVO { return SaleVO( ticketFk = id, level = "1", saleFk = idMovimiento, itemFk = itemFk, quantity = saldo, - longName = if (longName != null) longName else "", + longName = if (longName != null) longName else "", isPreviousPrepared = if (quantity == picked) "1" else "0", line1 = longName, line2 = if (subName.isNullOrEmpty()) "" else subName,//sergio:cuando subida versión de tarea #3510 se puede quitar isNullOrEmpty @@ -19,32 +19,29 @@ fun PreSacadorItemVO.toSale() : SaleVO { originalQuantity = quantity, placements = carros, agencyName = trabajador.toString(), - packingType=packingType, - salePersonFk=if (salesPersonFk.isNullOrEmpty()){""}else salesPersonFk, - rgb= null - + packingType = packingType, + rgb = null ) } - -fun PreSacadorItemVO.toSaleReposicion() : SaleVO { +fun PreSacadorItemVO.toSaleReposicion(): SaleVO { return SaleVO( ticketFk = id, level = "1", saleFk = idMovimiento, itemFk = itemFk, quantity = quantity, - longName = if (longName != null) longName else "", + longName = if (longName != null) longName else "", isPreviousPrepared = if ((quantity - saldo) == 0) "1" else "0", line1 = longName, line2 = if (subName.isNullOrEmpty()) "" else subName, pickedQuantity = (quantity - saldo), - workerFk =trabajador, + workerFk = trabajador, originalQuantity = quantity, placements = carros, agencyName = trabajador.toString(), - rgb=null + rgb = null ) } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/presacador/model/PreSacadorItemVO.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/presacador/model/PreSacadorItemVO.kt index 1622b848..d3b69a9b 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/presacador/model/PreSacadorItemVO.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/presacador/model/PreSacadorItemVO.kt @@ -4,7 +4,7 @@ import es.verdnatura.presentation.view.feature.sacador.model.PlacementVO class PreSacadorItemVO( var id: String = "", - var itemFk: Int , + var itemFk: Int, var packingType: String? = "",//sergio:cuando subida versión de tarea #3510 se puede quitar incialización var longName: String = "", var subName: String? = "",//sergio:cuando subida versión de tarea #3510 se puede quitar incialización @@ -17,8 +17,7 @@ class PreSacadorItemVO( var carros: List = listOf(), //var priority:Int =0, 7-1-2022 var pickingOrder: Int = 0, - var salesPersonFk: String = "", - var rgb:String?=null, + var rgb: String? = null, var reference: String = "" ) diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/sacador/fragment/SacadorViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/sacador/fragment/SacadorViewModel.kt index 4261f76f..5169add2 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/sacador/fragment/SacadorViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/sacador/fragment/SacadorViewModel.kt @@ -160,40 +160,40 @@ class SacadorViewModel(val context: Context) : BaseViewModel(context) { }) } - fun itemShelvingSale_addByCollection(collection: Int) { - salix.itemShelvingSaleAddByCollection(collection).enqueue( - object : - SalixCallback(context) { - override fun onError(t: Throwable) { - _response.value = - ResponseItemVO( - isError = true, - errorMessage = getMessageFromAllResponse( - nameofFunction(this), - t.message!! - ) - ) - } + /* fun itemShelvingSale_addByCollection(collection: Int) { + salix.itemShelvingSaleAddByCollection(collection).enqueue( + object : + SalixCallback(context) { + override fun onError(t: Throwable) { + _response.value = + ResponseItemVO( + isError = true, + errorMessage = getMessageFromAllResponse( + nameofFunction(this), + t.message!! + ) + ) + } - override fun onSuccess(response: Response) { - if (response.body() != null) { + override fun onSuccess(response: Response) { + if (response.body() != null) { - _response.value = - ResponseItemVO(isError = false, response = collection.toString()) - } else { + _response.value = + ResponseItemVO(isError = false, response = collection.toString()) + } else { - _response.value = ResponseItemVO( - isError = true, - errorMessage = getMessageFromAllResponse( - nameofFunction(this), - response.message() - ) - ) + _response.value = ResponseItemVO( + isError = true, + errorMessage = getMessageFromAllResponse( + nameofFunction(this), + response.message() + ) + ) - } - } - }) - } + } + } + }) + }*/ fun collectionGet() { salix.getCollectionSalix().enqueue(object : diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/sacador/model/TicketItemVO.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/sacador/model/TicketItemVO.kt index f35864cd..4b5a78f9 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/sacador/model/TicketItemVO.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/sacador/model/TicketItemVO.kt @@ -15,6 +15,7 @@ class CollectionTicket( var tickets: MutableList = mutableListOf(), var isError: Boolean = false, var errorMessage: String = "", + val sectorFk: Int? = null ) data class Ticket( @@ -22,7 +23,6 @@ data class Ticket( var level: String?, var rgb: String?, val agencyName: String, - val salesPersonFk: Int, val observations: String?, val warehouseFk: Int, val sales: MutableList = mutableListOf() @@ -36,7 +36,7 @@ data class Sale( val saleFk: Int, val itemFk: Int, val longName: String, - val size: Int, + val size: Int? = null, var semaphore: String?, var color: String = "", val productor: String? = "", @@ -71,7 +71,8 @@ data class Sale( var currentItemShelving: Int = 0, var stateCode: String? = "", var ticketOrder: Int? = null, - val username: String? = null + val username: String? = null, + val sectorFk: Int? = null ) @@ -113,7 +114,6 @@ class TicketSalix( var level: String? = "", var rgb: String?, var agencyName: String = "", - var salesPersonFk: String = "", var sales: List = listOf(), @SerializedName( value = "observations", @@ -171,7 +171,8 @@ class SaleVO( var sectorFk: Int? = null, var packingChecked: Int = 1, var isAdvanced: Int? = 0, - var parkingCode: String? = "" + var parkingCode: String? = "", + var pickedOrder: String? = null ) @@ -180,7 +181,6 @@ class TicketVO( var level: String? = "", var rgb: String?, var agencyName: String = "", - var salesPersonFk: String = "", var sales: List = listOf(), @SerializedName( value = "observations", diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/ticket/fragment/TicketAdvanceFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/ticket/fragment/TicketAdvanceFragment.kt index 4e0b21a6..68b31caa 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/ticket/fragment/TicketAdvanceFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/ticket/fragment/TicketAdvanceFragment.kt @@ -40,14 +40,14 @@ class TicketAdvanceFragment(var title: String) : if (!binding.scanInput.text.isNullOrEmpty()) { try { - viewModel.ticketAdvancePackaging( + viewModel.ticketExits( itemScanValue( binding.scanInput.text.toString(), arrayOf("ticket"), "id" ).toString().toInt(), mobileApplication.userId!! ) } catch (ex: Exception) { - getString(R.string.ticketFormatError) + getString(R.string.ticketScanError) } } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/ticket/fragment/TicketViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/ticket/fragment/TicketViewModel.kt index efe96330..dbbc37cb 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/ticket/fragment/TicketViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/ticket/fragment/TicketViewModel.kt @@ -1,18 +1,39 @@ package es.verdnatura.presentation.view.feature.ticket.fragment import android.content.Context +import com.google.gson.JsonObject +import es.verdnatura.R import es.verdnatura.domain.SalixCallback import es.verdnatura.presentation.base.BaseViewModel import es.verdnatura.presentation.common.PackingSiteSalix +import retrofit2.Response class TicketViewModel(val context: Context) : BaseViewModel(context) { fun ticketAdvancePackaging( - ticketFk: Int, workerFk: Int + ticketFk: Number, workerFk: Number ) { salix.ticketAdvancePackaging(PackingSiteSalix(ticketFk, workerFk)) .enqueue(object : SalixCallback(context) {}) } + fun ticketExits( + ticketFk: Number, + workerFk: Number + + ) { + salix.ticketExists(id = ticketFk) + .enqueue(object : SalixCallback(context) { + override fun onSuccess(response: Response) { + + if (response.body()!!.entrySet().first().value.asBoolean) { + ticketAdvancePackaging(ticketFk, workerFk) + } else { + defaultErrorHandler(Throwable(message = context.getString(R.string.ticketScanError))) + } + } + }) + } + } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/AutomaticAddItemFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/AutomaticAddItemFragment.kt index 5f4ffa1a..cb4a9229 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/AutomaticAddItemFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/AutomaticAddItemFragment.kt @@ -161,15 +161,14 @@ class AutomaticAddItemFragment( customDialogList.setDescription( getString(R.string.scanShelvingsLocate) ).setOkButton(getString(R.string.locate)) { - listItems.clear() listShelvings.forEach { viewModel.itemShelvingMakeMulti( it.code!!, ArrayList(listItems), mobileApplication.dataStoreApp.readDataStoreKey(WAREHOUSEFK) ) - } + listItems.clear() customDialogList.dismiss() }.setKoButton(getString(R.string.cancel)) { diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/UbicadorFragment.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/UbicadorFragment.kt index 6a356cb2..772e7b25 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/UbicadorFragment.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/UbicadorFragment.kt @@ -37,6 +37,7 @@ import es.verdnatura.presentation.common.OnVisibleClickListener6869 import es.verdnatura.presentation.common.PrinterDialogManager import es.verdnatura.presentation.common.ToolBarAdapterTooltip import es.verdnatura.presentation.common.hideKeyboard +import es.verdnatura.presentation.common.itemScanIsQr import es.verdnatura.presentation.common.itemScanValue import es.verdnatura.presentation.view.component.CustomDialog import es.verdnatura.presentation.view.component.CustomDialogInput @@ -650,8 +651,11 @@ class UbicadorFragment : BaseFragment item.itemCreated!!.contains("old", ignoreCase = true) + }.distinctBy { item -> + "${item.itemFk}:${item.code}:${item.parkingFk}" }.map { item -> val itemFk = item.itemFk val shelvingFk = item.code @@ -663,10 +667,12 @@ class UbicadorFragment : BaseFragment item.itemCreated!!.contains("new", ignoreCase = true) + }.distinctBy { item -> + "${item.itemFk}:${item.code}:${item.parkingFk}" }.map { item -> val itemFk = item.itemFk val shelvingFk = item.code @@ -678,7 +684,7 @@ class UbicadorFragment : BaseFragment + item.item.id, + item.description ?: "", + onPrintClick = { id, labelType, packing, copies -> - if (item.buyFk == null) { - viewModel.buyUltimate( - itemFk = item.id, - warehouseFk = mobileApplication.dataStoreApp.readDataStoreKey( - WAREHOUSEFK - ), - dated = LocalDate.now().format( - DateTimeFormatter.ofPattern("yyyy-dd-MM") - ), - reportName = "LabelBuy", - printerFk = mobileApplication.dataStoreApp.readDataStoreKey( - ConstAndValues.PRINTERFK - ), - userFk = mobileApplication.userId!!, - priority = "normal", - copies = copies, - labelType = labelType, - packing = packing - ) - customDialogTwoButtons.dismiss() - } else { - printItem( - item.buyFk, labelType, packing, copies - ) - customDialogTwoButtons.dismiss() - } - } + if (item.buyFk == null) { + viewModel.buyUltimate( + itemFk = item.id, + warehouseFk = mobileApplication.dataStoreApp.readDataStoreKey( + WAREHOUSEFK + ), + dated = LocalDate.now().format( + DateTimeFormatter.ofPattern("yyyy-dd-MM") + ), + reportName = "LabelBuy", + printerFk = mobileApplication.dataStoreApp.readDataStoreKey( + ConstAndValues.PRINTERFK + ), + userFk = mobileApplication.userId!!, + priority = "normal", + copies = copies, + labelType = labelType, + packing = packing + ) + customDialogTwoButtons.dismiss() + } else { + printItem( + item.buyFk, labelType, packing, copies + ) + customDialogTwoButtons.dismiss() + } + }, + onPrintChange = { text -> + if (itemScanIsQr(text)) { + viewModel.operatorUpdate( + workerFk = mobileApplication.userId!!, + labelerFK = itemScanValue( + text, + arrayOf("printer"), + "id" + ).toString().toLong() + ) + } else { + ma.messageWithSound( + getString(R.string.qrPrinterNotvalid), + isPlayed = true, + isError = true, + isToasted = false + ) + } + + }) customDialogInput.getEditText().requestFocus() } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/UbicadorViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/UbicadorViewModel.kt index 43daa242..5af862fe 100644 --- a/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/UbicadorViewModel.kt +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/ubicador/fragment/UbicadorViewModel.kt @@ -12,6 +12,7 @@ import es.verdnatura.domain.formatWithQuotes import es.verdnatura.domain.userCases.GetItemFromBarcodeUseCase import es.verdnatura.domain.userCases.GetItemPrintItemUseCase import es.verdnatura.domain.userCases.NotiticationUseCase +import es.verdnatura.domain.userCases.OperatorUseCase import es.verdnatura.presentation.base.BaseViewModel import es.verdnatura.presentation.common.Action import es.verdnatura.presentation.common.Event @@ -39,6 +40,7 @@ class UbicadorViewModel(val context: Context) : BaseViewModel(context) { private val getItemFromBarcodeUseCase = GetItemFromBarcodeUseCase(salix) private val printItemUseCase = GetItemPrintItemUseCase(salix) private val notificationUseCase = NotiticationUseCase(salix) + private val operatorUseCase = OperatorUseCase(salix) private val _responseUbicator by lazy { MutableLiveData() } val responseUbicator: LiveData @@ -185,16 +187,26 @@ class UbicadorViewModel(val context: Context) : BaseViewModel(context) { warehouse: Int, grouping: Int?, ) { + + //tarea 8268 salix.itemShelvingAdd( arrayListOf( shelving, item, quantity, - null, - grouping, packing, warehouse, ).formatWithQuotes() + /* salix.itemShelvingAdd( + arrayListOf( + shelving, + item, + quantity, + null, + grouping, + packing, + warehouse, + ).formatWithQuotes()*/ ).enqueue(object : SalixCallback(context) { override fun onResponse(call: Call, response: Response) { @@ -711,4 +723,11 @@ class UbicadorViewModel(val context: Context) : BaseViewModel(context) { } + fun operatorUpdate(workerFk: Number, labelerFK: Number) { + + operatorUseCase.updateOperator(workerFk = workerFk, hashMapOf("labelerFk" to labelerFK)) + .enqueue(object : SalixCallback(context) { + + }) + } } diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkerMistakeScreen.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkerMistakeScreen.kt new file mode 100644 index 00000000..4a012a53 --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkerMistakeScreen.kt @@ -0,0 +1,450 @@ +package es.verdnatura.presentation.view.feature.workermistake.fragment + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Search +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.IconButtonDefaults +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.VerticalDivider +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Dialog +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import es.verdnatura.R +import es.verdnatura.presentation.composable.CustomToolbar +import es.verdnatura.presentation.composable.ui.VerdnaturaColors +import es.verdnatura.presentation.view.component.CustomDialogListComposable +import es.verdnatura.presentation.view.feature.workermistake.model.DepartmentMistake +import es.verdnatura.presentation.view.feature.workermistake.model.WorkerFromMistake + +@Composable +fun WorkerMistakeScreen( + viewModel: WorkerMistakeViewModel? = null, + title: String, + onBackClick: () -> Unit = {}, + + ) { + val uiStateWorker by viewModel!!.uiStateWorkerDeparment.collectAsStateWithLifecycle() + var filterText by remember { mutableStateOf("") } + var showSearchableList by remember { mutableStateOf(false) } + + Box(modifier = Modifier.fillMaxSize()) { + + CustomToolbar( + title = title, + subtitle = "", + showBackButton = true, + showSwitch = false, + iconList = listOf(), + onBackClick = { onBackClick() }, + onSwitchChange = { }, + ) + Spacer(modifier = Modifier.height(8.dp)) + + Column( + modifier = Modifier + .fillMaxSize() + .padding(top = 56.dp) + ) { + Box { + HorizontalDivider( + color = Color.White, thickness = 1.dp + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + .height(56.dp), + verticalAlignment = Alignment.CenterVertically + ) { + + TextField( + value = filterText, + onValueChange = { filterText = it }, + modifier = Modifier.weight(1f), + placeholder = { + Text( + text = stringResource(R.string.nameSurname), + textAlign = TextAlign.Center, + color = VerdnaturaColors.BlackTextInput, + ) + }, + colors = TextFieldDefaults.colors( + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + focusedTextColor = VerdnaturaColors.White, + unfocusedTextColor = VerdnaturaColors.BlackTextInput, + cursorColor = Color.White, + focusedIndicatorColor = Color.DarkGray + ), + singleLine = true, + textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center) + ) + VerticalDivider(thickness = 4.dp, color = Color.Transparent) + Box(modifier = Modifier.weight(1f)) { + + TextField( + value = uiStateWorker.departmentSelected.name.ifEmpty { + stringResource(R.string.buscarDepartamento) + }, + onValueChange = { }, + modifier = Modifier + .fillMaxWidth() + .clickable { showSearchableList = true }, + + trailingIcon = { + Icon(painter = painterResource(id = R.drawable.ic_arrow_drop_down_black_24dp), + contentDescription = "Dropdown", + modifier = Modifier.clickable { + showSearchableList = true + viewModel!!.departmentGetHasMistake() + }) + }, + colors = TextFieldDefaults.colors( + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + focusedTextColor = VerdnaturaColors.OrangeSalix, + unfocusedTextColor = VerdnaturaColors.OrangeSalix, + focusedIndicatorColor = Color.DarkGray + ), + readOnly = true, + singleLine = true, + textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center) + ) + } + } + + Row( + modifier = Modifier + .fillMaxWidth() + .padding( + start = 8.dp, end = 8.dp, top = 8.dp, bottom = 16.dp + ), horizontalArrangement = Arrangement.SpaceEvenly + ) { + Text( + text = stringResource(id = R.string.name), + modifier = Modifier.weight(1.25f), + textAlign = TextAlign.Start, + color = Color.White, + fontSize = 14.sp + ) + + Text( + text = stringResource(id = R.string.surname), + modifier = Modifier.weight(1f), + textAlign = TextAlign.Center, + color = Color.White, + fontSize = 14.sp + ) + + Text( + text = "", + modifier = Modifier.weight(0.5f), + textAlign = TextAlign.Center, + color = Color.White, + fontSize = 14.sp + ) + } + HorizontalDivider(thickness = 1.dp, color = Color.LightGray) + + LazyColumn { + items(uiStateWorker.workers.filter { + it.firstName.contains( + filterText, + ignoreCase = true + ) || it.lastName.contains(filterText, ignoreCase = true) + }) { workerItem -> + WorkerMistakeItem(workerItem) { viewModel!!.setWorkerSelected(workerItem) } + HorizontalDivider(thickness = 1.dp, color = Color.DarkGray) + } + } + + } + + if (uiStateWorker.workerSelected.id != null) { + CustomDialogListComposable( + title = uiStateWorker.workerSelected.firstName, + buttonOkText = "Cancelar", + description = "Causa del error:", + showRecyclerView = true, + recyclerViewItems = uiStateWorker.mistakeTypes.map { it.description }, + onItemSelected = { item -> + println("Item selected: $item") + uiStateWorker.mistakeTypes.find { it.description == item }?.let { + viewModel!!.workerMistakeAdd(uiStateWorker.workerSelected.id!!, it.code) + } + }, + showTextInput = false, + onOkClick = { viewModel!!.setWorkerSelected(WorkerFromMistake()) } + ) + } + + if (showSearchableList) { + SearchableDepartmentsList(modifier = Modifier + .fillMaxWidth() + .align(Alignment.TopStart), + onDepartmentSelected = { department -> + viewModel!!.setDepartment(departmentSelected = department) + showSearchableList = false + }, + departmentList = uiStateWorker.departments, + onDismiss = { showSearchableList = false }) + } + + } +} + +@Composable +fun WorkerMistakeItem(workerItem: WorkerFromMistake, clickIcon: () -> Unit) { + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = workerItem.firstName, + modifier = Modifier.weight(1.25f), + textAlign = TextAlign.Start, + color = VerdnaturaColors.OrangeSalix + ) + Text( + text = workerItem.lastName, + modifier = Modifier.weight(1f), + textAlign = TextAlign.Start, + color = VerdnaturaColors.OrangeSalix + ) + IconButton( + onClick = { clickIcon() }, + modifier = Modifier.weight(0.5f), + colors = IconButtonDefaults.iconButtonColors( + containerColor = Color.Black, contentColor = VerdnaturaColors.OrangeSalix + ) + ) { + Icon( + painter = painterResource(id = R.drawable.emoticon_error), + contentDescription = "Action", + ) + } + } +} + +@Composable +fun SearchableDepartmentsList( + modifier: Modifier = Modifier, + departmentList: List, + onDepartmentSelected: (DepartmentMistake) -> Unit, + onDismiss: () -> Unit +) { + var searchQuery by remember { mutableStateOf("") } + val filteredDepartments = remember(searchQuery, departmentList) { + if (searchQuery.isEmpty()) { + departmentList + } else { + departmentList.filter { + it.name.contains(searchQuery, ignoreCase = true) || it.name.contains( + searchQuery, + ignoreCase = true + ) + } + } + } + + Dialog(onDismissRequest = onDismiss) { + Surface( + modifier = modifier + .fillMaxWidth() + .fillMaxHeight(), + shape = RoundedCornerShape(8.dp), + color = MaterialTheme.colorScheme.surface, + shadowElevation = 8.dp + ) { + Column( + modifier = Modifier.padding(16.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + + IconButton(onClick = onDismiss) { + Icon( + imageVector = Icons.Default.Close, contentDescription = "Cerrar" + ) + } + } + + Spacer(modifier = Modifier.height(8.dp)) + + OutlinedTextField( + value = searchQuery, + onValueChange = { searchQuery = it }, + modifier = Modifier.fillMaxWidth(), + placeholder = { Text("Buscar departamento") }, + leadingIcon = { + Icon( + imageVector = Icons.Default.Search, contentDescription = "Buscar" + ) + }, + singleLine = true + ) + + Spacer(modifier = Modifier.height(16.dp)) + + // Lista de departamentos + if (filteredDepartments.isEmpty()) { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + contentAlignment = Alignment.Center + ) { + Text( + text = "No se encontraron departamentos", + textAlign = TextAlign.Center, + color = Color.Gray + ) + } + } else { + LazyColumn { + items(filteredDepartments) { department -> + DepartmentItem(department = department, onSelected = { + onDepartmentSelected(department) + }) + } + } + } + } + } + } +} + +@Composable +private fun DepartmentItem( + department: DepartmentMistake, onSelected: () -> Unit +) { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp) + .clickable(onClick = onSelected), + elevation = CardDefaults.cardElevation( + defaultElevation = 2.dp + ) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + Text( + text = department.name, + style = MaterialTheme.typography.bodyLarge, + color = VerdnaturaColors.BlackCustomDialog + ) + + } + } +} + +// Clase de modelo para los elementos de la lista +data class WorkerItem( + val name: String, val surname: String + // Otros campos necesarios +) + +// Añade esta función preview debajo de tu WorkerMistakeScreen +@Preview( + showBackground = true, + backgroundColor = 0xFF2E7D32, // Color de fondo verde oscuro similar a verdnatura + widthDp = 360, + heightDp = 640 +) +@Composable +fun WorkerMistakeScreenPreview() { + MaterialTheme { + Surface(color = Color(0xFF2E7D32)) { // Fondo verde verdnatura + WorkerMistakeScreen( + viewModel = null, "Error" + ) + } + } +} + +// Preview para el item individual +@Preview(showBackground = true) +@Composable +fun WorkerMistakeItemPreview() { + MaterialTheme { + Surface(color = Color(0xFF2E7D32)) { + WorkerMistakeItem( + WorkerFromMistake( + firstName = "Juan", lastName = "García" + ), + clickIcon = { }, + ) + } + } +} + +// Si quieres probar con diferentes datos, puedes usar un PreviewParameterProvider +class SampleWorkerItemProvider : PreviewParameterProvider { + override val values = sequenceOf( + WorkerItem("Ana", "Martínez"), + WorkerItem("Carlos", "López"), + WorkerItem("María", "Rodríguez") + ) +} + +@Preview(showBackground = true) +@Composable +fun WorkerMistakeItemWithParametersPreview( + @PreviewParameter(SampleWorkerItemProvider::class) workerItem: WorkerFromMistake +) { + MaterialTheme { + Surface(color = Color(0xFF2E7D32)) { + WorkerMistakeItem(workerItem, clickIcon = { }) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkerMistakeViewModel.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkerMistakeViewModel.kt new file mode 100644 index 00000000..44f92427 --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkerMistakeViewModel.kt @@ -0,0 +1,151 @@ +package es.verdnatura.presentation.view.feature.workermistake.fragment + +import androidx.lifecycle.viewModelScope +import es.verdnatura.MobileApplication +import es.verdnatura.domain.SalixCallback +import es.verdnatura.presentation.base.BaseViewModelCompose +import es.verdnatura.presentation.view.feature.workermistake.model.DepartmentMistake +import es.verdnatura.presentation.view.feature.workermistake.model.MistakeType +import es.verdnatura.presentation.view.feature.workermistake.model.WorkerFromMistake +import es.verdnatura.presentation.view.feature.workermistake.model.WorkerMistakeSalix +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import retrofit2.Response + +data class UiStateWorkerDeparment( + val departments: List = emptyList(), + val workers: List = emptyList(), + val departmentSelected: DepartmentMistake = DepartmentMistake(-1, ""), + val mistakeTypes: List = emptyList(), + val workerSelected: WorkerFromMistake = WorkerFromMistake(), + val isLoading: Boolean = false +) + +class WorkerMistakeViewModel(var application: android.app.Application) : + BaseViewModelCompose(application) { + + private val _uiStateWorkerDeparment = MutableStateFlow(UiStateWorkerDeparment()) + val uiStateWorkerDeparment = _uiStateWorkerDeparment.asStateFlow() + + init { + viewModelScope.launch { + val departmendId = + (application as MobileApplication).dataStoreApp.readDataStoreKey("DEPARTMENTMISTAKEID") + val departmentName = + (application as MobileApplication).dataStoreApp.readDataStoreKey("DEPARTMENTMISTAKE") + + if (departmendId != -1) { + _uiStateWorkerDeparment.update { + it.copy( + departmentSelected = DepartmentMistake(departmendId, departmentName) + ) + } + workerGetFromHasMistake(departmendId) + } else { + viewModelScope.launch { departmentGetHasMistake() } + } + } + } + + fun setDepartment(departmentSelected: DepartmentMistake) { + viewModelScope.launch { + (application as MobileApplication).dataStoreApp.editDataStoreKey( + "DEPARTMENTMISTAKE", + departmentSelected.name + ) + (application as MobileApplication).dataStoreApp.editDataStoreKey( + "DEPARTMENTMISTAKEID", + departmentSelected.id + ) + _uiStateWorkerDeparment.update { + it.copy( + departmentSelected = departmentSelected + ) + } + workerGetFromHasMistake(departmentSelected.id) + } + + } + + fun setWorkerSelected(woker: WorkerFromMistake) { + viewModelScope.launch { + _uiStateWorkerDeparment.update { + it.copy( + workerSelected = woker + ) + } + workerMistakeTypeGet() + } + } + + fun departmentGetHasMistake() { + salix.departmentGetHasMistake().enqueue(object : + SalixCallback>(application.applicationContext) { + override fun onSuccess(response: Response>) { + + response.body()?.let { list -> + _uiStateWorkerDeparment.update { + it.copy( + departments = list, isLoading = false + ) + } + } + } + + }) + } + + private fun workerGetFromHasMistake(departmentFk: Number) { + salix.workerGetFromHasMistake(arrayListOf(departmentFk)).enqueue(object : + SalixCallback>(application.applicationContext) { + override fun onSuccess(response: Response>) { + response.body()?.let { list -> + _uiStateWorkerDeparment.update { + it.copy( + workers = list, isLoading = false + ) + } + } + } + + }) + } + + private fun workerMistakeTypeGet() { + salix.workerMistakesTypes() + .enqueue(object : SalixCallback>(application.applicationContext) { + + override fun onSuccess(response: Response>) { + response.body()?.let { list -> + _uiStateWorkerDeparment.update { + it.copy( + mistakeTypes = list, isLoading = false + ) + } + } + + } + + }) + } + + fun workerMistakeAdd( + workerFk: Int, typeFk: String + ) { + salix.workerMistakesAdd(WorkerMistakeSalix(workerFk, typeFk)) + .enqueue(object : SalixCallback(application.applicationContext) { + override fun onSuccess(response: Response) { + super.onSuccess(response) + setWorkerSelected(WorkerFromMistake()) + } + + override fun onError(t: Throwable) { + super.onError(t) + setWorkerSelected(WorkerFromMistake()) + } + }) + } + +} diff --git a/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkermistakeFragmentCompose.kt b/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkermistakeFragmentCompose.kt new file mode 100644 index 00000000..c1727a28 --- /dev/null +++ b/app/src/main/java/es/verdnatura/presentation/view/feature/workermistake/fragment/WorkermistakeFragmentCompose.kt @@ -0,0 +1,42 @@ +package es.verdnatura.presentation.view.feature.workermistake.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.ui.platform.ComposeView +import androidx.fragment.app.Fragment +import es.verdnatura.presentation.view.feature.main.activity.MainActivity +import org.koin.androidx.viewmodel.ext.android.viewModel + +class WorkermistakeFragmentCompose( + var entryPoint: String = "" + +) : Fragment() { + private val viewModel: WorkerMistakeViewModel by viewModel() + + companion object { + fun newInstance(entryPoint: String) = WorkermistakeFragmentCompose(entryPoint) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View { + return ComposeView(requireContext()).apply { + setContent { + WorkerMistakeScreen( + viewModel = viewModel, + title = entryPoint, + onBackClick = { (context as MainActivity).onMyBackPressed() } + ) + } + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + (context as MainActivity).hideBottomNavigation(View.GONE) + } + +} + diff --git a/app/src/main/res/drawable/ic_booking.xml b/app/src/main/res/drawable/ic_booking.xml new file mode 100644 index 00000000..acd75bd4 --- /dev/null +++ b/app/src/main/res/drawable/ic_booking.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_clean_shelving.xml b/app/src/main/res/drawable/ic_clean_shelving.xml new file mode 100644 index 00000000..06136184 --- /dev/null +++ b/app/src/main/res/drawable/ic_clean_shelving.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_click.xml b/app/src/main/res/drawable/ic_click.xml deleted file mode 100644 index d8388b22..00000000 --- a/app/src/main/res/drawable/ic_click.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_click_black.xml b/app/src/main/res/drawable/ic_click_black.xml deleted file mode 100644 index 69a6cf0f..00000000 --- a/app/src/main/res/drawable/ic_click_black.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/app/src/main/res/layout/component_custom_list_dialog.xml b/app/src/main/res/layout/component_custom_list_dialog.xml index f532c281..ab6748e1 100644 --- a/app/src/main/res/layout/component_custom_list_dialog.xml +++ b/app/src/main/res/layout/component_custom_list_dialog.xml @@ -131,6 +131,15 @@ tools:text="@string/delete" tools:visibility="visible" /> +