Migliorie in elenco inventari

This commit is contained in:
Giuseppe Scorrano 2022-11-22 10:42:18 +01:00
parent bad3e58fbd
commit 1512cb7de9
11 changed files with 343 additions and 50 deletions

View File

@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 11,
"identityHash": "1fbbe769d42f5fb33a56580bea8b11c6",
"identityHash": "6a7fc5a013080ef96827187ce0637459",
"entities": [
{
"tableName": "articoli_griglia",
@ -868,7 +868,7 @@
},
{
"tableName": "inventari",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `id_inventario` INTEGER, `cod_mdep` TEXT NOT NULL, `data_inventario` INTEGER, `data_reg` INTEGER, `data_ver` INTEGER, `filtro` TEXT, `flag_stato` TEXT, `flag_operazione` TEXT, `cod_anag` TEXT, `cod_dtip` TEXT, `inserito_da` TEXT, `registrato_da` TEXT, `verificato_da` TEXT, `data_ora_inizio` INTEGER, `data_ora_fine` INTEGER, `causale` TEXT, `remote_sync_date` INTEGER)",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `id_inventario` INTEGER, `cod_mdep` TEXT NOT NULL, `data_inventario` INTEGER, `data_reg` INTEGER, `data_ver` INTEGER, `filtro` TEXT, `flag_stato` TEXT, `flag_operazione` TEXT, `cod_anag` TEXT, `cod_dtip` TEXT, `inserito_da` TEXT, `registrato_da` TEXT, `verificato_da` TEXT, `data_ora_inizio` INTEGER, `data_ora_fine` INTEGER, `causale` TEXT, `zona` TEXT, `remote_sync_date` INTEGER)",
"fields": [
{
"fieldPath": "id",
@ -972,6 +972,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "zona",
"columnName": "zona",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteSyncDate",
"columnName": "remote_sync_date",
@ -1006,12 +1012,139 @@
}
],
"foreignKeys": []
},
{
"tableName": "inventario_rows",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `parent_id` INTEGER, `cod_mart` TEXT NOT NULL, `partita_mag` TEXT, `descrizione` TEXT, `qta` REAL NOT NULL DEFAULT 0, `num_cnf` REAL NOT NULL DEFAULT 0, `qta_cnf` REAL NOT NULL DEFAULT 0, `unt_mis` TEXT NOT NULL DEFAULT '0', `data_ora_inv` INTEGER, `scan_cod_barre` TEXT, `zona` TEXT, `remote_sync_date` INTEGER, FOREIGN KEY(`parent_id`) REFERENCES `inventari`(`_id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "parentId",
"columnName": "parent_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "codMart",
"columnName": "cod_mart",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "partitaMag",
"columnName": "partita_mag",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "descrizione",
"columnName": "descrizione",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "qta",
"columnName": "qta",
"affinity": "REAL",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "numConf",
"columnName": "num_cnf",
"affinity": "REAL",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "qtaConf",
"columnName": "qta_cnf",
"affinity": "REAL",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "untMis",
"columnName": "unt_mis",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "'0'"
},
{
"fieldPath": "dataOraInv",
"columnName": "data_ora_inv",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "scanCodBarre",
"columnName": "scan_cod_barre",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "zona",
"columnName": "zona",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteSyncDate",
"columnName": "remote_sync_date",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_inventario_rows__id",
"unique": false,
"columnNames": [
"_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_inventario_rows__id` ON `${TABLE_NAME}` (`_id`)"
},
{
"name": "index_inventario_rows_parent_id",
"unique": false,
"columnNames": [
"parent_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_inventario_rows_parent_id` ON `${TABLE_NAME}` (`parent_id`)"
}
],
"foreignKeys": [
{
"table": "inventari",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"parent_id"
],
"referencedColumns": [
"_id"
]
}
]
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1fbbe769d42f5fb33a56580bea8b11c6')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6a7fc5a013080ef96827187ce0637459')"
]
}
}

View File

