diff --git a/app/src/main/java/it/integry/integrywmsnative/core/settings/DBSettingsModel.java b/app/src/main/java/it/integry/integrywmsnative/core/settings/DBSettingsModel.java index 8cd5b303..79890c39 100644 --- a/app/src/main/java/it/integry/integrywmsnative/core/settings/DBSettingsModel.java +++ b/app/src/main/java/it/integry/integrywmsnative/core/settings/DBSettingsModel.java @@ -102,6 +102,7 @@ public class DBSettingsModel { private boolean flagProduzioneSkipAskVersamentoAutomatico; private boolean flagAccettazioneViewLotto = false; private boolean flagSpedizioneUnderflowQuantityWarning = false; + private boolean flagAccettazioneBollaMarkReceived = false; public boolean isFlagSpedizioneEnableFakeGiacenza() { return flagSpedizioneEnableFakeGiacenza; @@ -863,4 +864,13 @@ public class DBSettingsModel { this.flagSpedizioneUnderflowQuantityWarning = flagSpedizioneUnderflowQuantityWarning; return this; } + + public boolean isFlagAccettazioneBollaMarkReceived() { + return flagAccettazioneBollaMarkReceived; + } + + public DBSettingsModel setFlagAccettazioneBollaMarkReceived(boolean flagAccettazioneBollaMarkReceived) { + this.flagAccettazioneBollaMarkReceived = flagAccettazioneBollaMarkReceived; + return this; + } } diff --git a/app/src/main/java/it/integry/integrywmsnative/core/settings/SettingsManager.java b/app/src/main/java/it/integry/integrywmsnative/core/settings/SettingsManager.java index 2976c32e..ccfd5067 100644 --- a/app/src/main/java/it/integry/integrywmsnative/core/settings/SettingsManager.java +++ b/app/src/main/java/it/integry/integrywmsnative/core/settings/SettingsManager.java @@ -490,6 +490,12 @@ public class SettingsManager { .setKeySection("FLAG_ASK_PRINT_UL") .setSetter(dbSettingsModelIstance::setFlagAccettazioneBollaAskPrintUl) .setDefaultValue(false)); + stbGestSetupReaderList.add(new StbGestSetupReader<>(Boolean.class) + .setGestName("PICKING") + .setSection("ACCETTAZIONE_BOLLA") + .setKeySection("FLAG_ENABLE_MARK_RECEIVED") + .setSetter(dbSettingsModelIstance::setFlagAccettazioneBollaMarkReceived) + .setDefaultValue(false)); stbGestSetupReaderList.add(new StbGestSetupReader<>(Boolean.class) .setGestName("PICKING") .setSection("ACCETTAZIONE_BOLLA") diff --git a/app/src/main/java/it/integry/integrywmsnative/core/update/UpdatesManager.java b/app/src/main/java/it/integry/integrywmsnative/core/update/UpdatesManager.java index fb7938d1..75c6f1c8 100644 --- a/app/src/main/java/it/integry/integrywmsnative/core/update/UpdatesManager.java +++ b/app/src/main/java/it/integry/integrywmsnative/core/update/UpdatesManager.java @@ -7,18 +7,22 @@ import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.Handler; +import android.text.Html; +import android.util.Log; -import androidx.fragment.app.FragmentActivity; +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; import androidx.preference.PreferenceManager; +import com.google.firebase.crashlytics.FirebaseCrashlytics; + import java.io.File; -import java.util.Objects; import java.util.concurrent.ExecutorService; import javax.inject.Singleton; import it.integry.integrywmsnative.BuildConfig; -import it.integry.integrywmsnative.core.helper.ContextHelper; +import it.integry.integrywmsnative.MainApplication; import it.integry.integrywmsnative.core.rest.consumers.SystemRESTConsumer; import it.integry.integrywmsnative.core.rest.model.system.LatestAppVersionInfoDTO; import it.integry.integrywmsnative.core.settings.SettingsManager; @@ -26,11 +30,14 @@ import it.integry.integrywmsnative.core.utility.FileDownloader; import it.integry.integrywmsnative.core.utility.UtilityExceptions; import it.integry.integrywmsnative.gest.settings.MainSettingsFragment; import it.integry.integrywmsnative.view.dialogs.DialogProgressView; +import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView; import it.integry.integrywmsnative.view.dialogs.update_available.DialogUpdateAvailableView; @Singleton public class UpdatesManager { + private static final String TAG = "UpdatesManager"; + private final ExecutorService executorService; private final Handler handler; private final SystemRESTConsumer systemRESTConsumer; @@ -41,109 +48,145 @@ public class UpdatesManager { this.systemRESTConsumer = systemRESTConsumer; } - public void executeCheck(Context context, boolean forceReinstall) { - + public void executeCheck(@NonNull Context context, @NonNull FragmentManager fragmentManager, boolean forceReinstall) { executorService.execute(() -> { - try { - final String baseEndpoint = SettingsManager.i().getServer().getProtocol() + "://" + SettingsManager.i().getServer().getHost() + - (SettingsManager.i().getServer().getPort() > 0 ? ":" + SettingsManager.i().getServer().getPort() : "") + "/ems-api/"; - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); - var betaEnabled = sharedPreferences.getBoolean(MainSettingsFragment.KEY_BUTTON_ENABLE_BETA, false); + boolean betaEnabled = sharedPreferences.getBoolean(MainSettingsFragment.KEY_BUTTON_ENABLE_BETA, false); LatestAppVersionInfoDTO latestData = systemRESTConsumer.retrieveUpdatesInfoSynchronized(betaEnabled); - if (latestData == null) + if (latestData == null) { + Log.d(TAG, "No update information received from server."); return; + } - if (latestData.getLatestVersionCode() < BuildConfig.VERSION_CODE) + + boolean isUpdateRequired = latestData.getLatestVersionCode() > BuildConfig.VERSION_CODE; + boolean currentVersionIsBeta = BuildConfig.VERSION_NAME.toLowerCase().contains("beta"); + boolean isChannelSwitch = currentVersionIsBeta != betaEnabled; + + if (!isUpdateRequired && !forceReinstall && !isChannelSwitch) { + Log.d(TAG, "App is up to date."); return; + } - boolean currentVersionIsBeta = BuildConfig.VERSION_NAME.contains("beta"); - - if(!forceReinstall && currentVersionIsBeta == betaEnabled && latestData.getLatestVersionCode() == BuildConfig.VERSION_CODE) - return; - - //Se sto passando da una beta a una stable e viceversa non obbligo l'utente a fare l'aggiornamento - if(currentVersionIsBeta != betaEnabled || forceReinstall) { + // Se si passa da beta a stabile (o viceversa) o se è una reinstallazione forzata, + // l'aggiornamento non deve essere obbligatorio per non bloccare l'utente. + if (isChannelSwitch || forceReinstall) { latestData.setForced(false); } - String currentDownloadUrl = baseEndpoint + latestData.getUrl(); + final String baseEndpoint = SettingsManager.i().getServer().getProtocol() + "://" + SettingsManager.i().getServer().getHost() + + (SettingsManager.i().getServer().getPort() > 0 ? ":" + SettingsManager.i().getServer().getPort() : "") + "/ems-api/"; + String downloadUrl = baseEndpoint + latestData.getUrl(); - showDialog(context, latestData, () -> { - installAPK(context, currentDownloadUrl); - }); + handler.post(() -> showUpdateAvailableDialog(context, fragmentManager, latestData, downloadUrl)); } catch (Exception e) { - handler.post(() -> { - UtilityExceptions.defaultException(context, e); - }); + Log.e(TAG, "Error during update check", e); + // Se il check fallisce, non è un errore bloccante. L'utente può continuare a usare l'app. } }); } - private void showDialog(Context context, LatestAppVersionInfoDTO updatesData, Runnable onUpdateStart) { - DialogUpdateAvailableView.newInstance(updatesData, onUpdateStart) - .show(((FragmentActivity)context).getSupportFragmentManager(), "dialog-updates"); + private void showUpdateAvailableDialog(@NonNull Context context, @NonNull FragmentManager fragmentManager, @NonNull LatestAppVersionInfoDTO updatesData, @NonNull String downloadUrl) { + DialogUpdateAvailableView dialog = DialogUpdateAvailableView.newInstance(updatesData, () -> { + // L'utente ha accettato di aggiornare + downloadAndInstall(context, fragmentManager, downloadUrl, updatesData.isForced()); + }); + + if (updatesData.isForced()) { + dialog.setCancelable(false); + } + + dialog.show(fragmentManager, "dialog-updates"); } - private void installAPK(Context context, String downloadURL) { - - File destination = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); - - var progressDialogBuilder = new DialogProgressView("Download", null, false); - progressDialogBuilder.show(Objects.requireNonNull(ContextHelper.getFragmentManagerFromContext(context)), "tag"); - - - var fileDownloader = new FileDownloader() - .setDestFolder(destination) - .setUrlString(downloadURL) - .setOnProgressUpdate(progress -> { - handler.post(() -> { - progressDialogBuilder.setProgress(progress); - }); - }) - .setOnDownloadCompleted(destPath -> { - - handler.post(() -> { - progressDialogBuilder.dismiss(); - - if (!destination.exists()) { - UtilityExceptions.defaultException(context, new Exception("Errore durante il download dell'aggiornamento")); - return; - } - - Uri fileLoc; - Intent intent; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); - fileLoc = GenericFileProvider.getUriForFile(context, - context.getApplicationContext().getPackageName() + ".core.update.GenericFileProvider", - destPath); - } else { - intent = new Intent(Intent.ACTION_VIEW); - fileLoc = Uri.fromFile(destPath); - } - - intent.setDataAndType(fileLoc, "application/vnd.android.package-archive"); - intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - - context.startActivity(intent); - }); - - }); + private void downloadAndInstall(@NonNull Context context, @NonNull FragmentManager fragmentManager, @NonNull String downloadUrl, boolean isForced) { + DialogProgressView progressDialog = new DialogProgressView("Download", null, false); + if (isForced) { + progressDialog.setCancelable(false); + } + progressDialog.show(fragmentManager, "progress-dialog"); + FileDownloader fileDownloader = new FileDownloader() + .setExecutorService(executorService) + .setDestFolder(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)) + .setUrlString(downloadUrl) + .setOnProgressUpdate(progress -> handler.post(() -> progressDialog.setProgress(progress))); executorService.execute(() -> { try { - fileDownloader.download(); + File apkFile = fileDownloader.download(); + handler.post(() -> { + progressDialog.dismiss(); + installApk(context, apkFile, isForced); + }); } catch (Exception e) { - progressDialogBuilder.dismiss(); - UtilityExceptions.defaultException(context, e); + Log.e(TAG, "Download failed", e); + handler.post(() -> { + progressDialog.dismissAllowingStateLoss(); + handleUpdateError(context, e, isForced); + }); } }); } + + private void installApk(@NonNull Context context, @NonNull File apkFile, boolean isForced) { + if (!apkFile.exists()) { + handleUpdateError(context, new Exception("File APK non trovato dopo il download."), isForced); + return; + } + + Uri fileUri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + fileUri = GenericFileProvider.getUriForFile(context, + context.getApplicationContext().getPackageName() + ".core.update.GenericFileProvider", + apkFile); + } else { + fileUri = Uri.fromFile(apkFile); + } + + Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); + intent.setDataAndType(fileUri, "application/vnd.android.package-archive"); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + context.startActivity(intent); + // Se l'aggiornamento è forzato, l'app si chiuderà per attendere l'installazione manuale. + if (isForced) { + // Diamo tempo all'utente di vedere l'installer di sistema prima di chiudere l'app. + handler.postDelayed(MainApplication::exit, 1000); + } + } catch (Exception e) { + Log.e(TAG, "Failed to start APK installation", e); + handleUpdateError(context, e, isForced); + } + } + + private void handleUpdateError(@NonNull Context context, @NonNull Exception ex, boolean isForced) { + FirebaseCrashlytics.getInstance().recordException(ex); + String errorMessage = UtilityExceptions.recognizeExceptionMessage(ex); + + handler.post(() -> { + String title = isForced ? "Aggiornamento Obbligatorio Fallito" : "Errore Aggiornamento"; + Runnable onPositiveClick = null; + if (isForced) { + onPositiveClick = MainApplication::exit; + } + + DialogSimpleMessageView dialog = DialogSimpleMessageView.makeErrorDialog(context, + Html.fromHtml(errorMessage), + null, + onPositiveClick); + + if (isForced) { + dialog.setCancelable(false); + } + + dialog.show(); + }); + } } + diff --git a/app/src/main/java/it/integry/integrywmsnative/core/utility/FileDownloader.java b/app/src/main/java/it/integry/integrywmsnative/core/utility/FileDownloader.java index fd9fc64e..8dda94dc 100644 --- a/app/src/main/java/it/integry/integrywmsnative/core/utility/FileDownloader.java +++ b/app/src/main/java/it/integry/integrywmsnative/core/utility/FileDownloader.java @@ -9,6 +9,9 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicReference; import it.integry.integrywmsnative.core.expansion.RunnableArgs; @@ -18,68 +21,87 @@ public class FileDownloader { private File destFolder; private RunnableArgs onProgressUpdate; - private RunnableArgs onDownloadCompleted; + private ExecutorService executorService; - public void download() throws Exception { - InputStream input = null; - OutputStream output = null; - HttpURLConnection connection = null; - File downloadFile = null; + public File download() throws Exception { + CountDownLatch countDownLatch = new CountDownLatch(1); - try { - if (!destFolder.exists()) destFolder.mkdirs(); + AtomicReference result = new AtomicReference<>(); + AtomicReference exceptionAtomicReference = new AtomicReference<>(); - URL url = new URL(urlString); - connection = (HttpURLConnection) url.openConnection(); - connection.connect(); - connection.setConnectTimeout(120 * 1000); + executorService.execute(() -> { + InputStream input = null; + OutputStream output = null; + HttpURLConnection connection = null; + File downloadFile = null; - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) - throw new Exception("Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage()); - - input = connection.getInputStream(); - int totalBytesToDownload = connection.getContentLength(); - int downloadedBytes = 0; - - String title = URLUtil.guessFileName(String.valueOf(url), null, null); - downloadFile = new File(destFolder, title); - - if (downloadFile.exists()) - downloadFile.delete(); - - output = new FileOutputStream(downloadFile); - - byte[] buf = new byte[1024]; - int len; - while ((len = input.read(buf)) > 0) { - output.write(buf, 0, len); - - downloadedBytes += len; - if (onProgressUpdate != null) - onProgressUpdate.run((downloadedBytes * 100) / totalBytesToDownload); - } - - } catch (Exception e) { - if(downloadFile != null && downloadFile.exists()) - downloadFile.delete(); - throw e; - - } finally { try { - if (output != null) - output.close(); - if (input != null) - input.close(); - } catch (IOException ignored) { - } - if (connection != null) - connection.disconnect(); - } + if (!destFolder.exists()) destFolder.mkdirs(); - if (onDownloadCompleted != null) onDownloadCompleted.run(downloadFile); + URL url = new URL(urlString); + connection = (HttpURLConnection) url.openConnection(); + connection.connect(); + connection.setConnectTimeout(120 * 1000); + + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) + throw new Exception("Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage()); + + input = connection.getInputStream(); + int totalBytesToDownload = connection.getContentLength(); + int downloadedBytes = 0; + + String title = URLUtil.guessFileName(String.valueOf(url), null, null); + downloadFile = new File(destFolder, title); + + if (downloadFile.exists()) + downloadFile.delete(); + + output = new FileOutputStream(downloadFile); + + byte[] buf = new byte[1024]; + int len; + while ((len = input.read(buf)) > 0) { + output.write(buf, 0, len); + + downloadedBytes += len; + if (onProgressUpdate != null) + onProgressUpdate.run((downloadedBytes * 100) / totalBytesToDownload); + } + + result.set(downloadFile); + } catch (Exception e) { + if(downloadFile != null && downloadFile.exists()) + downloadFile.delete(); + exceptionAtomicReference.set(e); + + } finally { + try { + if (output != null) + output.close(); + if (input != null) + input.close(); + } catch (IOException ignored) { + } + if (connection != null) + connection.disconnect(); + + countDownLatch.countDown(); + } + }); + + countDownLatch.await(); + + if(exceptionAtomicReference.get() != null) + throw exceptionAtomicReference.get(); + + return result.get(); } + public FileDownloader setExecutorService(ExecutorService executorService) { + this.executorService = executorService; + return this; + } public String getUrlString() { return urlString; @@ -103,9 +125,4 @@ public class FileDownloader { this.onProgressUpdate = onProgressUpdate; return this; } - - public FileDownloader setOnDownloadCompleted(RunnableArgs onDownloadCompleted) { - this.onDownloadCompleted = onDownloadCompleted; - return this; - } } diff --git a/app/src/main/java/it/integry/integrywmsnative/core/utility/UtilityExceptions.java b/app/src/main/java/it/integry/integrywmsnative/core/utility/UtilityExceptions.java index 8c9c3ac0..1ef566b2 100644 --- a/app/src/main/java/it/integry/integrywmsnative/core/utility/UtilityExceptions.java +++ b/app/src/main/java/it/integry/integrywmsnative/core/utility/UtilityExceptions.java @@ -40,13 +40,7 @@ public class UtilityExceptions { Logger.e(ex, "Errore", (Object) ex.getStackTrace()); } - String errorMessage = CommonRESTException.tryRecognizeThenGetMessage(ex); - - if (errorMessage == null) { - errorMessage = ex.getMessage(); - - if (ex.getCause() != null) errorMessage += "
" + ex.getCause().getMessage(); - } + String errorMessage = recognizeExceptionMessage(ex); // FragmentManager fm = ContextHelper.getFragmentManagerFromContext(context); @@ -75,4 +69,15 @@ public class UtilityExceptions { } } + public static String recognizeExceptionMessage(Exception ex) { + String errorMessage = CommonRESTException.tryRecognizeThenGetMessage(ex); + + if (errorMessage == null) { + errorMessage = ex.getMessage(); + + if (ex.getCause() != null) errorMessage += "
" + ex.getCause().getMessage(); + } + return errorMessage; + } + } diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/MainAccettazioneBollaElencoFragment.java b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/MainAccettazioneBollaElencoFragment.java index 187a9895..bdebc521 100644 --- a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/MainAccettazioneBollaElencoFragment.java +++ b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/MainAccettazioneBollaElencoFragment.java @@ -2,12 +2,17 @@ package it.integry.integrywmsnative.gest.accettazione_bolla_elenco; import android.content.Context; import android.os.Bundle; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatTextView; +import androidx.appcompat.widget.PopupMenu; +import androidx.databinding.BindingAdapter; import androidx.databinding.ObservableArrayList; import com.annimon.stream.Stream; @@ -48,6 +53,9 @@ public class MainAccettazioneBollaElencoFragment extends BaseFragment implements private AppCompatTextView mAppBarTitle; public BindableBoolean fabVisible = new BindableBoolean(false); + public BindableBoolean fabMenuVisible = new BindableBoolean(false); + + private PopupMenu fabPopupMenu; private String mTextFilter; @@ -100,6 +108,9 @@ public class MainAccettazioneBollaElencoFragment extends BaseFragment implements this.initRecyclerView(); + if (SettingsManager.iDB().isFlagAccettazioneBollaMarkReceived()) + this.initFab(); + mToolbar.setRecyclerView(mBinding.accettazioneMainList); return mBinding.getRoot(); @@ -111,6 +122,7 @@ public class MainAccettazioneBollaElencoFragment extends BaseFragment implements super.onStart(); this.fabVisible.set(false); + this.fabMenuVisible.set(false); mViewModel.init(); } @@ -147,8 +159,11 @@ public class MainAccettazioneBollaElencoFragment extends BaseFragment implements .filter(y -> !y.getGroupTitle().equalsIgnoreCase(x.getGroupTitle()) && y.getSelectedObservable().get()) .forEach(y -> y.getSelectedObservable().set(false)); - fabVisible.set(Stream.of(mBolleInevaseMutableData) - .anyMatch(y -> y.getSelectedObservable().get())); + boolean rowSelected = Stream.of(mBolleInevaseMutableData) + .anyMatch(y -> y.getSelectedObservable().get()); + + fabVisible.set(rowSelected && !SettingsManager.iDB().isFlagAccettazioneBollaMarkReceived()); + fabMenuVisible.set(rowSelected && SettingsManager.iDB().isFlagAccettazioneBollaMarkReceived()); }); adapter.setEmptyView(this.mBinding.bolleAccettazioneEmptyView); @@ -159,6 +174,28 @@ public class MainAccettazioneBollaElencoFragment extends BaseFragment implements mToolbar.setRecyclerView(this.mBinding.accettazioneMainList); } + private void initFab() { + fabPopupMenu = new PopupMenu(requireContext(), this.mBinding.accettazioneBollaFab, + (Gravity.END | Gravity.BOTTOM), + androidx.appcompat.R.attr.popupMenuStyle, + com.google.android.material.R.style.Widget_Material3_PopupMenu_ContextMenu); + + fabPopupMenu.setForceShowIcon(true); + fabPopupMenu.getMenuInflater().inflate(R.menu.accettazione_bolla_fab_menu, fabPopupMenu.getMenu()); + + fabPopupMenu.setOnMenuItemClickListener(item -> { + int itemId = item.getItemId(); + + if (itemId == R.id.open_document) { + this.dispatchBolle(); + } else if (itemId == R.id.mark_document_received) { + this.setBolleReceived(); + } + + return false; + }); + } + private void refreshList() { List tmpList = mViewModel.getBolleList().getValue(); @@ -223,14 +260,23 @@ public class MainAccettazioneBollaElencoFragment extends BaseFragment implements }).toList(); } + public void openFabMenu() { + fabPopupMenu.show(); + } + + private void setBolleReceived() { + this.mViewModel.markDocumentReceived(getSelectedBolle()); + } public void dispatchBolle() { - List selectedBolle = Stream.of(this.mBolleInevaseMutableData) + this.mViewModel.loadPicking(getSelectedBolle()); + } + + private List getSelectedBolle() { + return Stream.of(this.mBolleInevaseMutableData) .filter(x -> x.getSelectedObservable().get()) .map(MainAccettazioneBolleElencoListModel::getOriginalModel) .toList(); - - this.mViewModel.loadPicking(selectedBolle); } @Override diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/MainAccettazioneBollaElencoViewModel.java b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/MainAccettazioneBollaElencoViewModel.java index 868b2c32..f4d843f7 100644 --- a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/MainAccettazioneBollaElencoViewModel.java +++ b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/MainAccettazioneBollaElencoViewModel.java @@ -1,12 +1,15 @@ package it.integry.integrywmsnative.gest.accettazione_bolla_elenco; +import androidx.databinding.ObservableInt; import androidx.lifecycle.MutableLiveData; import java.util.List; import javax.inject.Inject; +import it.integry.integrywmsnative.R; import it.integry.integrywmsnative.core.interfaces.viewmodel_listeners.ILoadingListener; +import it.integry.integrywmsnative.core.settings.SettingsManager; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.BolleAccettazioneRESTConsumer; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.SitBollaAccettazioneDTO; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.TestataBollaAccettazioneDTO; @@ -34,14 +37,10 @@ public class MainAccettazioneBollaElencoViewModel { }, this::sendError); } - public MutableLiveData> getBolleList() { return bolleList; } - - - public void loadPicking(List selectedBolle) { this.sendOnLoadingStarted(); @@ -53,21 +52,10 @@ public class MainAccettazioneBollaElencoViewModel { }, this::sendError); } - - - - - - - - - - - - - - - + public void markDocumentReceived(List selectedBolle) { + this.sendOnLoadingStarted(); + this.bolleAccettazioneRESTConsumer.markDocumentReceived(selectedBolle, this::sendOnLoadingEnded, this::sendError); + } public MainAccettazioneBollaElencoViewModel setListener(MainAccettazioneBollaElencoViewModel.Listener listener) { this.listener = listener; @@ -87,10 +75,9 @@ public class MainAccettazioneBollaElencoViewModel { } private void sendOnPickingReady(List bolle, List sitArts) { - if(this.listener != null) listener.onPickingReady(bolle, sitArts); + if (this.listener != null) listener.onPickingReady(bolle, sitArts); } - public interface Listener extends ILoadingListener { void onError(Exception ex); diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/BolleAccettazioneRESTConsumer.java b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/BolleAccettazioneRESTConsumer.java index a5f388ac..146c1e4b 100644 --- a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/BolleAccettazioneRESTConsumer.java +++ b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/BolleAccettazioneRESTConsumer.java @@ -9,9 +9,12 @@ import javax.inject.Singleton; import it.integry.integrywmsnative.core.expansion.RunnableArgs; import it.integry.integrywmsnative.core.rest.RESTBuilder; +import it.integry.integrywmsnative.core.rest.consumers.GiacenzaPvRESTConsumerService; import it.integry.integrywmsnative.core.rest.consumers._BaseRESTConsumer; import it.integry.integrywmsnative.core.rest.handler.ManagedErrorCallback; import it.integry.integrywmsnative.core.rest.model.ServiceRESTResponse; +import it.integry.integrywmsnative.core.rest.model.pv.SaveNewRowVerificaRequestDTO; +import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.MarkDocumentReceivedRequestDTO; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.RetrieveElencoArticoliAccettazioneBollaRequestDTO; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.RetrieveElencoArticoliAccettazioneBollaResponseDTO; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.RetrieveElencoBolleAccettazioneResponseDTO; @@ -65,4 +68,19 @@ public class BolleAccettazioneRESTConsumer extends _BaseRESTConsumer { }); } + public void markDocumentReceived(List bolle, Runnable onComplete, RunnableArgs onFailed) { + BolleAccettazioneRESTConsumerService service = restBuilder.getService(BolleAccettazioneRESTConsumerService.class); + service.markDocumentReceived(new MarkDocumentReceivedRequestDTO().setBolle(bolle)) + .enqueue(new ManagedErrorCallback<>() { + @Override + public void onResponse(Call> call, Response> response) { + analyzeAnswer(response, "markDocumentReceived", m -> onComplete.run(), onFailed); + } + + @Override + public void onFailure(Call> call, @NonNull final Exception e) { + onFailed.run(e); + } + }); + } } diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/BolleAccettazioneRESTConsumerService.java b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/BolleAccettazioneRESTConsumerService.java index ae71bc6f..57f0add3 100644 --- a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/BolleAccettazioneRESTConsumerService.java +++ b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/BolleAccettazioneRESTConsumerService.java @@ -1,6 +1,7 @@ package it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest; import it.integry.integrywmsnative.core.rest.model.ServiceRESTResponse; +import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.MarkDocumentReceivedRequestDTO; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.RetrieveElencoArticoliAccettazioneBollaRequestDTO; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.RetrieveElencoArticoliAccettazioneBollaResponseDTO; import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.RetrieveElencoBolleAccettazioneResponseDTO; @@ -17,4 +18,6 @@ public interface BolleAccettazioneRESTConsumerService { @POST("wms/accettazione-bolla/retrievePickingList") Call> retrievePickingListBolle(@Body RetrieveElencoArticoliAccettazioneBollaRequestDTO retrieveElencoArticoliAccettazioneBollaReques); + @POST("wms/accettazione-bolla/markDocumentReceived") + Call> markDocumentReceived(@Body MarkDocumentReceivedRequestDTO request); } diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/dto/MarkDocumentReceivedRequestDTO.java b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/dto/MarkDocumentReceivedRequestDTO.java new file mode 100644 index 00000000..70148eda --- /dev/null +++ b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_bolla_elenco/rest/dto/MarkDocumentReceivedRequestDTO.java @@ -0,0 +1,17 @@ +package it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto; + +import java.util.List; + +public class MarkDocumentReceivedRequestDTO { + + private List bolle; + + public List getBolle() { + return bolle; + } + + public MarkDocumentReceivedRequestDTO setBolle(List bolle) { + this.bolle = bolle; + return this; + } +} diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_ordini_picking/AccettazioneOrdiniPickingActivity.java b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_ordini_picking/AccettazioneOrdiniPickingActivity.java index dc5ef4ad..c1d5322e 100644 --- a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_ordini_picking/AccettazioneOrdiniPickingActivity.java +++ b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_ordini_picking/AccettazioneOrdiniPickingActivity.java @@ -19,6 +19,7 @@ import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.LinearLayoutManager; import com.annimon.stream.Stream; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; import java.math.BigDecimal; @@ -689,10 +690,15 @@ public class AccettazioneOrdiniPickingActivity extends BaseActivity implements A } private void showOrderByDialog() { - AlertDialog dialog = new AlertDialog.Builder(this).setTitle(this.getText(R.string.action_orderBy)).setSingleChoiceItems(AccettazioneOrdineInevasoOrderBy.descriptions, mCurrentOrderBy.getVal(), (dialog12, which) -> { - mCurrentOrderBy = AccettazioneOrdineInevasoOrderBy.Enum.fromInt(which); - SettingsManager.i().getUserSession().setDefaultOrdinamentoPickingAccettazione(which); - }).setPositiveButton(getText(R.string.ok), (dialog1, which) -> this.refreshList()).create(); + MaterialAlertDialogBuilder dialog = new MaterialAlertDialogBuilder(this) + .setTitle(this.getText(R.string.action_orderBy)) + .setSingleChoiceItems(AccettazioneOrdineInevasoOrderBy.descriptions, mCurrentOrderBy.getVal(), + (dialog12, which) -> { + mCurrentOrderBy = AccettazioneOrdineInevasoOrderBy.Enum.fromInt(which); + SettingsManager.i().getUserSession().setDefaultOrdinamentoPickingAccettazione(which); + }) + .setPositiveButton(getText(R.string.ok), (dialog1, which) -> this.refreshList()); + dialog.show(); } diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_ordini_picking/ui/AccettazioneOrdiniPickingListAdapter.java b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_ordini_picking/ui/AccettazioneOrdiniPickingListAdapter.java index 4ec1481a..c022884f 100644 --- a/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_ordini_picking/ui/AccettazioneOrdiniPickingListAdapter.java +++ b/app/src/main/java/it/integry/integrywmsnative/gest/accettazione_ordini_picking/ui/AccettazioneOrdiniPickingListAdapter.java @@ -22,6 +22,7 @@ import it.integry.integrywmsnative.R; import it.integry.integrywmsnative.core.expansion.OnListGeneralChangedCallback; import it.integry.integrywmsnative.core.expansion.RunnableArgs; import it.integry.integrywmsnative.core.utility.UtilityNumber; +import it.integry.integrywmsnative.core.utility.UtilityResources; import it.integry.integrywmsnative.core.utility.UtilityString; import it.integry.integrywmsnative.databinding.AccettazioneOrdineInevasoMainListGroupHeaderBinding; import it.integry.integrywmsnative.databinding.AccettazioneOrdineInevasoMainListGroupItemBinding; @@ -112,9 +113,9 @@ public class AccettazioneOrdiniPickingListAdapter extends SectionedRecyclerViewA } else if (pickingObjectDTO.getQtaEvasa().floatValue() > 0) { holder.mBinding.getRoot().setBackgroundColor(mContext.getResources().getColor(R.color.orange_600_with_alpha)); } else if (position % 2 == 1) { - holder.mBinding.getRoot().setBackgroundColor(Color.WHITE); + holder.mBinding.getRoot().setBackgroundColor(0); } else { - holder.mBinding.getRoot().setBackgroundColor(mContext.getResources().getColor(R.color.letturaFacilitataBGLight)); + holder.mBinding.getRoot().setBackgroundColor(UtilityResources.getColorResourceFromAttr(mContext, R.attr.colorLetturaFacilitataSurface)); } holder.mBinding.deactivatedOverBg.setVisibility(!pickingObjectDTO.isActive() ? View.VISIBLE : View.GONE); diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/main/MainActivity.java b/app/src/main/java/it/integry/integrywmsnative/gest/main/MainActivity.java index a1dbee92..b2d1a33d 100644 --- a/app/src/main/java/it/integry/integrywmsnative/gest/main/MainActivity.java +++ b/app/src/main/java/it/integry/integrywmsnative/gest/main/MainActivity.java @@ -93,7 +93,7 @@ public class MainActivity extends BaseActivity mBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.activity_main, null, false); setContentView(mBinding.getRoot()); - updatesManager.executeCheck(this, false); + updatesManager.executeCheck(this, getSupportFragmentManager(), false); UtilityContext.initMainActivity(this); setSupportActionBar(mBinding.appBarMain.toolbar); diff --git a/app/src/main/java/it/integry/integrywmsnative/gest/settings/MainSettingsFragment.java b/app/src/main/java/it/integry/integrywmsnative/gest/settings/MainSettingsFragment.java index cd77a341..8ac0bbc4 100644 --- a/app/src/main/java/it/integry/integrywmsnative/gest/settings/MainSettingsFragment.java +++ b/app/src/main/java/it/integry/integrywmsnative/gest/settings/MainSettingsFragment.java @@ -324,7 +324,7 @@ public class MainSettingsFragment extends PreferenceFragmentCompat implements IT private void checkUpdates() { Snackbar.make(getView(), R.string.checking_updates, Snackbar.LENGTH_SHORT) .show(); - updatesManager.executeCheck(getContext(), true); + updatesManager.executeCheck(getContext(), getParentFragmentManager(), true); } diff --git a/app/src/main/res/drawable/ic_filter_list_24dp_black.xml b/app/src/main/res/drawable/ic_filter_list_24dp_black.xml index 2d5ef68e..bb18d6b4 100644 --- a/app/src/main/res/drawable/ic_filter_list_24dp_black.xml +++ b/app/src/main/res/drawable/ic_filter_list_24dp_black.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/layout/accettazione_main_list_group_model.xml b/app/src/main/res/layout/accettazione_main_list_group_model.xml index 86fa7298..4842a293 100644 --- a/app/src/main/res/layout/accettazione_main_list_group_model.xml +++ b/app/src/main/res/layout/accettazione_main_list_group_model.xml @@ -35,7 +35,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" tools:text="Ord. Prod. 39 del 27 ott 2017" - android:textColor="#000" style="@style/TextAppearance.Material3.BodyMedium"/> diff --git a/app/src/main/res/layout/accettazione_ordine_inevaso_main_list__group_item.xml b/app/src/main/res/layout/accettazione_ordine_inevaso_main_list__group_item.xml index 5f3fe27e..eed1abd9 100644 --- a/app/src/main/res/layout/accettazione_ordine_inevaso_main_list__group_item.xml +++ b/app/src/main/res/layout/accettazione_ordine_inevaso_main_list__group_item.xml @@ -4,8 +4,7 @@ + android:layout_height="wrap_content"> @@ -123,7 +120,6 @@ android:layout_height="wrap_content" android:layout_marginStart="4dp" android:textAllCaps="true" - android:textColor="@android:color/black" android:textStyle="bold" tools:text="cnf" /> @@ -143,7 +139,6 @@ android:layout_alignParentStart="true" android:layout_marginTop="4dp" android:layout_toStartOf="@id/secondary_unt_mis" - android:textColor="@android:color/black" android:textSize="16sp" tools:text="DESCRIZIONE" /> @@ -156,7 +151,6 @@ android:layout_marginTop="2dp" android:layout_toStartOf="@id/secondary_unt_mis" android:layout_below="@+id/descrizione" - android:textColor="@android:color/black" android:textSize="14sp" tools:text="DATA ORD" /> @@ -196,7 +190,7 @@ + @@ -16,7 +16,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="top" - android:background="@color/full_white" android:fitsSystemWindows="false"> @@ -35,7 +34,6 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/full_white" android:minHeight="?attr/actionBarSize"> + app:layout_behavior="@string/appbar_scrolling_view_behavior" + tools:listitem="@layout/accettazione_ordine_inevaso_main_list__group_item" /> diff --git a/app/src/main/res/layout/fragment_main_accettazione_bolla.xml b/app/src/main/res/layout/fragment_main_accettazione_bolla.xml index b6f89c16..acf172b5 100644 --- a/app/src/main/res/layout/fragment_main_accettazione_bolla.xml +++ b/app/src/main/res/layout/fragment_main_accettazione_bolla.xml @@ -5,6 +5,12 @@ + + + + @@ -26,7 +32,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" - app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/> + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main_accettazione_ordini.xml b/app/src/main/res/layout/fragment_main_accettazione_ordini.xml index ce6abfe6..fb9c6b78 100644 --- a/app/src/main/res/layout/fragment_main_accettazione_ordini.xml +++ b/app/src/main/res/layout/fragment_main_accettazione_ordini.xml @@ -14,7 +14,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/full_white" tools:context="it.integry.integrywmsnative.gest.accettazione_ordini_elenco.MainAccettazioneOrdiniElencoFragment"> + android:scrollbars="vertical" + tools:listitem="@layout/accettazione_main_list_group_model"/> diff --git a/app/src/main/res/menu/accettazione_bolla_fab_menu.xml b/app/src/main/res/menu/accettazione_bolla_fab_menu.xml new file mode 100644 index 00000000..a4c116f7 --- /dev/null +++ b/app/src/main/res/menu/accettazione_bolla_fab_menu.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 404b9b5e..14e1125b 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -89,6 +89,9 @@ L\'UL selezionata è già agganciata ad un documento per cui non può essere utilizzata Stai caricando una UL di vendita. Sei sicuro di voler continuare? + Apri bolla + Segna bolla come ricevuta + Continua Versamento automatico diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f7b13d64..87b69a46 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -148,6 +148,9 @@ Piece Please scan a LU barcode to deposit + Open documents + Mark document as received + between 3 and 30 alphanumeric characters enter a valid username enter a valid code