Merge branch 'feature/RefactoringGestioneColli' into master-beta
This commit is contained in:
@@ -10,8 +10,8 @@ apply plugin: 'com.google.gms.google-services'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
||||||
def appVersionCode = 502
|
def appVersionCode = 504
|
||||||
def appVersionName = '1.46.14'
|
def appVersionName = '1.46.16'
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release {
|
release {
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ import it.integry.integrywmsnative.gest.spedizione.dialogs.row_info.prod_fabbiso
|
|||||||
import it.integry.integrywmsnative.gest.spedizione.dialogs.row_info.prod_fabbisogno_linee_prod.DialogRowInfoProdFabbisognoLineeProdModule;
|
import it.integry.integrywmsnative.gest.spedizione.dialogs.row_info.prod_fabbisogno_linee_prod.DialogRowInfoProdFabbisognoLineeProdModule;
|
||||||
import it.integry.integrywmsnative.gest.ultime_consegne_cliente.UltimeConsegneClienteComponent;
|
import it.integry.integrywmsnative.gest.ultime_consegne_cliente.UltimeConsegneClienteComponent;
|
||||||
import it.integry.integrywmsnative.gest.ultime_consegne_cliente.UltimeConsegneClienteModule;
|
import it.integry.integrywmsnative.gest.ultime_consegne_cliente.UltimeConsegneClienteModule;
|
||||||
|
import it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog.DialogUltimeConsegneFiltroAvanzatoComponent;
|
||||||
|
import it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog.DialogUltimeConsegneFiltroAvanzatoModule;
|
||||||
import it.integry.integrywmsnative.gest.ultimi_arrivi_fornitore.UltimiArriviFornitoreComponent;
|
import it.integry.integrywmsnative.gest.ultimi_arrivi_fornitore.UltimiArriviFornitoreComponent;
|
||||||
import it.integry.integrywmsnative.gest.ultimi_arrivi_fornitore.UltimiArriviFornitoreModule;
|
import it.integry.integrywmsnative.gest.ultimi_arrivi_fornitore.UltimiArriviFornitoreModule;
|
||||||
import it.integry.integrywmsnative.gest.versamento_merce.VersamentoMerceComponent;
|
import it.integry.integrywmsnative.gest.versamento_merce.VersamentoMerceComponent;
|
||||||
@@ -251,7 +253,8 @@ import it.integry.integrywmsnative.view.dialogs.update_available.DialogUpdateAva
|
|||||||
VerificaGiacenzeModule.class,
|
VerificaGiacenzeModule.class,
|
||||||
DialogExtraInfoModule.class,
|
DialogExtraInfoModule.class,
|
||||||
DialogAskDepositoModule.class,
|
DialogAskDepositoModule.class,
|
||||||
DialogChooseArtFromListaArtsModule.class
|
DialogChooseArtFromListaArtsModule.class,
|
||||||
|
DialogUltimeConsegneFiltroAvanzatoModule.class
|
||||||
})
|
})
|
||||||
public interface MainApplicationComponent {
|
public interface MainApplicationComponent {
|
||||||
|
|
||||||
@@ -422,6 +425,8 @@ public interface MainApplicationComponent {
|
|||||||
|
|
||||||
DialogChooseArtFromListaArtsComponent.Factory dialogChooseArtFromListaArtsComponent();
|
DialogChooseArtFromListaArtsComponent.Factory dialogChooseArtFromListaArtsComponent();
|
||||||
|
|
||||||
|
DialogUltimeConsegneFiltroAvanzatoComponent.Factory dialogDialogUltimeConsegneFiltroAvanzatoComponent();
|
||||||
|
|
||||||
void inject(MainApplication mainApplication);
|
void inject(MainApplication mainApplication);
|
||||||
|
|
||||||
void inject(AppContext mainApplication);
|
void inject(AppContext mainApplication);
|
||||||
|
|||||||
@@ -313,8 +313,8 @@ public class MainApplicationModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
DocumentRESTConsumer provideDocumentiRESTConsumer(RESTBuilder restBuilder) {
|
DocumentRESTConsumer provideDocumentiRESTConsumer(RESTBuilder restBuilder, ExecutorService executorService) {
|
||||||
return new DocumentRESTConsumer(restBuilder);
|
return new DocumentRESTConsumer(restBuilder, executorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import androidx.databinding.Observable;
|
|||||||
import androidx.databinding.ObservableField;
|
import androidx.databinding.ObservableField;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewTreeLifecycleOwner;
|
import androidx.lifecycle.ViewTreeLifecycleOwner;
|
||||||
|
|
||||||
@@ -540,6 +541,124 @@ public class Converters {
|
|||||||
view.setText(UtilityDate.formatDate(newValue, UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN));
|
view.setText(UtilityDate.formatDate(newValue, UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@BindingAdapter(value = {"binding", "parentView", "warningOnOldDates"}, requireAll = false)
|
||||||
|
public static void bindTextInputEditTextDate(TextInputEditText view, final MutableLiveData<Date> liveDataDate, BaseDialogFragment parentFragment, boolean warningOnOldDates) {
|
||||||
|
// Ottieni il LifecycleOwner dalla view
|
||||||
|
LifecycleOwner lifecycleOwner = ViewTreeLifecycleOwner.get(view);
|
||||||
|
if (lifecycleOwner == null) {
|
||||||
|
// Non è possibile osservare LiveData senza un LifecycleOwner
|
||||||
|
// Potresti loggare un errore o gestire questo caso come preferisci
|
||||||
|
Log.e("BindingAdapters", "LifecycleOwner not found for view " + view.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rimuovi eventuali TextWatcher o listener precedenti per evitare duplicazioni
|
||||||
|
// Questo è importante se il BindingAdapter viene chiamato più volte per la stessa view
|
||||||
|
Object oldTag = view.getTag(R.id.bound_observable_date_listener);
|
||||||
|
if (oldTag instanceof TextWatcherAdapter) {
|
||||||
|
view.removeTextChangedListener((TextWatcherAdapter) oldTag);
|
||||||
|
}
|
||||||
|
Object oldLiveDataTag = view.getTag(R.id.bound_observable_date_livedata);
|
||||||
|
if (oldLiveDataTag instanceof MutableLiveData) {
|
||||||
|
// Se c'era un observer precedente su un altro LiveData, rimuovilo
|
||||||
|
// Questo scenario è meno comune ma è bene gestirlo
|
||||||
|
Observer<Date> existingObserver = (Observer<Date>) view.getTag(R.id.bound_observable_date_observer);
|
||||||
|
if (existingObserver != null) {
|
||||||
|
((MutableLiveData<Date>) oldLiveDataTag).removeObserver(existingObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Imposta il listener per il click per aprire il DatePicker
|
||||||
|
RunnableArgs<View> onClick = v -> {
|
||||||
|
Calendar c = UtilityDate.getCalendarInstance();
|
||||||
|
if (liveDataDate.getValue() != null) {
|
||||||
|
c.setTime(liveDataDate.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialDatePicker<Long> datePicker =
|
||||||
|
MaterialDatePicker.Builder.datePicker()
|
||||||
|
.setSelection(c.getTimeInMillis())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
datePicker.addOnPositiveButtonClickListener(selection -> {
|
||||||
|
Calendar calendar = UtilityDate.getCalendarInstance();
|
||||||
|
calendar.setTimeInMillis(selection);
|
||||||
|
Date selectedDate = calendar.getTime();
|
||||||
|
|
||||||
|
if (parentFragment != null && warningOnOldDates && calendar.before(UtilityDate.getCalendarInstance())) {
|
||||||
|
DialogSimpleMessageView
|
||||||
|
.makeWarningDialog(new SpannableString("Hai scelto una data precedente a quella odierna. Continuare?"), null, () -> {
|
||||||
|
liveDataDate.postValue(selectedDate);
|
||||||
|
}, () -> {
|
||||||
|
// Non fare nulla se l'utente annulla
|
||||||
|
})
|
||||||
|
.show(parentFragment.requireActivity().getSupportFragmentManager(), "DatePickerWarningDialog");
|
||||||
|
} else {
|
||||||
|
liveDataDate.postValue(selectedDate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
datePicker.addOnNegativeButtonClickListener(dialog -> {
|
||||||
|
// Utente ha annullato, potresti voler resettare o non fare nulla
|
||||||
|
});
|
||||||
|
datePicker.addOnCancelListener(dialog -> {
|
||||||
|
// Utente ha cancellato (es. premendo back), potresti voler resettare o non fare nulla
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
datePicker.show(parentFragment.requireActivity().getSupportFragmentManager(), "MaterialDatePicker");
|
||||||
|
};
|
||||||
|
|
||||||
|
view.setOnClickListener(onClick::run);
|
||||||
|
if (view.getParent() != null && view.getParent().getParent() != null && view.getParent().getParent() instanceof TextInputLayout) {
|
||||||
|
((FrameLayout) view.getParent()).setOnClickListener(onClick::run);
|
||||||
|
((TextInputLayout) view.getParent().getParent()).setOnClickListener(onClick::run);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Osserva il LiveData per aggiornare la view quando il valore cambia
|
||||||
|
Observer<Date> dateObserver = date -> {
|
||||||
|
String formattedDate = UtilityDate.formatDate(date, UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN);
|
||||||
|
if (!view.getText().toString().equals(formattedDate)) {
|
||||||
|
view.setText(formattedDate);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rimuovi l'observer precedente se stiamo ri-bindando allo stesso LiveData
|
||||||
|
Observer<Date> existingObserver = (Observer<Date>) view.getTag(R.id.bound_observable_date_observer);
|
||||||
|
if (view.getTag(R.id.bound_observable_date_livedata) == liveDataDate && existingObserver != null) {
|
||||||
|
liveDataDate.removeObserver(existingObserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
liveDataDate.observe(lifecycleOwner, dateObserver);
|
||||||
|
|
||||||
|
// Salva il LiveData e l'observer nel tag per poterli rimuovere in futuro se necessario
|
||||||
|
view.setTag(R.id.bound_observable_date_livedata, liveDataDate);
|
||||||
|
view.setTag(R.id.bound_observable_date_observer, dateObserver);
|
||||||
|
|
||||||
|
// Imposta il valore iniziale
|
||||||
|
Date initialDate = liveDataDate.getValue();
|
||||||
|
view.setText(UtilityDate.formatDate(initialDate, UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN));
|
||||||
|
|
||||||
|
// Aggiungi un TextWatcher fittizio se necessario per coerenza con altri binding,
|
||||||
|
// ma in questo caso il LiveData guida l'aggiornamento.
|
||||||
|
// Se non hai bisogno di reagire ai cambiamenti di testo *dalla view al LiveData*
|
||||||
|
// (perché il DatePicker lo fa già), questo TextWatcher potrebbe non essere strettamente necessario.
|
||||||
|
// Tuttavia, per mantenere la struttura simile agli altri, lo includiamo.
|
||||||
|
TextWatcherAdapter watcher = new TextWatcherAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
// Normalmente qui si aggiornerebbe il LiveData,
|
||||||
|
// ma il DatePicker gestisce l'aggiornamento.
|
||||||
|
// Potresti aggiungere logica qui se l'utente può modificare il testo direttamente
|
||||||
|
// e vuoi che ciò si rifletta nel LiveData (richiederebbe parsing della data).
|
||||||
|
}
|
||||||
|
};
|
||||||
|
view.setTag(R.id.bound_observable_date_listener, watcher); // Salva il watcher nel tag
|
||||||
|
// view.addTextChangedListener(watcher); // Aggiungi solo se necessario
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@BindingAdapter(value = {"binding", "parentView", "warningOnOldDates"}, requireAll = false)
|
@BindingAdapter(value = {"binding", "parentView", "warningOnOldDates"}, requireAll = false)
|
||||||
public static void bindEditTextDate(EditText view, final ObservableField<LocalDate> observableDate, BaseDialogFragment parentFragment, boolean warningOnOldDates) {
|
public static void bindEditTextDate(EditText view, final ObservableField<LocalDate> observableDate, BaseDialogFragment parentFragment, boolean warningOnOldDates) {
|
||||||
Pair<ObservableField<LocalDate>, TextWatcherAdapter> pair = (Pair) view.getTag(R.id.bound_observable);
|
Pair<ObservableField<LocalDate>, TextWatcherAdapter> pair = (Pair) view.getTag(R.id.bound_observable);
|
||||||
@@ -606,6 +725,67 @@ public class Converters {
|
|||||||
view.setText(UtilityDate.formatDate(newValue, UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN));
|
view.setText(UtilityDate.formatDate(newValue, UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("binding")
|
||||||
|
public static void bindAutoCompleteTextView(AutoCompleteTextView view, final MutableLiveData<String> liveDataString) {
|
||||||
|
LifecycleOwner lifecycleOwner = ViewTreeLifecycleOwner.get(view);
|
||||||
|
if (lifecycleOwner == null) {
|
||||||
|
Log.e("BindingAdapters", "LifecycleOwner not found for view " + view.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rimuovi TextWatcher precedente
|
||||||
|
Object oldWatcherTag = view.getTag(R.id.bound_observable_actv_watcher);
|
||||||
|
if (oldWatcherTag instanceof TextWatcherAdapter) {
|
||||||
|
view.removeTextChangedListener((TextWatcherAdapter) oldWatcherTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rimuovi Observer precedente se il LiveData è cambiato
|
||||||
|
Object oldLiveDataTag = view.getTag(R.id.bound_observable_actv_livedata);
|
||||||
|
if (oldLiveDataTag instanceof MutableLiveData && oldLiveDataTag != liveDataString) {
|
||||||
|
Observer<String> existingObserver = (Observer<String>) view.getTag(R.id.bound_observable_actv_observer);
|
||||||
|
if (existingObserver != null) {
|
||||||
|
((MutableLiveData<String>) oldLiveDataTag).removeObserver(existingObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TextWatcher per aggiornare il LiveData quando il testo cambia nella View
|
||||||
|
TextWatcherAdapter watcher = new TextWatcherAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
if (liveDataString.getValue() == null || !liveDataString.getValue().equals(s.toString())) {
|
||||||
|
liveDataString.setValue(s.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
view.addTextChangedListener(watcher);
|
||||||
|
view.setTag(R.id.bound_observable_actv_watcher, watcher);
|
||||||
|
|
||||||
|
// Observer per aggiornare la View quando il LiveData cambia
|
||||||
|
Observer<String> observer = newValue -> {
|
||||||
|
if (!view.getText().toString().equals(newValue)) {
|
||||||
|
view.setText(newValue, false); // Il 'false' evita di far scattare il dropdown
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rimuovi l'observer precedente se stiamo ri-bindando allo stesso LiveData
|
||||||
|
Observer<String> existingObserver = (Observer<String>) view.getTag(R.id.bound_observable_actv_observer);
|
||||||
|
if (view.getTag(R.id.bound_observable_actv_livedata) == liveDataString && existingObserver != null) {
|
||||||
|
liveDataString.removeObserver(existingObserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
liveDataString.observe(lifecycleOwner, observer);
|
||||||
|
|
||||||
|
// Salva il LiveData e l'observer nel tag
|
||||||
|
view.setTag(R.id.bound_observable_actv_livedata, liveDataString);
|
||||||
|
view.setTag(R.id.bound_observable_actv_observer, observer);
|
||||||
|
|
||||||
|
// Imposta il valore iniziale
|
||||||
|
String initialValue = liveDataString.getValue();
|
||||||
|
if (initialValue != null && !view.getText().toString().equals(initialValue)) {
|
||||||
|
view.setText(initialValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@BindingAdapter("binding")
|
@BindingAdapter("binding")
|
||||||
public static void bindAutoCompleteTextView(AutoCompleteTextView view, final BindableString bindableString) {
|
public static void bindAutoCompleteTextView(AutoCompleteTextView view, final BindableString bindableString) {
|
||||||
Pair<BindableString, TextWatcherAdapter> pair = (Pair) view.getTag(R.id.bound_observable);
|
Pair<BindableString, TextWatcherAdapter> pair = (Pair) view.getTag(R.id.bound_observable);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package it.integry.integrywmsnative.core.expansion;
|
package it.integry.integrywmsnative.core.expansion;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -47,6 +47,14 @@ public abstract class BaseDialogFragment extends DialogFragment implements Dialo
|
|||||||
this.cancelable = cancelable;
|
this.cancelable = cancelable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||||
|
// getDialog().setOn
|
||||||
|
|
||||||
|
return super.onCreateDialog(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void show(FragmentManager manager, String tag) {
|
public void show(FragmentManager manager, String tag) {
|
||||||
try {
|
try {
|
||||||
@@ -58,11 +66,6 @@ public abstract class BaseDialogFragment extends DialogFragment implements Dialo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
this.initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onLoadingStarted() {
|
public void onLoadingStarted() {
|
||||||
this.openProgress();
|
this.openProgress();
|
||||||
|
|||||||
@@ -61,15 +61,16 @@ public class AuthInterceptor implements Interceptor {
|
|||||||
return chain.proceed(originalRequest);
|
return chain.proceed(originalRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Retrieve the new access token after refresh
|
||||||
|
accessToken = SettingsManager.i().getUserSession().getAccessToken();
|
||||||
|
}
|
||||||
|
|
||||||
// Add the access token to the request header
|
// Add the access token to the request header
|
||||||
var authorizedRequest = originalRequest.newBuilder()
|
var authorizedRequest = originalRequest.newBuilder()
|
||||||
.header("Authorization", "Bearer " + SettingsManager.i().getUserSession().getAccessToken())
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return chain.proceed(authorizedRequest);
|
return chain.proceed(authorizedRequest);
|
||||||
} else
|
|
||||||
return chain.proceed(originalRequest);
|
|
||||||
} else
|
} else
|
||||||
return chain.proceed(originalRequest);
|
return chain.proceed(originalRequest);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package it.integry.integrywmsnative.core.rest;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import it.integry.integrywmsnative.core.settings.SettingsManager;
|
import it.integry.integrywmsnative.core.settings.SettingsManager;
|
||||||
import it.integry.integrywmsnative.core.utility.UtilityDate;
|
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.Interceptor;
|
import okhttp3.Interceptor;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
@@ -31,18 +30,6 @@ public class HttpInterceptor implements Interceptor {
|
|||||||
.addHeader("Accept", "*/*")
|
.addHeader("Accept", "*/*")
|
||||||
.addHeader("x-app-token", APP_TOKEN);
|
.addHeader("x-app-token", APP_TOKEN);
|
||||||
|
|
||||||
|
|
||||||
String accessToken = null;
|
|
||||||
|
|
||||||
//Nel caso in cui il token è scaduto e devo richiamare la refresh non bisogna passare il vecchio token
|
|
||||||
if(SettingsManager.i().getUserSession().getAccessTokenExpiryDate() != null &&
|
|
||||||
UtilityDate.getNowTime().isBefore(SettingsManager.i().getUserSession().getAccessTokenExpiryDate().minusSeconds(20))) {
|
|
||||||
accessToken = SettingsManager.i().getUserSession().getAccessToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(accessToken != null)
|
|
||||||
builder.header("Authorization", "Bearer " + accessToken);
|
|
||||||
|
|
||||||
var newRequest = builder
|
var newRequest = builder
|
||||||
.url(url)
|
.url(url)
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package it.integry.integrywmsnative.core.rest.consumers;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
@@ -20,9 +21,11 @@ import retrofit2.Response;
|
|||||||
public class DocumentRESTConsumer extends _BaseRESTConsumer {
|
public class DocumentRESTConsumer extends _BaseRESTConsumer {
|
||||||
|
|
||||||
private final RESTBuilder restBuilder;
|
private final RESTBuilder restBuilder;
|
||||||
|
private final ExecutorService executorService;
|
||||||
|
|
||||||
public DocumentRESTConsumer(RESTBuilder restBuilder) {
|
public DocumentRESTConsumer(RESTBuilder restBuilder, ExecutorService executorService) {
|
||||||
this.restBuilder = restBuilder;
|
this.restBuilder = restBuilder;
|
||||||
|
this.executorService = executorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createDocsFromColli(List<LoadColliDTO> listColli, RunnableArgs<List<DtbDoct>> onComplete, RunnableArgs<Exception> onFailed) {
|
public void createDocsFromColli(List<LoadColliDTO> listColli, RunnableArgs<List<DtbDoct>> onComplete, RunnableArgs<Exception> onFailed) {
|
||||||
@@ -40,19 +43,22 @@ public class DocumentRESTConsumer extends _BaseRESTConsumer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createDocFromColli(LoadColliDTO loadColliDTO, RunnableArgs<DtbDoct> onComplete, RunnableArgs<Exception> onFailed) {
|
public DtbDoct makeSynchronousCreateDocFromColliRequest(LoadColliDTO loadColliDTO) throws Exception {
|
||||||
DocumentiRESTConsumerService documentiRESTConsumerService = restBuilder.getService(DocumentiRESTConsumerService.class);
|
DocumentiRESTConsumerService documentiRESTConsumerService = restBuilder.getService(DocumentiRESTConsumerService.class);
|
||||||
documentiRESTConsumerService
|
var response = documentiRESTConsumerService
|
||||||
.createDocFromColli(loadColliDTO)
|
.createDocFromColli(loadColliDTO)
|
||||||
.enqueue(new ManagedErrorCallback<>() {
|
.execute();
|
||||||
@Override
|
|
||||||
public void onResponse(Call<ServiceRESTResponse<DtbDoct>> call, Response<ServiceRESTResponse<DtbDoct>> response) {
|
|
||||||
analyzeAnswer(response, "createDocFromColli", onComplete, onFailed);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
return analyzeAnswer(response, "createDocFromColli");
|
||||||
public void onFailure(Call<ServiceRESTResponse<DtbDoct>> call, @NonNull final Exception e) {
|
}
|
||||||
onFailed.run(e);
|
|
||||||
|
public void makeCreateDocFromColliRequest(LoadColliDTO loadColliDTO, RunnableArgs<DtbDoct> onComplete, RunnableArgs<Exception> onFailed) {
|
||||||
|
executorService.execute(() -> {
|
||||||
|
try {
|
||||||
|
var result = makeSynchronousCreateDocFromColliRequest(loadColliDTO);
|
||||||
|
if (onComplete != null) onComplete.run(result);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
if (onFailed != null) onFailed.run(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ public class OrdiniRESTConsumer extends _BaseRESTConsumer {
|
|||||||
var response = service.retrieveAlreadyRegisteredUDS(request)
|
var response = service.retrieveAlreadyRegisteredUDS(request)
|
||||||
.execute();
|
.execute();
|
||||||
var data = analyzeAnswer(response, "getBancaliGiaRegistrati");
|
var data = analyzeAnswer(response, "getBancaliGiaRegistrati");
|
||||||
return data == null ? new ArrayList<>() : data.getUdsList();
|
return data == null || data.getUdsList() == null ? new ArrayList<>() : data.getUdsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getBancaliGiaRegistrati(List<OrdineInevasoDTO> orders, int segno, RunnableArgs<List<AlreadyRegisteredUlDTO>> onComplete, RunnableArgs<Exception> onFailed) {
|
public void getBancaliGiaRegistrati(List<OrdineInevasoDTO> orders, int segno, RunnableArgs<List<AlreadyRegisteredUlDTO>> onComplete, RunnableArgs<Exception> onFailed) {
|
||||||
|
|||||||
@@ -125,13 +125,12 @@ public class PrinterRESTConsumer extends _BaseRESTConsumer {
|
|||||||
|
|
||||||
public void printClosedOrdersSynchronized(PrintOrderCloseDTO dto, String codMdep) throws Exception {
|
public void printClosedOrdersSynchronized(PrintOrderCloseDTO dto, String codMdep) throws Exception {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
return;
|
// return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrinterRESTConsumerService printerService = restBuilder.getService(PrinterRESTConsumerService.class, 240);
|
PrinterRESTConsumerService printerService = restBuilder.getService(PrinterRESTConsumerService.class, 240);
|
||||||
Call<ServiceRESTResponse<Object>> callable = printerService.printClosedOrders(codMdep, dto);
|
|
||||||
|
|
||||||
var response = callable.execute();
|
var response = printerService.printClosedOrders(codMdep, dto).execute();
|
||||||
analyzeAnswer(response, "printCollo");
|
analyzeAnswer(response, "printCollo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -806,7 +806,7 @@ public class OrdiniUscitaElencoFragment extends BaseFragment implements ITitledF
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Stream.of(this.mOrdiniInevasiMutableData)
|
this.mOrdiniInevasiMutableData.stream()
|
||||||
.forEach(x -> x.getSelectedObservable().set(false));
|
.forEach(x -> x.getSelectedObservable().set(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -862,12 +862,10 @@ public class SpedizioneActivity extends BaseActivity implements SpedizioneViewMo
|
|||||||
|
|
||||||
public void closeOrder() {
|
public void closeOrder() {
|
||||||
this.fabPopupMenu.dismiss();
|
this.fabPopupMenu.dismiss();
|
||||||
this.onLoadingStarted();
|
|
||||||
|
|
||||||
executorService.execute(() -> {
|
executorService.execute(() -> {
|
||||||
try {
|
try {
|
||||||
this.mViewmodel.closeOrder();
|
this.mViewmodel.closeOrder();
|
||||||
this.onLoadingEnded();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
onError(e);
|
onError(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,14 +342,6 @@ public class SpedizioneViewModel {
|
|||||||
return mIsOrdTrasf;
|
return mIsOrdTrasf;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onOrderClosedPrintingDone() {
|
|
||||||
if (this.mIsOrdTrasf && !UtilityString.isNullOrEmpty(SettingsManager.iDB().getCodDtipOrdTrasfV())) {
|
|
||||||
this.sendCreateDocsRequest();
|
|
||||||
} else {
|
|
||||||
this.sendOnOrderClosed();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendOnLoadingStarted() {
|
private void sendOnLoadingStarted() {
|
||||||
if (this.mListener != null) mListener.onLoadingStarted();
|
if (this.mListener != null) mListener.onLoadingStarted();
|
||||||
@@ -2123,15 +2115,21 @@ public class SpedizioneViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void closeOrder() {
|
public void closeOrder() {
|
||||||
|
this.sendOnLoadingStarted();
|
||||||
|
|
||||||
if (SettingsManager.iDB().isFlagPrintEtichetteOnOrderClose() || SettingsManager.iDB().isFlagPrintPackingListOnOrderClose()) {
|
if (SettingsManager.iDB().isFlagPrintEtichetteOnOrderClose() || SettingsManager.iDB().isFlagPrintPackingListOnOrderClose()) {
|
||||||
var printRequestResult = this.sendOnCloseOrderPrintRequest();
|
var printRequestResult = this.sendOnCloseOrderPrintRequest();
|
||||||
this.onCloseOrderPrintRequest(printRequestResult);
|
this.onCloseOrderPrintRequested(printRequestResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onOrderClosedPrintingDone();
|
if (this.mIsOrdTrasf && !UtilityString.isNullOrEmpty(SettingsManager.iDB().getCodDtipOrdTrasfV())) {
|
||||||
|
this.sendCreateDocsRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendOnOrderClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onCloseOrderPrintRequest(PrintOrderCloseDTO dto) {
|
private void onCloseOrderPrintRequested(PrintOrderCloseDTO dto) {
|
||||||
if (!dto.isFlagPrintPackingList() && !dto.isFlagPrintSSCC()) {
|
if (!dto.isFlagPrintPackingList() && !dto.isFlagPrintSSCC()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2147,13 +2145,22 @@ public class SpedizioneViewModel {
|
|||||||
|
|
||||||
dto.setPrintList(closedOrders);
|
dto.setPrintList(closedOrders);
|
||||||
|
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
printClosedOrders(dto);
|
printClosedOrders(dto);
|
||||||
|
latch.countDown();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.sendLUPrintError(e, () -> {
|
this.sendLUPrintError(e, () -> {
|
||||||
|
latch.countDown();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printClosedOrders(PrintOrderCloseDTO dto) throws Exception {
|
private void printClosedOrders(PrintOrderCloseDTO dto) throws Exception {
|
||||||
@@ -2201,6 +2208,7 @@ public class SpedizioneViewModel {
|
|||||||
|
|
||||||
void createDocs() {
|
void createDocs() {
|
||||||
executorService.execute(() -> {
|
executorService.execute(() -> {
|
||||||
|
this.sendOnLoadingStarted();
|
||||||
List<MtbColt> registeredUds = null;
|
List<MtbColt> registeredUds = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -2237,7 +2245,12 @@ public class SpedizioneViewModel {
|
|||||||
loadCollidto.setSaveDoc(true);
|
loadCollidto.setSaveDoc(true);
|
||||||
loadCollidto.setGestione("L");
|
loadCollidto.setGestione("L");
|
||||||
|
|
||||||
this.mDocumentRESTConsumer.createDocFromColli(loadCollidto, doc -> this.sendOnOrderClosed(), this::sendError);
|
try {
|
||||||
|
this.mDocumentRESTConsumer.makeSynchronousCreateDocFromColliRequest(loadCollidto);
|
||||||
|
} catch (Exception e) {
|
||||||
|
sendError(e);
|
||||||
|
}
|
||||||
|
this.sendOnLoadingEnded();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import androidx.databinding.DataBindingUtil;
|
|||||||
import androidx.databinding.ObservableArrayList;
|
import androidx.databinding.ObservableArrayList;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import com.annimon.stream.Optional;
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -39,7 +38,7 @@ import it.integry.integrywmsnative.core.settings.SettingsManager;
|
|||||||
import it.integry.integrywmsnative.core.utility.UtilityExceptions;
|
import it.integry.integrywmsnative.core.utility.UtilityExceptions;
|
||||||
import it.integry.integrywmsnative.databinding.FragmentMainUltimeConsegneClienteBinding;
|
import it.integry.integrywmsnative.databinding.FragmentMainUltimeConsegneClienteBinding;
|
||||||
import it.integry.integrywmsnative.gest.picking_resi.PickingResiActivity;
|
import it.integry.integrywmsnative.gest.picking_resi.PickingResiActivity;
|
||||||
import it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog.DialogUltimeConsegneFiltroAvanzato;
|
import it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog.DialogUltimeConsegneFiltroAvanzatoView;
|
||||||
import it.integry.integrywmsnative.ui.ElevatedToolbar;
|
import it.integry.integrywmsnative.ui.ElevatedToolbar;
|
||||||
|
|
||||||
public class UltimeConsegneClienteFragment extends BaseFragment implements UltimeConsegneClienteViewModel.Listener, ITitledFragment, IScrollableFragment, IFilterableFragment {
|
public class UltimeConsegneClienteFragment extends BaseFragment implements UltimeConsegneClienteViewModel.Listener, ITitledFragment, IScrollableFragment, IFilterableFragment {
|
||||||
@@ -54,8 +53,6 @@ public class UltimeConsegneClienteFragment extends BaseFragment implements Ultim
|
|||||||
@Inject
|
@Inject
|
||||||
UltimeConsegneClienteViewModel mViewModel;
|
UltimeConsegneClienteViewModel mViewModel;
|
||||||
|
|
||||||
private DialogUltimeConsegneFiltroAvanzato.DialogUltimeConsegneFiltroAvanzatoViewModel mAppliedFilterViewModel;
|
|
||||||
|
|
||||||
private FragmentMainUltimeConsegneClienteBinding mBindings;
|
private FragmentMainUltimeConsegneClienteBinding mBindings;
|
||||||
|
|
||||||
public UltimeConsegneClienteFragment() {
|
public UltimeConsegneClienteFragment() {
|
||||||
@@ -114,10 +111,12 @@ public class UltimeConsegneClienteFragment extends BaseFragment implements Ultim
|
|||||||
this.mViewModel.loadCodAnagClienti(gtbAnags -> {
|
this.mViewModel.loadCodAnagClienti(gtbAnags -> {
|
||||||
handler.post(() -> {
|
handler.post(() -> {
|
||||||
|
|
||||||
DialogUltimeConsegneFiltroAvanzato.make(getActivity(), gtbAnags, mAppliedFilterViewModel, (filter) -> {
|
DialogUltimeConsegneFiltroAvanzatoView.newInstance(gtbAnags, filterResult -> {
|
||||||
mAppliedFilterViewModel = filter;
|
if (filterResult == null || filterResult.isAborted()) {
|
||||||
refreshItems();
|
popMe();
|
||||||
}).show();
|
} else refreshConsegne(filterResult.getGtbAnag());
|
||||||
|
})
|
||||||
|
.show(requireActivity().getSupportFragmentManager(), "dialog-filtro-ultime-consegne");
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -133,7 +132,6 @@ public class UltimeConsegneClienteFragment extends BaseFragment implements Ultim
|
|||||||
mBindings.recyclerView.setHasFixedSize(true);
|
mBindings.recyclerView.setHasFixedSize(true);
|
||||||
mBindings.recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
mBindings.recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||||
mBindings.recyclerView.setAdapter(mAdapter);
|
mBindings.recyclerView.setAdapter(mAdapter);
|
||||||
// mBindings.fastscroll.setRecyclerView(mBindings.recyclerView);
|
|
||||||
|
|
||||||
|
|
||||||
if (mToolbar != null)
|
if (mToolbar != null)
|
||||||
@@ -162,21 +160,10 @@ public class UltimeConsegneClienteFragment extends BaseFragment implements Ultim
|
|||||||
this.mDocumentiMutableData.addAll(sort(documentList));
|
this.mDocumentiMutableData.addAll(sort(documentList));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshItems() {
|
private void refreshConsegne(GtbAnag gtbAnag) {
|
||||||
this.onLoadingStarted();
|
this.onLoadingStarted();
|
||||||
|
|
||||||
String currentAnagFilter = mAppliedFilterViewModel != null ? mAppliedFilterViewModel.ragSoc.get() : null;
|
this.mViewModel.loadConsegneClienti(gtbAnag.getCodAnag(),
|
||||||
String currentCodAnagFilter = null;
|
|
||||||
|
|
||||||
Optional<GtbAnag> singleGtbAnag = Stream.of(this.mViewModel.getGtbAnagClienti().getValue())
|
|
||||||
.filter(x -> (x.getCodAnag() + " - " + x.getRagSoc()).equals(currentAnagFilter))
|
|
||||||
.findSingle();
|
|
||||||
|
|
||||||
if (singleGtbAnag.isPresent()) {
|
|
||||||
currentCodAnagFilter = singleGtbAnag.get().getCodAnag();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mViewModel.loadConsegneClienti(currentCodAnagFilter,
|
|
||||||
null,
|
null,
|
||||||
-1,
|
-1,
|
||||||
548
|
548
|
||||||
|
|||||||
@@ -1,192 +0,0 @@
|
|||||||
package it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog;
|
|
||||||
|
|
||||||
import android.app.DatePickerDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
|
|
||||||
import com.annimon.stream.Stream;
|
|
||||||
import com.annimon.stream.function.Predicate;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import it.integry.integrywmsnative.R;
|
|
||||||
import it.integry.integrywmsnative.core.di.BindableString;
|
|
||||||
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
|
|
||||||
import it.integry.integrywmsnative.core.model.GtbAnag;
|
|
||||||
import it.integry.integrywmsnative.core.utility.UtilityDate;
|
|
||||||
import it.integry.integrywmsnative.core.utility.UtilityString;
|
|
||||||
import it.integry.integrywmsnative.databinding.DialogUltimeConsegneFiltroAvanzatoBinding;
|
|
||||||
import it.integry.integrywmsnative.ui.adapter.SimpleAutoCompleteDropdownAdapter;
|
|
||||||
|
|
||||||
public class DialogUltimeConsegneFiltroAvanzato {
|
|
||||||
|
|
||||||
private AlertDialog mAlert;
|
|
||||||
private Context mContext;
|
|
||||||
private DialogUltimeConsegneFiltroAvanzatoViewModel mBaseViewModel;
|
|
||||||
private RunnableArgs<DialogUltimeConsegneFiltroAvanzatoViewModel> mOnDismiss;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private ArrayAdapter<String> arrayAdapterRagSoc;
|
|
||||||
|
|
||||||
private List<GtbAnag> mItems;
|
|
||||||
private List<GtbAnag> mFilteredItems;
|
|
||||||
|
|
||||||
private Predicate<GtbAnag> currentRagSocPredicate = null;
|
|
||||||
private Predicate<GtbAnag> currentDataDocPredicate = null;
|
|
||||||
|
|
||||||
public static AlertDialog make(final Context context,
|
|
||||||
final List<GtbAnag> items,
|
|
||||||
DialogUltimeConsegneFiltroAvanzatoViewModel baseViewModel,
|
|
||||||
RunnableArgs<DialogUltimeConsegneFiltroAvanzatoViewModel> onDismiss) {
|
|
||||||
return new DialogUltimeConsegneFiltroAvanzato(context, items, baseViewModel, onDismiss).mAlert;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public DialogUltimeConsegneFiltroAvanzato(final Context context,
|
|
||||||
final List<GtbAnag> items,
|
|
||||||
DialogUltimeConsegneFiltroAvanzatoViewModel baseViewModel,
|
|
||||||
RunnableArgs<DialogUltimeConsegneFiltroAvanzatoViewModel> onDismiss) {
|
|
||||||
mContext = context;
|
|
||||||
mItems = items;
|
|
||||||
mBaseViewModel = baseViewModel;
|
|
||||||
mOnDismiss = onDismiss;
|
|
||||||
|
|
||||||
DialogUltimeConsegneFiltroAvanzatoViewModel viewModel = baseViewModel != null ? baseViewModel : new DialogUltimeConsegneFiltroAvanzatoViewModel();
|
|
||||||
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
DialogUltimeConsegneFiltroAvanzatoBinding binding = DialogUltimeConsegneFiltroAvanzatoBinding.inflate(inflater, null, false);
|
|
||||||
|
|
||||||
final AlertDialog.Builder dialog = new AlertDialog.Builder(context)
|
|
||||||
.setView(binding.getRoot());
|
|
||||||
|
|
||||||
binding.setViewmodel(viewModel);
|
|
||||||
initViewModelNew(viewModel);
|
|
||||||
initView(binding, viewModel);
|
|
||||||
|
|
||||||
mAlert = dialog.create();
|
|
||||||
mAlert.setCanceledOnTouchOutside(false);
|
|
||||||
|
|
||||||
mAlert.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
|
||||||
mAlert.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
|
||||||
|
|
||||||
binding.positiveBtn.setOnClickListener(view -> {
|
|
||||||
mAlert.dismiss();
|
|
||||||
});
|
|
||||||
|
|
||||||
binding.neutralBtn.setOnClickListener(view -> {
|
|
||||||
resetAll(viewModel);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
mAlert.setOnDismissListener(dialogInterface -> {
|
|
||||||
if(mOnDismiss != null) mOnDismiss.run(viewModel);
|
|
||||||
});
|
|
||||||
|
|
||||||
refreshList();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetAll(DialogUltimeConsegneFiltroAvanzatoViewModel viewModel) {
|
|
||||||
viewModel.ragSoc.set(null);
|
|
||||||
viewModel.dataDoc.set(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initView(DialogUltimeConsegneFiltroAvanzatoBinding bindings, DialogUltimeConsegneFiltroAvanzatoViewModel viewModel) {
|
|
||||||
|
|
||||||
arrayAdapterRagSoc = new SimpleAutoCompleteDropdownAdapter<>(mContext, R.layout.dialog_vendita_filtro_avanzato__single_item, getAvailableRagSocs(false));
|
|
||||||
arrayAdapterRagSoc.addAll();
|
|
||||||
bindings.filledExposedDropdownRagSoc.setAdapter(arrayAdapterRagSoc);
|
|
||||||
|
|
||||||
bindings.filledExposedDropdownDataDoc.setOnClickListener(view -> {
|
|
||||||
Calendar c = UtilityDate.getCalendarInstance();
|
|
||||||
|
|
||||||
if(viewModel.dataDocDate != null) {
|
|
||||||
c.setTime(viewModel.dataDocDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mYear = c.get(Calendar.YEAR);
|
|
||||||
int mMonth = c.get(Calendar.MONTH);
|
|
||||||
int mDay = c.get(Calendar.DAY_OF_MONTH);
|
|
||||||
|
|
||||||
DatePickerDialog datePickerDialog = new DatePickerDialog(mContext,
|
|
||||||
(view2, year, month, day) -> {
|
|
||||||
|
|
||||||
viewModel.dataDocDate = new GregorianCalendar(year, month, day).getTime();
|
|
||||||
viewModel.dataDoc.set(UtilityDate.formatDate(viewModel.dataDocDate, UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN));
|
|
||||||
|
|
||||||
}, mYear, mMonth, mDay);
|
|
||||||
datePickerDialog.show();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
viewModel.ragSoc.refresh();
|
|
||||||
viewModel.dataDoc.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initViewModelNew(DialogUltimeConsegneFiltroAvanzatoViewModel viewModel) {
|
|
||||||
|
|
||||||
BindableString.resetListeners(viewModel.ragSoc);
|
|
||||||
BindableString.registerListener(viewModel.ragSoc, value -> {
|
|
||||||
if (UtilityString.isNullOrEmpty(value)) currentRagSocPredicate = null;
|
|
||||||
else {
|
|
||||||
currentRagSocPredicate = o -> {
|
|
||||||
return o.getRagSoc().equalsIgnoreCase(viewModel.ragSoc.get());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshList();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> getAvailableRagSocs(boolean skipRecalc) {
|
|
||||||
if(currentDataDocPredicate == null){
|
|
||||||
mFilteredItems = mItems;
|
|
||||||
} else if(!skipRecalc){
|
|
||||||
Stream<GtbAnag> tmpStream = Stream.of(mItems)
|
|
||||||
.filter(x ->
|
|
||||||
(currentDataDocPredicate == null || (currentDataDocPredicate.test(x)))
|
|
||||||
);
|
|
||||||
|
|
||||||
mFilteredItems = tmpStream.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Stream.of(mFilteredItems).map(x -> x.getCodAnag() + " - " + x.getRagSoc()).distinct().withoutNulls().toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void refreshList() {
|
|
||||||
|
|
||||||
if(currentRagSocPredicate == null && currentDataDocPredicate == null){
|
|
||||||
mFilteredItems = mItems;
|
|
||||||
} else {
|
|
||||||
Stream<GtbAnag> tmpStream = Stream.of(mItems)
|
|
||||||
.filter(x ->
|
|
||||||
(currentRagSocPredicate == null || (currentRagSocPredicate.test(x))) &&
|
|
||||||
(currentDataDocPredicate== null || (currentDataDocPredicate.test(x)))
|
|
||||||
);
|
|
||||||
|
|
||||||
mFilteredItems = tmpStream.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DialogUltimeConsegneFiltroAvanzatoViewModel {
|
|
||||||
|
|
||||||
public BindableString ragSoc = new BindableString();
|
|
||||||
public BindableString dataDoc = new BindableString();
|
|
||||||
|
|
||||||
public Date dataDocDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog;
|
||||||
|
|
||||||
|
import dagger.Subcomponent;
|
||||||
|
|
||||||
|
@Subcomponent
|
||||||
|
public interface DialogUltimeConsegneFiltroAvanzatoComponent {
|
||||||
|
|
||||||
|
@Subcomponent.Factory
|
||||||
|
interface Factory {
|
||||||
|
DialogUltimeConsegneFiltroAvanzatoComponent create();
|
||||||
|
}
|
||||||
|
|
||||||
|
void inject(DialogUltimeConsegneFiltroAvanzatoView dialogUltimeConsegneFiltroAvanzatoView);
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
|
||||||
|
@Module(subcomponents = DialogUltimeConsegneFiltroAvanzatoComponent.class)
|
||||||
|
public class DialogUltimeConsegneFiltroAvanzatoModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
DialogUltimeConsegneFiltroAvanzatoViewModel providesDialogDialogUltimeConsegneFiltroAvanzatoViewModel() {
|
||||||
|
return new DialogUltimeConsegneFiltroAvanzatoViewModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import it.integry.integrywmsnative.MainApplication;
|
||||||
|
import it.integry.integrywmsnative.R;
|
||||||
|
import it.integry.integrywmsnative.core.expansion.BaseDialogFragment;
|
||||||
|
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
|
||||||
|
import it.integry.integrywmsnative.core.model.GtbAnag;
|
||||||
|
import it.integry.integrywmsnative.databinding.DialogUltimeConsegneFiltroAvanzatoBinding;
|
||||||
|
import it.integry.integrywmsnative.ui.adapter.SimpleAutoCompleteDropdownAdapter;
|
||||||
|
|
||||||
|
public class DialogUltimeConsegneFiltroAvanzatoView extends BaseDialogFragment {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
DialogUltimeConsegneFiltroAvanzatoViewModel mViewModel;
|
||||||
|
|
||||||
|
private DialogUltimeConsegneFiltroAvanzatoBinding mBindings;
|
||||||
|
private Context mContext;
|
||||||
|
private SimpleAutoCompleteDropdownAdapter<String> arrayAdapterRagSoc;
|
||||||
|
|
||||||
|
private final RunnableArgs<Result> onConfirm;
|
||||||
|
|
||||||
|
|
||||||
|
public static DialogUltimeConsegneFiltroAvanzatoView newInstance(final List<GtbAnag> items, RunnableArgs<Result> onConfirm) {
|
||||||
|
return new DialogUltimeConsegneFiltroAvanzatoView(items, onConfirm);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DialogUltimeConsegneFiltroAvanzatoView(final List<GtbAnag> items, RunnableArgs<Result> onConfirm) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.onConfirm = onConfirm;
|
||||||
|
|
||||||
|
MainApplication.appComponent
|
||||||
|
.dialogDialogUltimeConsegneFiltroAvanzatoComponent()
|
||||||
|
.create()
|
||||||
|
.inject(this);
|
||||||
|
mViewModel.init(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||||
|
this.mContext = requireContext();
|
||||||
|
|
||||||
|
mBindings = DialogUltimeConsegneFiltroAvanzatoBinding.inflate(LayoutInflater.from(this.mContext), null, false);
|
||||||
|
mBindings.setLifecycleOwner(this); // Necessario per LiveData e binding
|
||||||
|
mBindings.setView(this);
|
||||||
|
mBindings.setViewmodel(mViewModel);
|
||||||
|
|
||||||
|
setCancelable(false);
|
||||||
|
|
||||||
|
var alertDialog = new MaterialAlertDialogBuilder(this.mContext)
|
||||||
|
.setView(mBindings.getRoot())
|
||||||
|
.setCancelable(isCancelable())
|
||||||
|
.setPositiveButton(R.string.ok, (dialog, which) -> onOk())
|
||||||
|
.setNegativeButton(R.string.abort, (dialog, which) -> {
|
||||||
|
if (onConfirm != null) onConfirm.run(Result.aborted());
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
|
||||||
|
alertDialog.setCanceledOnTouchOutside(isCancelable());
|
||||||
|
alertDialog.setOnShowListener(this); // Rimosso se non specificamente necessario per altro
|
||||||
|
|
||||||
|
this.initDropDowns();
|
||||||
|
|
||||||
|
return alertDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dismiss() {
|
||||||
|
if (getDialog() != null) getDialog().dismiss();
|
||||||
|
super.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDropDowns() {
|
||||||
|
// Usa il LiveData delle stringhe formattate dal ViewModel
|
||||||
|
arrayAdapterRagSoc = new SimpleAutoCompleteDropdownAdapter<>(
|
||||||
|
mContext,
|
||||||
|
R.layout.dialog_vendita_filtro_avanzato__single_item, // Assicurati che questo layout sia un semplice TextView
|
||||||
|
mViewModel.getAvailableRagSocsStrings(), // LiveData<List<String>>
|
||||||
|
this // LifecycleOwner
|
||||||
|
);
|
||||||
|
mBindings.filledExposedDropdownRagSoc.setAdapter(arrayAdapterRagSoc);
|
||||||
|
|
||||||
|
// Gestisci la selezione di un item
|
||||||
|
mBindings.filledExposedDropdownRagSoc.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
|
String selectedFormattedString = arrayAdapterRagSoc.getItem(position);
|
||||||
|
if (selectedFormattedString != null) {
|
||||||
|
GtbAnag selectedAnag = mViewModel.findGtbAnagByFormattedString(selectedFormattedString);
|
||||||
|
mViewModel.setRagSoc(selectedAnag); // Aggiorna il GtbAnag nel ViewModel
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
if (mViewModel != null) {
|
||||||
|
mViewModel.resetFilters();
|
||||||
|
}
|
||||||
|
// I campi testo dovrebbero aggiornarsi automaticamente grazie al data binding
|
||||||
|
// e agli observer sui LiveData (ragSocTextBindable e dataDocBindable).
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onOk() {
|
||||||
|
if (onConfirm != null)
|
||||||
|
onConfirm.run(Result.completed(mViewModel.getRagSocBindable().getValue(), mViewModel.getDataDocBindable().getValue()));
|
||||||
|
// dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
mBindings = null; // Per evitare memory leaks
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class Result {
|
||||||
|
private final GtbAnag gtbAnag;
|
||||||
|
private final Date dataDoc;
|
||||||
|
private final boolean isAborted;
|
||||||
|
|
||||||
|
private Result(GtbAnag gtbAnag, Date dataDoc, boolean isAborted) {
|
||||||
|
this.gtbAnag = gtbAnag;
|
||||||
|
this.dataDoc = dataDoc;
|
||||||
|
this.isAborted = isAborted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result completed(GtbAnag gtbAnag, Date dataDoc) {
|
||||||
|
return new Result(gtbAnag, dataDoc, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result aborted() {
|
||||||
|
return new Result(null, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAborted() {
|
||||||
|
return isAborted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GtbAnag getGtbAnag() {
|
||||||
|
return gtbAnag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDataDoc() {
|
||||||
|
return dataDoc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
package it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import it.integry.integrywmsnative.core.model.GtbAnag;
|
||||||
|
|
||||||
|
public class DialogUltimeConsegneFiltroAvanzatoViewModel {
|
||||||
|
|
||||||
|
private final MutableLiveData<GtbAnag> ragSoc = new MutableLiveData<>();
|
||||||
|
private final MutableLiveData<Date> dataDoc = new MutableLiveData<>();
|
||||||
|
|
||||||
|
private List<GtbAnag> availableItems; // Lista completa di GtbAnag originali
|
||||||
|
private final MutableLiveData<List<GtbAnag>> filteredItems = new MutableLiveData<>();
|
||||||
|
|
||||||
|
// LiveData per il testo dell'AutoCompleteTextView della Ragione Sociale
|
||||||
|
private final MutableLiveData<String> ragSocText = new MutableLiveData<>();
|
||||||
|
// LiveData per popolare l'adapter dell'AutoCompleteTextView
|
||||||
|
private final MutableLiveData<List<String>> availableRagSocsStrings = new MutableLiveData<>();
|
||||||
|
|
||||||
|
private final MutableLiveData<Predicate<GtbAnag>> currentRagSocPredicate = new MutableLiveData<>();
|
||||||
|
private final MutableLiveData<Predicate<GtbAnag>> currentDataDocPredicate = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public void init(List<GtbAnag> availableItems) {
|
||||||
|
this.availableItems = availableItems;
|
||||||
|
// Imposta il valore iniziale di filteredItems e availableRagSocsStrings
|
||||||
|
// assicurandosi che i predicati siano null all'inizio se non diversamente specificato.
|
||||||
|
if (this.currentRagSocPredicate.getValue() == null && this.currentDataDocPredicate.getValue() == null) {
|
||||||
|
this.filteredItems.setValue(availableItems);
|
||||||
|
} else {
|
||||||
|
// Se ci sono predicati pre-impostati, applicali.
|
||||||
|
// Questa logica è più per completezza, normalmente all'init i filtri sono resettati.
|
||||||
|
refreshList();
|
||||||
|
}
|
||||||
|
// Calcola availableRagSocsStrings dopo aver impostato availableItems e potenzialmente i predicati.
|
||||||
|
this.availableRagSocsStrings.setValue(calcAvailableRagSocsStrings());
|
||||||
|
this.initBindable();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initBindable() {
|
||||||
|
// Quando il GtbAnag selezionato (ragSoc) cambia
|
||||||
|
this.ragSoc.observeForever(selectedAnag -> {
|
||||||
|
String textToShow = "";
|
||||||
|
Predicate<GtbAnag> newPredicate = null;
|
||||||
|
|
||||||
|
if (selectedAnag != null) {
|
||||||
|
textToShow = formatGtbAnagToString(selectedAnag);
|
||||||
|
newPredicate = o -> o.getCodAnag().equals(selectedAnag.getCodAnag());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Objects.equals(ragSocText.getValue(), textToShow)) {
|
||||||
|
ragSocText.postValue(textToShow);
|
||||||
|
}
|
||||||
|
if (!Objects.equals(currentRagSocPredicate.getValue(), newPredicate)) {
|
||||||
|
currentRagSocPredicate.postValue(newPredicate);
|
||||||
|
} else if (newPredicate == null && currentRagSocPredicate.getValue() != null) {
|
||||||
|
currentRagSocPredicate.postValue(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Quando il testo nell'AutoCompleteTextView (ragSocText) cambia
|
||||||
|
this.ragSocText.observeForever(text -> {
|
||||||
|
GtbAnag currentAnagSelection = ragSoc.getValue();
|
||||||
|
if (text == null || text.isEmpty()) {
|
||||||
|
if (currentAnagSelection != null) {
|
||||||
|
this.ragSoc.postValue(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (currentAnagSelection != null) {
|
||||||
|
if (!text.equals(formatGtbAnagToString(currentAnagSelection))) {
|
||||||
|
this.ragSoc.postValue(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Quando la data del documento (dataDoc) cambia
|
||||||
|
this.dataDoc.observeForever(date -> {
|
||||||
|
Predicate<GtbAnag> newDatePredicate = null;
|
||||||
|
if (date != null) {
|
||||||
|
// TODO: Implementare la logica effettiva per creare un predicato GtbAnag basato sulla data.
|
||||||
|
// Poiché GtbAnag è un'anagrafica, questo filtro potrebbe non applicarsi direttamente
|
||||||
|
// ad essa, ma a una lista di transazioni/documenti che usano GtbAnag.
|
||||||
|
// Se 'dataDoc' NON deve filtrare la lista di GtbAnag, allora 'currentDataDocPredicate'
|
||||||
|
// dovrebbe essere gestito diversamente o non essere legato a questo 'dataDoc'.
|
||||||
|
// Per ora, l'effetto principale del reset di 'dataDoc' (impostandolo a null)
|
||||||
|
// sarà quello di impostare 'currentDataDocPredicate' a null.
|
||||||
|
// Esempio concettuale se GtbAnag avesse un campo data:
|
||||||
|
// newDatePredicate = gtbAnag -> UtilityDate.isSameDay(gtbAnag.getDataDocumento(), date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggiorna currentDataDocPredicate solo se il suo stato logico cambia
|
||||||
|
boolean predicateEffectivelyChanged = !Objects.equals(currentDataDocPredicate.getValue(), newDatePredicate) ||
|
||||||
|
(newDatePredicate == null && currentDataDocPredicate.getValue() != null) ||
|
||||||
|
(newDatePredicate != null && currentDataDocPredicate.getValue() == null);
|
||||||
|
|
||||||
|
if (predicateEffectivelyChanged) {
|
||||||
|
currentDataDocPredicate.postValue(newDatePredicate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.currentRagSocPredicate.observeForever(ragSocPredicate -> refreshList());
|
||||||
|
this.currentDataDocPredicate.observeForever(dataDocPredicate -> refreshList());
|
||||||
|
|
||||||
|
// Calcola availableRagSocsStrings inizialmente dopo che gli observer sono impostati
|
||||||
|
// e availableItems è disponibile.
|
||||||
|
if (this.availableItems != null) {
|
||||||
|
refreshList(); // Questo chiamerà anche calcAvailableRagSocsStrings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshList() {
|
||||||
|
Stream<GtbAnag> tmpStream;
|
||||||
|
if (availableItems == null) {
|
||||||
|
filteredItems.postValue(List.of());
|
||||||
|
availableRagSocsStrings.postValue(List.of());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate<GtbAnag> ragSocPred = currentRagSocPredicate.getValue();
|
||||||
|
Predicate<GtbAnag> dataDocPred = currentDataDocPredicate.getValue();
|
||||||
|
|
||||||
|
if (ragSocPred == null && dataDocPred == null) {
|
||||||
|
tmpStream = availableItems.stream();
|
||||||
|
} else {
|
||||||
|
tmpStream = availableItems.stream()
|
||||||
|
.filter(x -> (ragSocPred == null || ragSocPred.test(x)) &&
|
||||||
|
(dataDocPred == null || dataDocPred.test(x)));
|
||||||
|
}
|
||||||
|
filteredItems.postValue(tmpStream.collect(Collectors.toList()));
|
||||||
|
availableRagSocsStrings.postValue(calcAvailableRagSocsStrings());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> calcAvailableRagSocsStrings() {
|
||||||
|
if (availableItems == null) return List.of();
|
||||||
|
|
||||||
|
Predicate<GtbAnag> dataFilterPredicate = currentDataDocPredicate.getValue();
|
||||||
|
|
||||||
|
return availableItems.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
// Filtra la lista per l'adapter dell'AutoCompleteTextView solo per data,
|
||||||
|
// il filtro testuale lo fa l'adapter stesso.
|
||||||
|
.filter(x -> (dataFilterPredicate == null || dataFilterPredicate.test(x)))
|
||||||
|
.map(this::formatGtbAnagToString)
|
||||||
|
.distinct()
|
||||||
|
.sorted() // Opzionale: ordina alfabeticamente
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatGtbAnagToString(GtbAnag anag) {
|
||||||
|
if (anag == null) return "";
|
||||||
|
return anag.getCodAnag() + " - " + anag.getRagSoc();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GtbAnag findGtbAnagByFormattedString(String formattedString) {
|
||||||
|
if (formattedString == null || availableItems == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (GtbAnag anag : availableItems) {
|
||||||
|
if (anag != null && formattedString.equals(formatGtbAnagToString(anag))) {
|
||||||
|
return anag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getAvailableRagSocsStrings() {
|
||||||
|
return availableRagSocsStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<String> getRagSocTextBindable() {
|
||||||
|
return ragSocText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<GtbAnag> getRagSocBindable() {
|
||||||
|
return ragSoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<Date> getDataDocBindable() {
|
||||||
|
return dataDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DialogUltimeConsegneFiltroAvanzatoViewModel setRagSoc(GtbAnag ragSocItem) {
|
||||||
|
if (!Objects.equals(this.ragSoc.getValue(), ragSocItem)) {
|
||||||
|
this.ragSoc.postValue(ragSocItem);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DialogUltimeConsegneFiltroAvanzatoViewModel setDataDoc(Date dataDocItem) {
|
||||||
|
// L'observer su this.dataDoc gestirà l'aggiornamento di currentDataDocPredicate.
|
||||||
|
if (!Objects.equals(this.dataDoc.getValue(), dataDocItem)) {
|
||||||
|
this.dataDoc.postValue(dataDocItem);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resetta tutti i filtri ai loro stati predefiniti.
|
||||||
|
*/
|
||||||
|
public void resetFilters() {
|
||||||
|
// Impostando i LiveData a null, gli observer associati (in initBindable)
|
||||||
|
// si occuperanno di resettare i testi e i predicati.
|
||||||
|
setRagSoc(null);
|
||||||
|
setDataDoc(null); // Questo chiamerà l'observer di dataDoc che resetterà currentDataDocPredicate
|
||||||
|
|
||||||
|
// refreshList() sarà chiamato automaticamente dagli observer dei predicati.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,119 +1,189 @@
|
|||||||
package it.integry.integrywmsnative.ui.adapter;
|
package it.integry.integrywmsnative.ui.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Filter;
|
import android.widget.Filter;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.databinding.ObservableArrayList;
|
import androidx.databinding.ObservableArrayList;
|
||||||
import androidx.databinding.ObservableList;
|
import androidx.databinding.ObservableList;
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SimpleAutoCompleteDropdownAdapter<T> extends ArrayAdapter<T> {
|
public class SimpleAutoCompleteDropdownAdapter<T> extends ArrayAdapter<T> {
|
||||||
|
|
||||||
private final ObservableArrayList<T> objects;
|
private final List<T> originalItems = new ArrayList<>();
|
||||||
private final LayoutInflater mInflater;
|
private final Object originalItemsLock = new Object();
|
||||||
private int mDropDownResource;
|
|
||||||
|
|
||||||
public SimpleAutoCompleteDropdownAdapter(@NonNull Context context, int resource, @NonNull List<T> objects) {
|
/**
|
||||||
this(context, resource, new ObservableArrayList<>());
|
* Costruttore per una lista statica di oggetti.
|
||||||
this.objects.addAll(objects);
|
*
|
||||||
|
* @param context Il contesto corrente.
|
||||||
|
* @param resource La risorsa ID per una risorsa di layout contenente un TextView da popolare.
|
||||||
|
* @param staticObjects Gli oggetti da rappresentare nella ListView.
|
||||||
|
*/
|
||||||
|
public SimpleAutoCompleteDropdownAdapter(@NonNull Context context, int resource, @NonNull List<T> staticObjects) {
|
||||||
|
super(context, resource, new ArrayList<>(staticObjects)); // Usa una copia per la lista visualizzata
|
||||||
|
synchronized (originalItemsLock) {
|
||||||
|
this.originalItems.addAll(staticObjects); // Salva una copia per il filtraggio
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleAutoCompleteDropdownAdapter(@NonNull Context context, int resource, @NonNull ObservableArrayList<T> objects) {
|
/**
|
||||||
super(context, resource, new ArrayList<>(objects));
|
* Costruttore per una ObservableArrayList di oggetti.
|
||||||
mInflater = LayoutInflater.from(context);
|
* L'adapter si aggiornerà automaticamente quando la lista osservabile cambia.
|
||||||
mDropDownResource = resource;
|
*
|
||||||
this.objects = objects;
|
* @param context Il contesto corrente.
|
||||||
|
* @param resource La risorsa ID per una risorsa di layout contenente un TextView da popolare.
|
||||||
|
* @param observableList La ObservableArrayList di oggetti.
|
||||||
|
*/
|
||||||
|
public SimpleAutoCompleteDropdownAdapter(@NonNull Context context, int resource, @NonNull ObservableArrayList<T> observableList) {
|
||||||
|
super(context, resource, new ArrayList<>(observableList)); // Inizializza con lo stato corrente
|
||||||
|
synchronized (originalItemsLock) {
|
||||||
|
this.originalItems.addAll(observableList); // Salva lo stato corrente per il filtraggio
|
||||||
|
}
|
||||||
|
|
||||||
|
observableList.addOnListChangedCallback(new ObservableList.OnListChangedCallback<ObservableList<T>>() {
|
||||||
|
private void updateLists() {
|
||||||
|
// Si assume che observableList sia modificata sul thread UI o che la sincronizzazione sia gestita esternamente.
|
||||||
|
List<T> currentData = new ArrayList<>(observableList); // Crea uno snapshot
|
||||||
|
synchronized (originalItemsLock) {
|
||||||
|
originalItems.clear();
|
||||||
|
originalItems.addAll(currentData); // Aggiorna la lista originale per il filtraggio
|
||||||
|
}
|
||||||
|
// Aggiorna la lista visualizzata dall'adapter
|
||||||
|
clear();
|
||||||
|
addAll(currentData); // Usa lo snapshot
|
||||||
|
// notifyDataSetChanged(); // ArrayAdapter.addAll non chiama notifyDataSetChanged, quindi è necessario se non chiamato da clear()
|
||||||
|
// Tuttavia, clear() e addAll() di ArrayAdapter gestiscono la notifica se mNotifyOnChange è true (default).
|
||||||
|
// Per sicurezza e coerenza con il codice originale, lo manteniamo.
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
// Listener per aggiornare l'adapter quando la lista cambia
|
|
||||||
this.objects.addOnListChangedCallback(new ObservableList.OnListChangedCallback<ObservableList<T>>() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(ObservableList<T> sender) {
|
public void onChanged(ObservableList<T> sender) {
|
||||||
updateAdapter();
|
updateLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemRangeChanged(ObservableList<T> sender, int positionStart, int itemCount) {
|
public void onItemRangeChanged(ObservableList<T> sender, int positionStart, int itemCount) {
|
||||||
updateAdapter();
|
updateLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemRangeInserted(ObservableList<T> sender, int positionStart, int itemCount) {
|
public void onItemRangeInserted(ObservableList<T> sender, int positionStart, int itemCount) {
|
||||||
updateAdapter();
|
updateLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemRangeMoved(ObservableList<T> sender, int fromPosition, int toPosition, int itemCount) {
|
public void onItemRangeMoved(ObservableList<T> sender, int fromPosition, int toPosition, int itemCount) {
|
||||||
updateAdapter();
|
updateLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemRangeRemoved(ObservableList<T> sender, int positionStart, int itemCount) {
|
public void onItemRangeRemoved(ObservableList<T> sender, int positionStart, int itemCount) {
|
||||||
updateAdapter();
|
updateLists();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAdapter() {
|
/**
|
||||||
clear();
|
* Costruttore per LiveData contenente una lista di oggetti.
|
||||||
addAll(objects);
|
* L'adapter si aggiornerà automaticamente quando il LiveData emette una nuova lista.
|
||||||
notifyDataSetChanged();
|
*
|
||||||
|
* @param context Il contesto corrente.
|
||||||
|
* @param resource La risorsa ID per una risorsa di layout contenente un TextView da popolare.
|
||||||
|
* @param liveData Il LiveData che contiene la lista di oggetti.
|
||||||
|
* @param lifecycleOwner Il LifecycleOwner usato per osservare il LiveData.
|
||||||
|
*/
|
||||||
|
public SimpleAutoCompleteDropdownAdapter(@NonNull Context context, int resource,
|
||||||
|
@NonNull LiveData<List<T>> liveData,
|
||||||
|
@NonNull LifecycleOwner lifecycleOwner) {
|
||||||
|
super(context, resource, new ArrayList<>()); // Inizia vuoto, LiveData popolerà
|
||||||
|
|
||||||
|
liveData.observe(lifecycleOwner, newList -> {
|
||||||
|
// L'observer di LiveData viene eseguito sul thread UI
|
||||||
|
List<T> dataToUse = (newList == null) ? new ArrayList<>() : new ArrayList<>(newList);
|
||||||
|
synchronized (originalItemsLock) {
|
||||||
|
originalItems.clear();
|
||||||
|
originalItems.addAll(dataToUse); // Aggiorna la lista originale per il filtraggio
|
||||||
|
}
|
||||||
|
// Aggiorna la lista visualizzata dall'adapter
|
||||||
|
clear();
|
||||||
|
addAll(dataToUse); // addAll gestisce correttamente una collezione vuota se newList è null
|
||||||
|
// notifyDataSetChanged(); // Come sopra, gestito da clear/addAll se mNotifyOnChange è true. Mantenuto per coerenza.
|
||||||
|
notifyDataSetChanged();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Filter getFilter() {
|
public Filter getFilter() {
|
||||||
return new StringFilter(objects);
|
return new StringFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StringFilter extends Filter {
|
private class StringFilter extends Filter {
|
||||||
|
|
||||||
private final List<T> sourceObjects;
|
|
||||||
|
|
||||||
public StringFilter(List<T> objects) {
|
|
||||||
this.sourceObjects = objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FilterResults performFiltering(CharSequence chars) {
|
protected FilterResults performFiltering(CharSequence chars) {
|
||||||
String filterSeq = chars == null ? "" : chars.toString().toLowerCase();
|
String filterSeq = chars == null ? "" : chars.toString().toLowerCase();
|
||||||
FilterResults result = new FilterResults();
|
FilterResults result = new FilterResults();
|
||||||
|
List<T> itemsToFilter;
|
||||||
|
|
||||||
|
// Accedi alla lista originale in modo thread-safe
|
||||||
|
synchronized (originalItemsLock) {
|
||||||
|
itemsToFilter = new ArrayList<>(originalItems); // Usa una copia della lista originale
|
||||||
|
}
|
||||||
|
|
||||||
if (filterSeq.isEmpty()) {
|
if (filterSeq.isEmpty()) {
|
||||||
result.values = new ArrayList<>(sourceObjects);
|
result.values = itemsToFilter; // Restituisce tutti gli elementi originali
|
||||||
result.count = sourceObjects.size();
|
result.count = itemsToFilter.size();
|
||||||
} else {
|
} else {
|
||||||
ArrayList<T> filtered = new ArrayList<>();
|
ArrayList<T> filteredItems = new ArrayList<>();
|
||||||
for (T object : sourceObjects) {
|
for (T object : itemsToFilter) { // Filtra dalla lista originale completa
|
||||||
String stringObject = object.toString();
|
if (object != null) {
|
||||||
|
String stringObject = object.toString();
|
||||||
if (stringObject.toLowerCase().contains(filterSeq)) {
|
if (stringObject.toLowerCase().contains(filterSeq)) {
|
||||||
filtered.add(object);
|
filteredItems.add(object);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.values = filtered;
|
result.values = filteredItems;
|
||||||
result.count = filtered.size();
|
result.count = filteredItems.size();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
protected void publishResults(CharSequence constraint, @Nullable FilterResults results) {
|
||||||
List<T> filtered = (List<T>) results.values;
|
List<T> newValues = null;
|
||||||
if (filtered != null) {
|
if (results != null && results.values != null) {
|
||||||
synchronized (this) {
|
newValues = (List<T>) results.values;
|
||||||
clear();
|
}
|
||||||
addAll(filtered);
|
|
||||||
notifyDataSetChanged();
|
// Aggiorna la lista visualizzata dall'adapter (mObjects)
|
||||||
}
|
// Non modificare originalItems qui
|
||||||
|
SimpleAutoCompleteDropdownAdapter.this.clear();
|
||||||
|
if (newValues != null) {
|
||||||
|
SimpleAutoCompleteDropdownAdapter.this.addAll(newValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArrayAdapter.clear() e ArrayAdapter.addAll() dovrebbero chiamare notifyDataSetChanged()
|
||||||
|
// se mNotifyOnChange è true (default).
|
||||||
|
// Tuttavia, la logica originale usava una notifica esplicita, quindi la manteniamo.
|
||||||
|
if (results != null && results.count > 0) {
|
||||||
|
SimpleAutoCompleteDropdownAdapter.this.notifyDataSetChanged();
|
||||||
|
} else {
|
||||||
|
// Se non ci sono risultati o il filtro è vuoto e non ha prodotto risultati (improbabile con la logica sopra)
|
||||||
|
// notifyDataSetInvalidated indica che i dati non sono validi e la vista dovrebbe essere resettata.
|
||||||
|
// notifyDataSetChanged è generalmente sufficiente se la lista è semplicemente vuota.
|
||||||
|
SimpleAutoCompleteDropdownAdapter.this.notifyDataSetInvalidated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,65 +1,65 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<layout
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="view"
|
||||||
|
type="it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog.DialogUltimeConsegneFiltroAvanzatoView" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewmodel"
|
name="viewmodel"
|
||||||
type="it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog.DialogUltimeConsegneFiltroAvanzato.DialogUltimeConsegneFiltroAvanzatoViewModel" />
|
type="it.integry.integrywmsnative.gest.ultime_consegne_cliente.dialog.DialogUltimeConsegneFiltroAvanzatoViewModel" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:cardCornerRadius="12dp"
|
|
||||||
app:cardElevation="0dp">
|
|
||||||
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp">
|
android:paddingHorizontal="16dp"
|
||||||
|
android:paddingVertical="16dp">
|
||||||
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<TextView
|
||||||
android:id="@+id/title_text"
|
android:id="@+id/title_text"
|
||||||
|
style="@style/MaterialAlertDialog.Material3.Title.Text.CenterStacked"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/TextViewMaterial.Dialog.HeadlineText"
|
android:layout_marginBottom="16dp"
|
||||||
android:text="@string/dialog_vendita_filtro_avanzato"
|
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:layout_marginBottom="12dp"/>
|
android:text="@string/dialog_vendita_filtro_avanzato" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/input_cod_rag_soc"
|
android:id="@+id/input_cod_rag_soc"
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/rag_soc"
|
||||||
android:imeOptions="actionNext"
|
android:imeOptions="actionNext"
|
||||||
android:nextFocusDown="@id/input_data_doc"
|
android:nextFocusDown="@id/input_data_doc">
|
||||||
android:hint="@string/rag_soc">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatAutoCompleteTextView
|
<androidx.appcompat.widget.AppCompatAutoCompleteTextView
|
||||||
android:id="@+id/filled_exposed_dropdown_rag_soc"
|
android:id="@+id/filled_exposed_dropdown_rag_soc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:singleLine="true"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:imeOptions="actionNext"
|
android:imeOptions="actionNext"
|
||||||
android:nextFocusDown="@id/input_data_doc"
|
android:nextFocusDown="@id/input_data_doc"
|
||||||
app:binding="@{viewmodel.ragSoc}" />
|
android:singleLine="true"
|
||||||
|
android:text="@={viewmodel.ragSocTextBindable}" /> <!-- Binding bidirezionale -->
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
@@ -68,6 +68,7 @@
|
|||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
android:hint="@string/document_date">
|
android:hint="@string/document_date">
|
||||||
|
|
||||||
|
|
||||||
@@ -75,62 +76,25 @@
|
|||||||
android:id="@+id/filled_exposed_dropdown_data_doc"
|
android:id="@+id/filled_exposed_dropdown_data_doc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="textNoSuggestions"
|
|
||||||
android:focusable="false"
|
android:focusable="false"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
app:binding="@{viewmodel.dataDoc}"/>
|
android:textAppearance="?attr/textAppearanceSubtitle1"
|
||||||
|
android:minHeight="?attr/listPreferredItemHeightSmall"
|
||||||
|
app:binding="@{viewmodel.dataDocBindable}"
|
||||||
|
app:parentView="@{view}" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Button.PrimaryOutline"
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="24dp"
|
android:layout_gravity="center_horizontal"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginTop="12dp"
|
||||||
android:layout_marginTop="8dp">
|
android:text="@string/reset"
|
||||||
|
android:onClick="@{() -> view.reset()}"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
android:id="@+id/buttons_guideline"
|
</androidx.cardview.widget.CardView>
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_percent="0.5"/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/neutral_btn"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="@style/Button.PrimaryOutline"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/buttons_guideline"
|
|
||||||
app:strokeColor="?colorPrimary"
|
|
||||||
android:text="@string/reset"/>
|
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/positive_btn"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="@style/Button.PrimaryFull"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/buttons_guideline"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:text="@string/confirm"/>
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
</layout>
|
</layout>
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
<!-- <item name="android:textAllCaps">false</item>-->
|
<!-- <item name="android:textAllCaps">false</item>-->
|
||||||
<!-- <item name="android:paddingTop">8dp</item>-->
|
<!-- <item name="android:paddingTop">8dp</item>-->
|
||||||
<!-- <item name="android:paddingBottom">8dp</item>-->
|
<!-- <item name="android:paddingBottom">8dp</item>-->
|
||||||
<item name="iconTint">@color/colorPrimary</item>
|
<item name="iconTint">?colorPrimary</item>
|
||||||
<item name="strokeColor">@color/colorPrimary</item>
|
<item name="strokeColor">?colorPrimary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Button.PrimaryFull" parent="Widget.Material3.Button.UnelevatedButton">
|
<style name="Button.PrimaryFull" parent="Widget.Material3.Button.UnelevatedButton">
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<!-- <item name="android:textAllCaps">false</item>-->
|
<!-- <item name="android:textAllCaps">false</item>-->
|
||||||
<!-- <item name="android:paddingTop">8dp</item>-->
|
<!-- <item name="android:paddingTop">8dp</item>-->
|
||||||
<!-- <item name="android:paddingBottom">8dp</item>-->
|
<!-- <item name="android:paddingBottom">8dp</item>-->
|
||||||
<item name="backgroundTint">@color/colorPrimary</item>
|
<item name="backgroundTint">?colorPrimary</item>
|
||||||
<item name="iconTint">@android:color/white</item>
|
<item name="iconTint">@android:color/white</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,14 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<item name="bound_observable" type="id" />
|
<item name="bound_observable" type="id" />
|
||||||
|
<item name="bound_observable_date_listener" type="id" />
|
||||||
|
<item name="bound_observable_date_livedata" type="id" />
|
||||||
|
<item name="bound_observable_date_observer" type="id" />
|
||||||
<item name="bound_observable_visibility" type="id" />
|
<item name="bound_observable_visibility" type="id" />
|
||||||
<item name="bound_reverse_visibility" type="id" />
|
<item name="bound_reverse_visibility" type="id" />
|
||||||
|
<item name="bound_observable_actv_watcher" type="id" />
|
||||||
|
<item name="bound_observable_actv_livedata" type="id" />
|
||||||
|
<item name="bound_observable_actv_observer" type="id" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user