@ -60,4 +60,8 @@ public class InventarioRepository extends _BaseRepository<MtbInvent, InventarioR
}, onError);
}
public void delete(InventarioRoomDTO inventarioDTO, Runnable onComplete, RunnableArgs<Exception> onError){
localDataSource.makeDeleteRequest(inventarioDTO, onComplete, onError);
}
}

View File

@ -358,6 +358,33 @@ public class Converters {
}
}
@BindingAdapter("binding")
public static void bindTextInputEditTextLong(TextInputEditText view, final ObservableField<Long> observableLong) {
Pair<ObservableField<Long>, TextWatcherAdapter> pair = (Pair) view.getTag(R.id.bound_observable);
if (pair == null || pair.first != observableLong) {
if (pair != null) {
view.removeTextChangedListener(pair.second);
}
TextWatcherAdapter watcher = new TextWatcherAdapter() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Long value = null;
if (!UtilityString.isNullOrEmpty(s.toString()))
value = Long.valueOf(s.toString());
observableLong.set(value);
}
};
view.setTag(R.id.bound_observable, new Pair<>(observableLong, watcher));
view.addTextChangedListener(watcher);
}
Long newValue = observableLong.get();
Long viewValue = view.getText().toString().trim().length() > 0 ? Long.valueOf(view.getText().toString()) : Long.valueOf(0);
if (!viewValue.equals(newValue) && newValue != null) {
view.setText(newValue.toString());
}
}
@BindingAdapter(value = {"binding", "parentView", "warningOnOldDates"}, requireAll = false)
public static void bindTextInputEditTextDate(TextInputEditText view, final ObservableField<Date> observableDate, BaseDialogFragment parentFragment, boolean warningOnOldDates) {
Pair<ObservableField<Date>, TextWatcherAdapter> pair = (Pair) view.getTag(R.id.bound_observable);

View File

@ -11,6 +11,7 @@ import androidx.fragment.app.Fragment;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
@ -26,6 +27,9 @@ public abstract class BaseFragment extends Fragment {
@Inject
public DialogProgressView mCurrentProgress;
@Inject
public ExecutorService executorService;
protected ElevatedToolbar mToolbar;
protected final List<Runnable> mOnPreDestroyList = new ArrayList<>();
@ -65,7 +69,7 @@ public abstract class BaseFragment extends Fragment {
BarcodeManager.disable();
if (!progressOpened && !this.mCurrentProgress.isAdded()) {
this.progressOpened = true;
requireActivity().runOnUiThread(() -> {
executorService.execute(() -> {
this.mCurrentProgress.show(requireActivity().getSupportFragmentManager(), "tag");
});
}
@ -75,7 +79,7 @@ public abstract class BaseFragment extends Fragment {
BarcodeManager.enable();
if (progressOpened) {
this.progressOpened = false;
requireActivity().runOnUiThread(() -> {
executorService.execute(() -> {
mCurrentProgress.dismissAllowingStateLoss();
});
}

View File

@ -78,27 +78,33 @@ public class ElencoInventariFragment extends BaseFragment implements ITitledFrag
private void initRecyclerView() {
mViewModel.getInventarioList().observe(getViewLifecycleOwner(), data -> {
// binding.reportEmptyView.setVisibility(data == null || data.isEmpty() ? View.VISIBLE : View.GONE);
mBinding.emptyView.setVisibility(data == null || data.isEmpty() ? View.VISIBLE : View.GONE);
});
var itemType = new Type<InventarioRoomDTO, FragmentElencoInventarioListSingleItemBinding>(R.layout.fragment_elenco_inventario_list_single_item, BR.item);
itemType.onClick(x -> {
new BottomSheetInventarioActionsView(x.getBinding().getItem())
.setListener(new BottomSheetInventarioActionsView.Listener() {
@Override
public void onItemEdit() {
mViewModel.loadInventarioData(x.getBinding().getItem().getIdInventario(), listArts -> {
startPicking(x.getBinding().getItem(), listArts);
});
}
var item = x.getBinding().getItem();
@Override
public void onItemDelete() {
if (!item.isSyncronized()) {
var bottomSheetActions = new BottomSheetInventarioActionsView(item)
.setListener(new BottomSheetInventarioActionsView.Listener() {
@Override
public void onItemEdit() {
mViewModel.loadInventarioData(item.getIdInventario(), listArts -> {
startPicking(item, listArts);
});
}
}
})
.show(requireActivity().getSupportFragmentManager(), "tag");
@Override
public void onItemDelete() {
deleteInventarioRequest(item);
}
});
bottomSheetActions.show(requireActivity().getSupportFragmentManager(), "tag");
}
return null;
});
@ -115,11 +121,6 @@ public class ElencoInventariFragment extends BaseFragment implements ITitledFrag
}
private void startPicking(InventarioRoomDTO inventarioRoomDTO, List<InventarioArtDTO> listArts) {
PickingInventarioActivity.startActivity(requireContext(), inventarioRoomDTO, listArts);
}
@Override
public void onPreDestroy(Runnable onComplete) {
mViewModel.destroyData();
@ -132,13 +133,23 @@ public class ElencoInventariFragment extends BaseFragment implements ITitledFrag
}
@Override
public void onInventarioInfoRequest(RunnableArgss<Integer, String> onComplete) {
public void onInventarioInfoRequest(RunnableArgss<Long, String> onComplete) {
DialogAskInfoInventarioView.newInstance(onComplete, null)
.show(requireActivity().getSupportFragmentManager(), "tag");
}
@Override
public void onCreateInventarioRequest(int inventoryId, String zone) {
public void onInventarioLoaded(InventarioRoomDTO inventarioRoomDTO, List<InventarioArtDTO> listaArts) {
startPicking(inventarioRoomDTO, listaArts);
}
private void startPicking(InventarioRoomDTO inventarioRoomDTO, List<InventarioArtDTO> listArts) {
PickingInventarioActivity.startActivity(requireContext(), inventarioRoomDTO, listArts);
}
@Override
public void onCreateInventarioRequest(long inventoryId, String zone) {
DialogYesNoView
.newInstance(null, "Vuoi procedere con la creazione di un nuovo inventario con codice " + inventoryId + "?",
dialogResponse -> {
@ -155,4 +166,21 @@ public class ElencoInventariFragment extends BaseFragment implements ITitledFrag
})
.show(requireActivity().getSupportFragmentManager(), "tag");
}
public void deleteInventarioRequest(InventarioRoomDTO inventarioRoomDTO) {
DialogYesNoView
.newInstance(null, "Vuoi cancellare l'inventario?",
dialogResponse -> {
switch (dialogResponse) {
case YES:
this.mViewModel.deleteInventario(inventarioRoomDTO);
break;
case NO:
case ABORT:
break;
}
})
.show(requireActivity().getSupportFragmentManager(), "tag");
}
}

View File

@ -3,6 +3,7 @@ package it.integry.integrywmsnative.gest.inventario;
import androidx.lifecycle.LiveData;
import java.util.List;
import java.util.Objects;
import it.integry.integrywmsnative.core.data_store.db.entity.InventarioRoomDTO;
import it.integry.integrywmsnative.core.data_store.db.respository_new.InventarioRepository;
@ -13,6 +14,7 @@ import it.integry.integrywmsnative.core.rest.consumers.InventarioRESTConsumer;
import it.integry.integrywmsnative.core.rest.model.inventario.InventarioArtDTO;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilityDate;
import it.integry.integrywmsnative.core.utility.UtilityString;
public class ElencoInventariViewModel {
@ -54,13 +56,31 @@ public class ElencoInventariViewModel {
this.sendOnLoadingStarted();
inventarioRESTConsumer.loadInventario(inventoryId, loadedInventario -> {
this.sendOnLoadingEnded();
if (loadedInventario == null || loadedInventario.getMtbInvent() == null)
if (loadedInventario == null || loadedInventario.getMtbInvent() == null) {
this.sendOnLoadingEnded();
this.sendCreateInventarioRequest(inventoryId, zone);
else this.createNewInventario(inventoryId, zone, (inventarioRoom, listaArts) -> {
} else {
});
var matchedInventory = getInventarioList().getValue()
.stream()
.filter(x -> Objects.equals(x.getIdInventario(), inventoryId) && UtilityString.equalsIgnoreCase(x.getZona(), zone))
.findFirst()
.orElse(null);
if (matchedInventory == null)
this.createNewInventario(inventoryId, zone, (inventarioRoom, listaArts) -> {
this.sendOnLoadingEnded();
this.sendOnInventarioLoaded(inventarioRoom, listaArts);
});
else
loadInventarioData(inventoryId, listaArts -> {
this.sendOnLoadingEnded();
this.sendOnInventarioLoaded(matchedInventory, listaArts);
});
}
}, this::sendOnError);
});
}
@ -83,16 +103,21 @@ public class ElencoInventariViewModel {
var createdInventario = new InventarioRoomDTO();
createdInventario.setIdInventario(inventoryId);
createdInventario.setZona(zone);
createdInventario.setCodMdep(codMdep);
createdInventario.setInseritoDa(settingsManager.getSettings().getUser().getFullname());
createdInventario.setDataInventario(UtilityDate.getNow());
inventarioRepository.insert(createdInventario, () -> {
loadInventarioData(inventoryId, inventarioArts -> {
loadInventarioData(inventoryId, inventarioArts -> {
inventarioRepository.insert(createdInventario, () -> {
this.sendOnLoadingEnded();
onComplete.run(createdInventario, inventarioArts);
});
}, this::sendOnError);
}, this::sendOnError);
});
}
public void deleteInventario(InventarioRoomDTO inventarioRoomDTO) {
inventarioRepository.delete(inventarioRoomDTO, null, this::sendOnError);
}
@ -100,11 +125,15 @@ public class ElencoInventariViewModel {
this.listener = listener;
}
private void sendOnInventarioInfoRequest(RunnableArgss<Integer, String> onComplete) {
private void sendOnInventarioInfoRequest(RunnableArgss<Long, String> onComplete) {
if (listener != null) listener.onInventarioInfoRequest(onComplete);
}
private void sendCreateInventarioRequest(int inventoryId, String zone) {
private void sendOnInventarioLoaded(InventarioRoomDTO inventarioRoomDTO, List<InventarioArtDTO> listaArts) {
if (listener != null) listener.onInventarioLoaded(inventarioRoomDTO, listaArts);
}
private void sendCreateInventarioRequest(long inventoryId, String zone) {
if (this.listener != null) this.listener.onCreateInventarioRequest(inventoryId, zone);
}
@ -122,9 +151,11 @@ public class ElencoInventariViewModel {
public interface Listener extends ILoadingListener {
void onInventarioInfoRequest(RunnableArgss<Integer, String> onComplete);
void onInventarioInfoRequest(RunnableArgss<Long, String> onComplete);
void onCreateInventarioRequest(int inventoryId, String zone);
void onInventarioLoaded(InventarioRoomDTO inventarioRoomDTO, List<InventarioArtDTO> listaArts);
void onCreateInventarioRequest(long inventoryId, String zone);
void onError(Exception ex);

View File

@ -11,12 +11,15 @@ import androidx.databinding.ObservableField;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.apache.commons.lang3.StringUtils;
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.RunnableArgss;
import it.integry.integrywmsnative.core.utility.UtilityString;
import it.integry.integrywmsnative.databinding.DialogAskInfoInventarioBinding;
public class DialogAskInfoInventarioView extends BaseDialogFragment {
@ -24,21 +27,21 @@ public class DialogAskInfoInventarioView extends BaseDialogFragment {
@Inject
DialogAskInfoInventarioViewModel mViewModel;
private final RunnableArgss<Integer, String> onConfirmed;
private final RunnableArgss<Long, String> onConfirmed;
private final Runnable onAbort;
public ObservableField<Integer> inventoryId = new ObservableField<>();
public ObservableField<Long> inventoryId = new ObservableField<>();
public ObservableField<String> zone = new ObservableField<>();
private DialogAskInfoInventarioBinding mBindings;
private Context mContext;
//Pass here all external parameters
public static DialogAskInfoInventarioView newInstance(RunnableArgss<Integer, String> onConfirmed, Runnable onAbort) {
public static DialogAskInfoInventarioView newInstance(RunnableArgss<Long, String> onConfirmed, Runnable onAbort) {
return new DialogAskInfoInventarioView(onConfirmed, onAbort);
}
private DialogAskInfoInventarioView(RunnableArgss<Integer, String> onConfirmed, Runnable onAbort) {
private DialogAskInfoInventarioView(RunnableArgss<Long, String> onConfirmed, Runnable onAbort) {
super();
this.onConfirmed = onConfirmed;
@ -66,8 +69,12 @@ public class DialogAskInfoInventarioView extends BaseDialogFragment {
.setView(mBindings.getRoot())
.setCancelable(cancelable)
.setPositiveButton(R.string.ok, (dialog, which) -> {
var zone = UtilityString.empty2null(this.zone.get());
if(zone != null) zone = StringUtils.capitalize(zone);
if (this.onConfirmed != null)
this.onConfirmed.run(this.inventoryId.get(), this.zone.get());
this.onConfirmed.run(this.inventoryId.get(), zone);
})
.setNegativeButton(R.string.abort, (dialog, which) -> {
if (this.onAbort != null) this.onAbort.run();

View File

@ -17,6 +17,59 @@
android:orientation="vertical"
tools:context=".gest.inventario.ElencoInventariFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.3"
android:visibility="gone">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_empty_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.2" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_empty_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.15" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_empty_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.85" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintEnd_toStartOf="@id/guideline_empty_right"
app:layout_constraintStart_toEndOf="@id/guideline_empty_left"
app:layout_constraintTop_toTopOf="@id/guideline_empty_top">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="72dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_playlist_add_check_24dp" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/AppTheme.NewMaterial.Text.Medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/no_inventory_available_text" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/inventario_list"

View File

@ -3,7 +3,9 @@
<data>
<import type="android.view.View" />
<import type="it.integry.integrywmsnative.core.utility.UtilityDate" />
<import type="it.integry.integrywmsnative.core.utility.UtilityString" />
<variable
name="item"
@ -77,7 +79,7 @@
android:layout_below="@id/badge1"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:layout_toStartOf="@id/compilato_da"
android:layout_toStartOf="@id/zona"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/not_synchronized"
@ -91,23 +93,25 @@
android:layout_below="@id/badge1"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:layout_toStartOf="@id/compilato_da"
android:layout_toStartOf="@id/zona"
android:ellipsize="end"
android:singleLine="true"
android:text="@{&quot;Sincronizzato il &quot; + UtilityDate.formatDate(item.remoteSyncDate, UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN)}"
app:visibility="@{item.syncronized}" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/compilato_da"
android:id="@+id/zona"
style="@style/AppTheme.NewMaterial.Text.Badge"
android:textSize="12sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/date"
android:layout_alignParentEnd="true"
android:layout_marginTop="4dp"
android:text="@{item.inseritoDa}"
android:textSize="12sp"
tools:text="Nome Cognome" />
android:text="@{item.zona}"
app:visibility="@{UtilityString.isNullOrEmpty(item.zona) ? View.GONE : View.VISIBLE}"
android:textAllCaps="true"
tools:text="fresco" />
</RelativeLayout>
</layout>

View File

@ -208,6 +208,7 @@
<string name="no_available_order_on_line">Nessun ordine compatibile</string>
<string name="no_item_text">Nessun articolo</string>
<string name="no_item_in_recupera_materiale">Nessuna UL versata in produzione</string>
<string name="no_inventory_available_text">Nessun inventario disponibile</string>
<string name="already_used_anonymous_barcode"><![CDATA[L\'etichetta scansionata è stata già utilizzata]]></string>
<string name="no_result_from_barcode">Il barcode scansionato non ha fornito alcun risultato</string>

View File

@ -207,7 +207,8 @@
<string name="no_item_to_pick_text">No items to pick</string>
<string name="no_docs_to_show_text">No documents to show</string>
<string name="no_orders_to_pick_text">No orders to dispatch</string>
.
<string name="no_inventory_available_text">No inventory available</string>
<string name="no_available_order_on_line">no compatible orders found</string>
<string name="no_item_text">No items</string>
<string name="no_item_in_recupera_materiale">No LU poured into production</string>