Finish v1.47.15(528)
All checks were successful
WMS - Android (New)/pipeline/head This commit looks good

This commit is contained in:
Marco Elefante 2025-09-11 13:37:25 +02:00
commit e8da16cb8a
25 changed files with 321 additions and 297 deletions

2
.gitignore vendored
View File

@ -149,3 +149,5 @@ crashlytics.properties
crashlytics-build.properties
### AndroidStudio Patch ###
!/gradle/wrapper/gradle-wrapper.jar
/.idea/copilot.data.migration.agent.xml
/.idea/copilot.data.migration.edit.xml

View File

@ -8,10 +8,11 @@ apply plugin: 'com.google.firebase.crashlytics'
//apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
android {
def appVersionCode = 521
def appVersionName = '1.47.08'
def appVersionCode = 528
def appVersionName = '1.47.15'
signingConfigs {
release {
@ -34,7 +35,7 @@ android {
defaultConfig {
applicationId "it.integry.integrywmsnative"
minSdkVersion 21
targetSdkVersion 35
targetSdk 36
versionCode appVersionCode
versionName appVersionName
// testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -60,6 +61,9 @@ android {
// shrinkResources true // Rimuove risorse non utilizzate
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
firebaseCrashlytics {
mappingFileUploadEnabled true
}
}
}
@ -91,7 +95,7 @@ android {
abortOnError false
}
namespace 'it.integry.integrywmsnative'
compileSdk 35
compileSdk 36
}
configurations {
@ -110,18 +114,18 @@ dependencies {
implementation 'com.github.lupaulus:logger:2.3.2'
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:33.14.0')
implementation platform('com.google.firebase:firebase-bom:33.16.0')
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-crashlytics'
implementation 'com.google.firebase:firebase-perf'
implementation 'com.google.android.gms:play-services-basement:18.7.0'
implementation 'com.google.android.gms:play-services-basement:18.7.1'
//JJWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'io.jsonwebtoken:jjwt-api:0.13.0'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.13.0'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.13.0'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'androidx.cardview:cardview:1.0.0'
@ -134,14 +138,14 @@ dependencies {
}
implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0"
implementation 'com.squareup.retrofit2:retrofit:2.11.0'
implementation 'com.squareup.retrofit2:converter-gson:2.11.0'
implementation 'com.squareup.retrofit2:retrofit:3.0.0'
implementation 'com.squareup.retrofit2:converter-gson:3.0.0'
implementation 'com.annimon:stream:1.2.2'
implementation 'androidx.lifecycle:lifecycle-runtime:2.9.0'
implementation 'org.apache.commons:commons-text:1.9'
implementation 'androidx.lifecycle:lifecycle-runtime:2.9.3'
implementation 'org.apache.commons:commons-text:1.14.0'
//MVVM
def dagger2_version = '2.55'
def dagger2_version = '2.57.1'
implementation "com.google.dagger:dagger:$dagger2_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger2_version"
implementation "com.google.dagger:dagger-android:$dagger2_version"
@ -157,7 +161,7 @@ dependencies {
implementation 'com.github.pedromassango:doubleClick:3.0'
//SQLite ROOM
def room_version = "2.7.1"
def room_version = "2.7.2"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
@ -183,11 +187,13 @@ dependencies {
implementation 'com.github.harry1453:android-bluetooth-serial:v1.1.2'
// RxJava is also required.
implementation 'io.reactivex.rxjava2:rxjava:2.1.12'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.2.21'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
//Barcode generator
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
implementation("org.javatuples:javatuples:1.2")
}
repositories {

View File

@ -34,6 +34,12 @@
<init>(...);
@com.google.gson.annotations.SerializedName <fields>;
}
# Per JJWT
-keep class io.jsonwebtoken.** { *; }
-keepnames class io.jsonwebtoken.* { *; }
-keepnames interface io.jsonwebtoken.* { *; }
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken

View File

@ -24,19 +24,4 @@ public class CommonConst {
public static String RECOVER_COLLO_FILE = "recover_ul.json";
}
public static class Mail {
public static String[] forErrorsDebug = {
"g.scorrano@integry.it",
"v.castellana@integry.it"
};
public static String[] forErrors = {
// "syslogs@integry.it",
"g.scorrano@integry.it",
"v.castellana@integry.it"
};
}
}

View File

@ -11,11 +11,11 @@ public class JwtUtils {
private final static String SIGNING_KEY = "gICy3bjD56i/YFnBZZKe5ibiz3Snsp08nybGGziCV4ZcvyXBbyqWUnJ2wTrRXhOuf/xdljPXX0yBaqdAgvKthQ==";
public static Claims parseJwt(String token) {
Jws<Claims> jws = Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(Decoders.BASE64.decode(SIGNING_KEY)))
Jws<Claims> jws = Jwts.parser()
.verifyWith(Keys.hmacShaKeyFor(Decoders.BASE64.decode(SIGNING_KEY)))
.build()
.parseClaimsJws(token);
.parseSignedClaims(token);
return jws.getBody();
return jws.getPayload();
}
}

View File

@ -90,10 +90,10 @@ public class AppContext {
Logger.addLogAdapter(new AndroidLogAdapter());
logsFolder = new File(mApplicationContext.getExternalFilesDir(null).getAbsolutePath());
removeOldLogs(logsFolder);
int maxBytesSize = 5 * 1024 * 1024;
Logger.addLogAdapter(new DiskLogAdapter(logsFolder, maxBytesSize));
removeOldLogs(logsFolder);
}
private void removeOldLogs(File logsFolder) {

View File

@ -1,8 +1,5 @@
package it.integry.integrywmsnative.core.rest.consumers;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import com.google.gson.Gson;
@ -17,8 +14,6 @@ import java.util.concurrent.ExecutorService;
import javax.inject.Singleton;
import it.integry.integrywmsnative.BuildConfig;
import it.integry.integrywmsnative.core.CommonConst;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.rest.RESTBuilder;
import it.integry.integrywmsnative.core.rest.handler.ManagedErrorCallback;
@ -27,9 +22,7 @@ import it.integry.integrywmsnative.core.rest.model.MailRequestDTO;
import it.integry.integrywmsnative.core.rest.model.NativeSqlRequestDTO;
import it.integry.integrywmsnative.core.rest.model.ServiceRESTResponse;
import it.integry.integrywmsnative.core.rest.model.system.LatestAppVersionInfoDTO;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilityGson;
import it.integry.integrywmsnative.core.utility.UtilityString;
import retrofit2.Call;
import retrofit2.Response;
@ -110,36 +103,6 @@ public class SystemRESTConsumer extends _BaseRESTConsumer {
});
}
public void sendErrorLogMail(String message, Runnable onComplete, RunnableArgs<Exception> onFailed) {
String currentAzienda = UtilityString.isNullOrEmpty(SettingsManager.i().getUserSession().getProfileDB()) ? "" : " [" + SettingsManager.i().getUserSession().getProfileDB() + "]";
String dest = "";
if (BuildConfig.DEBUG) {
dest = TextUtils.join(";", CommonConst.Mail.forErrorsDebug);
} else {
dest = TextUtils.join(";", CommonConst.Mail.forErrors);
}
MailRequestDTO mailDTO = new MailRequestDTO()
.setFrom("sender@integry.it")
.setFromName((BuildConfig.DEBUG ? "[DEBUG] " : "") + "WMS Android")
.setTo(dest)
.setSubject("Bug notification" + currentAzienda)
.setMsgText(message)
.setHtml(true);
sendMail(mailDTO, () -> {
if (onComplete != null) onComplete.run();
}, ex -> {
Log.e(SystemRESTConsumer.class.getName(), "", ex);
if (onFailed != null) onFailed.run(ex);
});
}
public void sendMailSynchronized(MailRequestDTO mailDTO) throws Exception {
SystemRESTConsumerService service = restBuilder.getService(SystemRESTConsumerService.class);
var response = service.sendMail(mailDTO).execute();

View File

@ -1,8 +1,13 @@
package it.integry.integrywmsnative.core.rest.model;
import com.google.gson.annotations.SerializedName;
public class AvailableCodMdepsDTO {
@SerializedName("codMdep")
private String codMdep;
@SerializedName("descrizione")
private String descrizione;
public String getCodMdep() {

View File

@ -39,8 +39,6 @@ public class SettingsManager {
private static SettingsModel settingsModelIstance;
private static DBSettingsModel dbSettingsModelIstance;
private static boolean firstStart = false;
private static Context mContext;
private static SystemRESTConsumer mSystemRESTConsumer;
private static ImballiRESTConsumer mImballiRESTConsumer;
@ -65,15 +63,15 @@ public class SettingsManager {
public void init() {
settingsModelIstance = (SettingsModel) Stash.getObject(TAG, SettingsModel.class);
if (settingsModelIstance == null) {
if (settingsModelIstance == null)
settingsModelIstance = new SettingsModel();
if (settingsModelIstance.getServer() == null)
settingsModelIstance.setServer(new SettingsModel.Server());
firstStart = true;
}
dbSettingsModelIstance = new DBSettingsModel();
}
public SettingsModel getSettings() {
@ -89,10 +87,6 @@ public class SettingsManager {
return dbSettingsModelIstance;
}
public static boolean isFirstStart() {
return firstStart;
}
public static boolean isInstanceAvailable() {
return i() != null;
}

View File

@ -49,8 +49,12 @@ public class LoginViewModel {
FirebaseInstallations.getInstance().getId().addOnCompleteListener(fid -> {
SettingsManager.i().createUserSession();
retrieveAvailableProfiles(protocol, host, port, username, password, selectedProfile -> {
SettingsManager.i().createUserSession();
if(selectedProfile == null) {
this.sendOnLoadingEnded();
return;
}
authenticate(protocol, host, port, username, password, selectedProfile, fid.getResult(), fullName -> {
@ -126,6 +130,8 @@ public class LoginViewModel {
}
private void authenticate(String protocol, String host, int port, String username, String password, String profileDb, String deviceSalt, RunnableArgs<String> onComplete) {
mAuthenticationRESTConsumer.authenticate(protocol, host, port, username, password, profileDb, deviceSalt, sessionData -> {
var claims = JwtUtils.parseJwt(sessionData.getAccessToken());

View File

@ -53,7 +53,7 @@ public class ProdRecuperoMaterialeViewModel {
this.sendOnLoadingStarted();
mProdRecuperoMaterialeRESTConsumer.loadLastULVersate(codJfas, ulList -> {
this.mUlList.setValue(ulList);
this.mUlList.postValue(ulList);
this.sendOnLoadingEnded();
}, this::sendError);

View File

@ -21,7 +21,7 @@ public class ProdRientroMerceOrderListFilterViewModel {
public void init(List<OrdineLavorazioneDTO> initialList) {
this.initialOrderList = initialList;
this.currentFilteredOrderList.setValue(this.initialOrderList);
this.currentFilteredOrderList.postValue(this.initialOrderList);
}
public MutableLiveData<List<OrdineLavorazioneDTO>> getMutableFilteredOrderList() {

View File

@ -33,7 +33,9 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import javax.inject.Inject;
@ -258,81 +260,98 @@ public class MainSettingsFragment extends PreferenceFragmentCompat implements IT
private void exportLog() {
var handler = new Handler(Looper.getMainLooper());
DialogYesNoView.newInstance("Esportazione log", "Vuoi inviare il log degli eventi al supporto?", result -> {
if (result == DialogConsts.Results.NO || result == DialogConsts.Results.ABORT)
return;
executorService.execute(() -> {
this.openProgress();
if(!askConfirmToExportLog()) {
return;
}
executorService.execute(() -> {
this.openProgress();
File logFilePath = appContext.getLogFilePath();
var files = logFilePath.listFiles();
File logFilePath = appContext.getLogFilePath();
var files = logFilePath.listFiles();
var fileToShare = Arrays.stream(files)
.sorted(Comparator.reverseOrder())
.findFirst()
.orElse(null);
try {
List<MailAttachmentDTO> attachmentDTOList = new ArrayList<>();
var fileToShare = Arrays.stream(files)
.sorted(Comparator.reverseOrder())
.findFirst()
.orElse(null);
try {
List<MailAttachmentDTO> attachmentDTOList = new ArrayList<>();
if (fileToShare != null) {
var htmlContent = createAppLogAttachment(fileToShare);
if (fileToShare != null) {
var htmlContent = createAppLogAttachment(fileToShare);
byte[] buffer = htmlContent.getBytes();//specify the size to allow.
String base64 = Base64.encodeToString(buffer, Base64.NO_WRAP);
byte[] buffer = htmlContent.getBytes();//specify the size to allow.
String base64 = Base64.encodeToString(buffer, Base64.NO_WRAP);
var logAttachment = new MailAttachmentDTO()
.setFileName("wms_log.html")
.setFileb64Content(base64);
attachmentDTOList.add(logAttachment);
}
var logAttachment = new MailAttachmentDTO()
.setFileName("wms_log.html")
.setFileb64Content(base64);
attachmentDTOList.add(logAttachment);
}
rawDao.vacuumDb(new SimpleSQLiteQuery("pragma wal_checkpoint(full)"));
File[] dbFiles = new File[3];
dbFiles[0] = requireContext().getDatabasePath("integry_wms");
dbFiles[1] = requireContext().getDatabasePath("integry_wms-shm");
dbFiles[2] = requireContext().getDatabasePath("integry_wms-wal");
rawDao.vacuumDb(new SimpleSQLiteQuery("pragma wal_checkpoint(full)"));
rawDao.vacuumDb(new SimpleSQLiteQuery("VACUUM;"));
File[] dbFiles = new File[3];
dbFiles[0] = requireContext().getDatabasePath("integry_wms");
dbFiles[1] = requireContext().getDatabasePath("integry_wms-shm");
dbFiles[2] = requireContext().getDatabasePath("integry_wms-wal");
for (int i = 0; i < dbFiles.length; i++) {
byte[] dbFileBytes = new byte[(int) dbFiles[i].length()];
FileInputStream inputStream = new FileInputStream(dbFiles[i]);
final int read = inputStream.read(dbFileBytes);
inputStream.close();
for (int i = 0; i < dbFiles.length; i++) {
byte[] dbFileBytes = new byte[(int) dbFiles[i].length()];
FileInputStream inputStream = new FileInputStream(dbFiles[i]);
final int read = inputStream.read(dbFileBytes);
inputStream.close();
var dbAttachment = new MailAttachmentDTO()
.setFileName(dbFiles[i].getName())
.setFileb64Content(Base64.encodeToString(dbFileBytes, Base64.NO_WRAP));
attachmentDTOList.add(dbAttachment);
}
var dbAttachment = new MailAttachmentDTO()
.setFileName(dbFiles[i].getName())
.setFileb64Content(Base64.encodeToString(dbFileBytes, Base64.NO_WRAP));
attachmentDTOList.add(dbAttachment);
}
var mailRequest = new MailRequestDTO()
.setTo("developer@integry.it")
.setMsgText("Questa è una mail contenente il log del WMS")
.setSubject("Internal WMS log")
.setAttachments(attachmentDTOList);
var mailRequest = new MailRequestDTO()
.setTo("developer@integry.it")
.setMsgText("Questa è una mail contenente il log del WMS")
.setSubject("Internal WMS log")
.setAttachments(attachmentDTOList);
systemRESTConsumer.sendMailSynchronized(mailRequest);
systemRESTConsumer.sendMailSynchronized(mailRequest);
this.closeProgress();
} catch (Exception ex) {
handler.post(() -> {
FirebaseCrashlytics.getInstance().recordException(ex, new CustomKeysAndValues.Builder() {{
putString("ExportLog", "Error while exporting log");
}}.build());
this.closeProgress();
UtilityExceptions.defaultException(requireContext(), ex);
});
}
});
})
.show(getParentFragmentManager(), "tag");
this.closeProgress();
} catch (Exception ex) {
handler.post(() -> {
FirebaseCrashlytics.getInstance().recordException(ex, new CustomKeysAndValues.Builder() {{
putString("ExportLog", "Error while exporting log");
}}.build());
this.closeProgress();
UtilityExceptions.defaultException(requireContext(), ex);
});
}
});
}
private boolean askConfirmToExportLog() {
CountDownLatch countDownLatch = new CountDownLatch(1);
AtomicBoolean userConfirmed = new AtomicBoolean(false);
DialogYesNoView.newInstance("Esportazione log", "Vuoi inviare il log degli eventi al supporto?", result -> {
userConfirmed.set(result != DialogConsts.Results.NO && result != DialogConsts.Results.ABORT);
countDownLatch.countDown();
}).show(getParentFragmentManager(), "tag");
try {
countDownLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return userConfirmed.get();
}
private void openProgress() {
// executorService.execute(() -> {
this.mCurrentProgress.show(requireActivity().getSupportFragmentManager());

View File

@ -739,12 +739,12 @@ public class SpedizioneActivity extends BaseActivity implements SpedizioneViewMo
public void addExtraItem() {
handler.post(() -> {
DialogScanArtView
.newInstance(!mEnableFakeGiacenza, (status, mtbAart, ean128Model, mtbColr) -> {
.newInstance(!mEnableFakeGiacenza, (status, mtbAart, ean128Model, mtbColt) -> {
if (status == DialogConsts.Results.YES) {
executorService.execute(() -> {
try {
this.mViewmodel.dispatchExtraItem(mtbAart, ean128Model, mtbColr);
this.mViewmodel.dispatchExtraItem(mtbAart, ean128Model, mtbColt);
} catch (Exception e) {
onError(e);
}
@ -855,9 +855,11 @@ public class SpedizioneActivity extends BaseActivity implements SpedizioneViewMo
public void closeOrder() {
this.fabPopupMenu.dismiss();
this.onLoadingStarted();
executorService.execute(() -> {
try {
this.mViewmodel.closeOrder();
this.onLoadingEnded();
} catch (Exception e) {
onError(e);
}

View File

@ -1224,7 +1224,7 @@ public class SpedizioneViewModel {
return !stati.isEmpty() ? stati.get(0) : null;
}
public void dispatchExtraItem(MtbAart mtbAart, Ean128Model ean128Model, MtbColr mtbColrToUse) throws Exception {
public void dispatchExtraItem(MtbAart mtbAart, Ean128Model ean128Model, MtbColt refMtbColt) throws Exception {
PickingObjectDTO pickingObjectDTO = new PickingObjectDTO().setMtbAart(mtbAart).setTempPickData(PickDataDTO.fromEan128(ean128Model));
@ -1243,12 +1243,23 @@ public class SpedizioneViewModel {
String partitaMag = null;
LocalDate dataScad = null;
MtbColt refMtbColt = null;
// MtbColt refMtbColt = null;
if (mtbColrToUse != null) {
refMtbColt = new MtbColt().setDataCollo(mtbColrToUse.getDataColloD()).setSerCollo(mtbColrToUse.getSerCollo()).setNumCollo(mtbColrToUse.getNumCollo()).setGestione(mtbColrToUse.getGestione()).setMtbColr(new ObservableArrayList<>());
if (refMtbColt != null && refMtbColt.getMtbColr() != null && !refMtbColt.getMtbColr().isEmpty()) {
MtbColr mtbColrToUse = refMtbColt.getMtbColr().get(0);
refMtbColt.getMtbColr().add(mtbColrToUse);
//Se il collo di riferimento non ha righe, lo creo al volo
// refMtbColt = new MtbColt()
// .setDataCollo(mtbColrToUse.getDataColloD())
// .setSerCollo(mtbColrToUse.getSerCollo())
// .setNumCollo(mtbColrToUse.getNumCollo())
// .setGestione(mtbColrToUse.getGestione())
//// .setCodMdep(mtbColrToUse.getCodMdepIn())
//// .setPosizione(mtbColrToUse.getPosizioneIn())
//// .setBarcodeUl(mtbColrToUse.getBarcodeUlIn())
// .setMtbColr(new ObservableArrayList<>());
//
// refMtbColt.getMtbColr().add(mtbColrToUse);
pickingObjectDTO.setMtbAart(mtbColrToUse.getMtbAart()).setTempPickData(new PickDataDTO().setSourceMtbColt(refMtbColt));
@ -2113,7 +2124,6 @@ public class SpedizioneViewModel {
}
public void closeOrder() {
this.sendOnLoadingStarted();
if (SettingsManager.iDB().isFlagPrintEtichetteOnOrderClose() || SettingsManager.iDB().isFlagPrintPackingListOnOrderClose()) {
var printRequestResult = this.sendOnCloseOrderPrintRequest();
@ -2123,8 +2133,6 @@ public class SpedizioneViewModel {
if (this.mIsOrdTrasf && !UtilityString.isNullOrEmpty(SettingsManager.iDB().getCodDtipOrdTrasfV())) {
this.sendCreateDocsRequest();
}
this.sendOnOrderClosed();
}
private void onCloseOrderPrintRequested(PrintOrderCloseDTO dto) {

View File

@ -1,11 +1,17 @@
package it.integry.integrywmsnative.view.dialogs.ask_cliente.dto;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
public class DialogAskClienteClienteDTO {
@SerializedName("codAnag")
private String codAnag;
@SerializedName("ragSoc")
private String ragSoc;
@SerializedName("codJcoms")
private ArrayList<String> codJcoms = new ArrayList<>();
public String getCodAnag() {

View File

@ -1,23 +1,34 @@
package it.integry.integrywmsnative.view.dialogs.ask_cliente.dto;
import com.google.gson.annotations.SerializedName;
import it.integry.integrywmsnative.core.model.VtbDest;
public class DialogAskClienteDestinatarioDTO {
@SerializedName("codAnag")
private String codAnag;
@SerializedName("codVdes")
private String codVdes;
@SerializedName("destinatario")
private String destinatario;
@SerializedName("indirizzo")
private String indirizzo;
@SerializedName("cap")
private String cap;
@SerializedName("citta")
private String citta;
@SerializedName("prov")
private String prov;
@SerializedName("nazione")
private String nazione;
public String getCodAnag() {

View File

@ -4,15 +4,19 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.ObservableArrayList;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.javatuples.Quartet;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Inject;
@ -27,6 +31,7 @@ import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.expansion.RunnableArgssss;
import it.integry.integrywmsnative.core.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.model.MtbDepoPosizione;
import it.integry.integrywmsnative.core.rest.model.Ean128Model;
import it.integry.integrywmsnative.databinding.DialogScanArtBinding;
@ -38,6 +43,9 @@ public class DialogScanArtView extends BaseDialogFragment implements DialogScanA
@Inject
DialogScanArtViewModel mViewModel;
@Inject
Handler handler;
private Context mContext;
private final boolean mForceOnlyUL;
@ -46,15 +54,15 @@ public class DialogScanArtView extends BaseDialogFragment implements DialogScanA
private int mBarcodeScannerInstanceID;
private RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, MtbColr> onPickingCompleted = null;
private RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> onPickingCompleted = null;
private RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest = null;
public static DialogScanArtView newInstance(boolean forceOnlyUL, @NotNull RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, MtbColr> onPickingCompleted, RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest) {
public static DialogScanArtView newInstance(boolean forceOnlyUL, @NotNull RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> onPickingCompleted, RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest) {
return new DialogScanArtView(forceOnlyUL, onPickingCompleted, onMagazzinoAutomaticoPickingRequest);
}
private DialogScanArtView(boolean forceOnlyUL, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, MtbColr> onItemChoosed, RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest) {
private DialogScanArtView(boolean forceOnlyUL, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> onItemChoosed, RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest) {
super();
mForceOnlyUL = forceOnlyUL;
@ -122,37 +130,60 @@ public class DialogScanArtView extends BaseDialogFragment implements DialogScanA
private final RunnableArgs<BarcodeScanDTO> onScanSuccessfull = data -> {
this.onLoadingStarted();
this.mViewModel.processBarcodeDTO(data, (status, mtbAart, ean128Model, mtbColrList) -> {
executorService.execute(() -> {
var filteredMtbColrList = mtbColrList;
try {
if (mtbAart != null && filteredMtbColrList != null) {
filteredMtbColrList = filteredMtbColrList.stream()
.filter(x -> x.getCodMart().equalsIgnoreCase(mtbAart.getCodMart()))
.collect(Collectors.toList());
Quartet<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> result = this.mViewModel.processBarcodeDTO(data, pickMagazzinoAutomaticoPosizione -> {
handler.post(() -> {
this.onMagazzinoAutomaticoPickingRequest.run(pickMagazzinoAutomaticoPosizione);
this.onLoadingEnded();
dismiss();
});
});
var status = result.getValue0();
var mtbAart = result.getValue1();
var ean128Model = result.getValue2();
var mtbColt = result.getValue3();
List<MtbColr> filteredMtbColrList = mtbColt.getMtbColr();
if (mtbAart != null && filteredMtbColrList != null) {
filteredMtbColrList = filteredMtbColrList.stream()
.filter(x -> x.getCodMart().equalsIgnoreCase(mtbAart.getCodMart()))
.collect(Collectors.toList());
}
List<MtbColr> finalFilteredMtbColrList = filteredMtbColrList;
handler.post(() -> {
if (finalFilteredMtbColrList != null && finalFilteredMtbColrList.size() > 1) {
DialogChooseArtFromListaMtbColrView.make(getActivity(), finalFilteredMtbColrList, mtbColrChose -> {
mtbColt.setMtbColr(new ObservableArrayList<>());
mtbColt.getMtbColr().add(mtbColrChose);
onPickingCompleted.run(status, mtbAart, ean128Model, mtbColt);
}).show();
} else if (finalFilteredMtbColrList != null && finalFilteredMtbColrList.size() == 1) {
mtbColt.setMtbColr(new ObservableArrayList<>());
mtbColt.getMtbColr().add(finalFilteredMtbColrList.get(0));
onPickingCompleted.run(status, mtbAart, ean128Model, mtbColt);
} else {
onPickingCompleted.run(status, mtbAart, ean128Model, null);
}
this.onLoadingEnded();
dismiss();
});
} catch (Exception ex) {
onError(ex);
}
if (filteredMtbColrList != null && filteredMtbColrList.size() > 1) {
DialogChooseArtFromListaMtbColrView.make(getActivity(), filteredMtbColrList, mtbColrChose -> {
onPickingCompleted.run(status, mtbAart, ean128Model, mtbColrChose);
}).show();
} else if (filteredMtbColrList != null && filteredMtbColrList.size() == 1) {
onPickingCompleted.run(status, mtbAart, ean128Model, filteredMtbColrList.get(0));
} else {
onPickingCompleted.run(status, mtbAart, ean128Model, null);
}
this.onLoadingEnded();
dismiss();
}, pickMagazzinoAutomaticoPosizione -> {
this.onMagazzinoAutomaticoPickingRequest.run(pickMagazzinoAutomaticoPosizione);
this.onLoadingEnded();
dismiss();
});
};
}

View File

@ -1,22 +1,17 @@
package it.integry.integrywmsnative.view.dialogs.scan_art;
import com.annimon.stream.Stream;
import org.javatuples.Quartet;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import it.integry.barcode_base_android_library.model.BarcodeScanDTO;
import it.integry.integrywmsnative.core.exception.EmptyLUException;
import it.integry.integrywmsnative.core.exception.InvalidLUException;
import it.integry.integrywmsnative.core.exception.NoLUFoundException;
import it.integry.integrywmsnative.core.exception.NoResultFromBarcodeException;
import it.integry.integrywmsnative.core.exception.ScannedPositionNotExistException;
import it.integry.integrywmsnative.core.exception.TooManyLUFoundInMonoLUPositionException;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.expansion.RunnableArgssss;
import it.integry.integrywmsnative.core.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.model.MtbDepoPosizione;
import it.integry.integrywmsnative.core.rest.consumers.ArticoloRESTConsumer;
import it.integry.integrywmsnative.core.rest.consumers.BarcodeRESTConsumer;
@ -62,23 +57,23 @@ public class DialogScanArtViewModel {
return this;
}
public void processBarcodeDTO(BarcodeScanDTO barcodeScanDTO, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, List<MtbColr>> onPickingCompleted, RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest) {
public Quartet<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> processBarcodeDTO(BarcodeScanDTO barcodeScanDTO, RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest) throws Exception {
if (UtilityBarcode.isEtichettaAnonima(barcodeScanDTO)) {
//Cerco gli articoli presenti nell'ul dell'etichetta anonima
this.executeEtichettaLU(barcodeScanDTO.getStringValue(), onPickingCompleted);
return this.executeEtichettaLU(barcodeScanDTO.getStringValue());
} else if (UtilityBarcode.isEtichettaPosizione(barcodeScanDTO)) {
//Cerco l'UL presente all'interno della posizione
this.executeEtichettaPosizione(barcodeScanDTO.getStringValue(), onPickingCompleted, onMagazzinoAutomaticoPickingRequest);
return this.executeEtichettaPosizione(barcodeScanDTO.getStringValue(), onMagazzinoAutomaticoPickingRequest);
} else if (UtilityBarcode.isEtichetta128(barcodeScanDTO)) {
this.executeEtichettaEan128(barcodeScanDTO, onPickingCompleted);
return this.executeEtichettaEan128(barcodeScanDTO);
} else if (UtilityBarcode.isEanPeso(barcodeScanDTO) && !mForceOnlyUL) {
this.executeEtichettaEanPeso(barcodeScanDTO, onPickingCompleted);
return this.executeEtichettaEanPeso(barcodeScanDTO);
} else {
this.loadArticolo(barcodeScanDTO.getStringValue(), null, onPickingCompleted);
return this.loadArticolo(barcodeScanDTO.getStringValue(), null);
}
// else {
@ -87,123 +82,108 @@ public class DialogScanArtViewModel {
}
private void executeEtichettaEan128(BarcodeScanDTO barcodeScanDTO, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, List<MtbColr>> onComplete) {
this.mBarcodeRESTConsumer.decodeEan128(barcodeScanDTO, ean128Model -> {
String barcodeProd = null;
if (ean128Model.Sscc != null) barcodeProd = ean128Model.Sscc;
if (ean128Model.Gtin != null) barcodeProd = ean128Model.Gtin;
if (ean128Model.Content != null) barcodeProd = ean128Model.Content;
private Quartet<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> executeEtichettaEan128(BarcodeScanDTO barcodeScanDTO) throws Exception {
var ean128Model = this.mBarcodeRESTConsumer.decodeEan128Synchronized(barcodeScanDTO);
if (!UtilityString.isNullOrEmpty(barcodeProd)) {
if (!UtilityString.isNullOrEmpty(ean128Model.Sscc)) {
this.executeEtichettaLU(ean128Model.Sscc, onComplete);
} else if (!mForceOnlyUL) {
String barcodeProd = null;
if (ean128Model.Sscc != null) barcodeProd = ean128Model.Sscc;
if (ean128Model.Gtin != null) barcodeProd = ean128Model.Gtin;
if (ean128Model.Content != null) barcodeProd = ean128Model.Content;
if (!UtilityString.isNullOrEmpty(barcodeProd)) {
if (!UtilityString.isNullOrEmpty(ean128Model.Sscc)) {
return this.executeEtichettaLU(ean128Model.Sscc);
} else if (!mForceOnlyUL) {
return this.loadArticolo(barcodeProd, ean128Model);
this.loadArticolo(barcodeProd, ean128Model, onComplete);
} else {
this.sendError(new Exception("Barcode non valido"));
}
} else {
//EAN 128 non completo o comunque mancano i riferimenti al prodotto
this.sendError(new NoResultFromBarcodeException(barcodeProd));
throw new Exception("Barcode non valido");
}
}, this::sendError);
}
private void executeEtichettaEanPeso(BarcodeScanDTO barcodeScanDTO, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, List<MtbColr>> onComplete) {
try {
Ean13PesoModel ean13PesoModel = Ean13PesoModel.fromBarcode(barcodeScanDTO.getStringValue());
this.loadArticolo(ean13PesoModel.getPrecode(), ean13PesoModel.toEan128(), onComplete);
} catch (Exception ex) {
this.sendError(ex);
} else {
//EAN 128 non completo o comunque mancano i riferimenti al prodotto
throw new NoResultFromBarcodeException(barcodeProd);
}
}
private Quartet<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> executeEtichettaEanPeso(BarcodeScanDTO barcodeScanDTO) throws Exception {
Ean13PesoModel ean13PesoModel = Ean13PesoModel.fromBarcode(barcodeScanDTO.getStringValue());
private void executeEtichettaLU(String SSCC, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, List<MtbColr>> onComplete) {
mColliMagazzinoRESTConsumer.getBySSCC(SSCC, true, false, mtbColt -> {
if (mtbColt != null && mtbColt.getMtbColr() != null && !mtbColt.getMtbColr().isEmpty()) {
if (mtbColt.getSegno() != -1) {
onComplete.run(DialogConsts.Results.YES, null, null, mtbColt.getMtbColr());
} else this.sendError(new InvalidLUException());
} else {
this.sendError(new EmptyLUException());
}
}, this::sendError);
return this.loadArticolo(ean13PesoModel.getPrecode(), ean13PesoModel.toEan128());
}
private Quartet<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> executeEtichettaLU(String SSCC) throws Exception {
var mtbColt = mColliMagazzinoRESTConsumer.getBySsccSynchronized(SSCC, true, false);
private void executeEtichettaPosizione(String stringValue, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, List<MtbColr>> onComplete, RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest) {
MtbDepoPosizione foundPosizione = Stream.of(SettingsManager.iDB().getAvailablePosizioni())
if (mtbColt == null || mtbColt.getMtbColr() == null || mtbColt.getMtbColr().isEmpty())
throw new NoLUFoundException();
if (mtbColt.getSegno() == -1) throw new InvalidLUException();
return new Quartet<>(DialogConsts.Results.YES, null, null, mtbColt);
}
private Quartet<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> executeEtichettaPosizione(String stringValue, RunnableArgs<MtbDepoPosizione> onMagazzinoAutomaticoPickingRequest) throws Exception {
MtbDepoPosizione foundPosizione = SettingsManager.iDB().getAvailablePosizioni().stream()
.filter(x -> x.getPosizione().equalsIgnoreCase(stringValue))
.single();
.findFirst()
.orElse(null);
if (foundPosizione == null) {
if (foundPosizione == null)
//Nessuna posizione trovata con questo barcode
this.sendError(new ScannedPositionNotExistException());
return;
}
throw new ScannedPositionNotExistException();
if (foundPosizione.isMagazzinoAutomatico()) {
//Eseguo picking da magazzino automatico
onMagazzinoAutomaticoPickingRequest.run(foundPosizione);
} else {
this.executePosizione(foundPosizione, null, onComplete);
return this.executePosizione(foundPosizione, null);
}
return null;
}
private void executePosizione(MtbDepoPosizione posizione, MtbAart articolo, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, List<MtbColr>> onComplete) {
this.mPosizioniRESTConsumer.getBancaliInPosizione(posizione, mtbColtList -> {
private Quartet<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> executePosizione(MtbDepoPosizione posizione, MtbAart articolo) throws Exception {
var mtbColtList = this.mPosizioniRESTConsumer.getBancaliInPosizioneSynchronized(posizione);
if (mtbColtList == null || mtbColtList.isEmpty()) {
this.sendError(new NoLUFoundException());
} else if (mtbColtList.size() == 1) {
this.mColliMagazzinoRESTConsumer.getByTestata(mtbColtList.get(0), true, false, mtbColt -> {
onComplete.run(DialogConsts.Results.YES, articolo, null, mtbColt.getMtbColr());
}, this::sendError);
} else {
this.sendError(new TooManyLUFoundInMonoLUPositionException());
}
if (mtbColtList == null || mtbColtList.isEmpty())
throw new NoLUFoundException();
}, this::sendError);
if (mtbColtList.size() != 1) {
throw new TooManyLUFoundInMonoLUPositionException();
}
var mtbColt = this.mColliMagazzinoRESTConsumer.getByTestataSynchronized(mtbColtList.get(0), true, false);
return new Quartet<>(DialogConsts.Results.YES, articolo, null, mtbColt);
}
private void loadArticolo(@NotNull String barcodeProd, Ean128Model ean128Model, RunnableArgssss<DialogConsts.Results, MtbAart, Ean128Model, List<MtbColr>> onComplete) {
this.mArticoloRESTConsumer.searchByBarcode(barcodeProd, mtbAartList -> {
if (mtbAartList != null && !mtbAartList.isEmpty()) {
private Quartet<DialogConsts.Results, MtbAart, Ean128Model, MtbColt> loadArticolo(@NotNull String barcodeProd, Ean128Model ean128Model) throws Exception {
var mtbAartList = this.mArticoloRESTConsumer.searchByBarcodeSynchronized(barcodeProd);
MtbAart firstArt = mtbAartList.get(0);
MtbDepoPosizione firstArtPosition = UtilityPosizione.getFromCache(firstArt.getPosizione());
if (mtbAartList == null || mtbAartList.isEmpty())
throw new NoResultFromBarcodeException(barcodeProd);
if (firstArtPosition != null && firstArtPosition.isFlagMonoCollo() && mForceOnlyUL) {
this.executePosizione(firstArtPosition, firstArt, onComplete);
} else if (!mForceOnlyUL) {
onComplete.run(DialogConsts.Results.YES, mtbAartList.get(0), ean128Model, null);
} else {
this.sendError(new NoResultFromBarcodeException(barcodeProd));
}
MtbAart firstArt = mtbAartList.get(0);
MtbDepoPosizione firstArtPosition = UtilityPosizione.getFromCache(firstArt.getPosizione());
} else {
this.sendError(new NoResultFromBarcodeException(barcodeProd));
}
}, this::sendError);
if (firstArtPosition != null && firstArtPosition.isFlagMonoCollo() && mForceOnlyUL)
return this.executePosizione(firstArtPosition, firstArt);
if (!mForceOnlyUL)
return new Quartet<>(DialogConsts.Results.YES, mtbAartList.get(0), ean128Model, null);
throw new NoResultFromBarcodeException(barcodeProd);
}
private void sendError(Exception ex) {
if (this.mListener != null) mListener.onError(ex);
}
public void setListener(Listener listener) {
this.mListener = listener;
}

View File

@ -1,11 +1,11 @@
apply plugin: 'com.android.library'
android {
compileSdk 35
compileSdk 36
defaultConfig {
minSdkVersion 21
targetSdk 35
targetSdk 36
consumerProguardFiles 'consumer-rules.pro'
}
@ -36,5 +36,5 @@ configurations {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
}

View File

@ -3,7 +3,7 @@
buildscript {
ext {
kotlin_version = '2.1.0'
agp_version = '8.11.1'
agp_version = '8.13.0'
}
repositories {

View File

@ -1,11 +1,11 @@
apply plugin: 'com.android.library'
android {
compileSdk 35
compileSdk 36
defaultConfig {
minSdkVersion 21
targetSdk 35
targetSdk 36
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -38,6 +38,6 @@ dependencies {
// implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation project(":honeywellsdk")
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation project(path: ':barcode_base_android_library')
}

View File

@ -1,11 +1,11 @@
apply plugin: 'com.android.library'
android {
compileSdk 35
compileSdk 36
defaultConfig {
minSdkVersion 21
targetSdk 35
targetSdk 36
// testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
@ -37,6 +37,6 @@ configurations {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation project(':barcode_base_android_library')
}

View File

@ -1,11 +1,11 @@
apply plugin: 'com.android.library'
android {
compileSdk 35
compileSdk 36
defaultConfig {
minSdkVersion 21
targetSdk 35
targetSdk 36
// testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -35,6 +35,6 @@ configurations {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation project(':barcode_base_android_library')
}

View File

@ -1,11 +1,11 @@
apply plugin: 'com.android.library'
android {
compileSdk 35
compileSdk 36
defaultConfig {
minSdkVersion 21
targetSdk 35
targetSdk 36
// testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -37,7 +37,7 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
testImplementation 'junit:junit:4.13.2'
implementation project(path: ':barcode_base_android_library')
}