Implementata prima Activity (Login) con binding dinamici

This commit is contained in:
Giuseppe Scorrano 2018-04-20 16:50:15 +02:00
parent 1098c7573e
commit 5ada26ace0
52 changed files with 1956 additions and 73 deletions

View File

@ -18,7 +18,7 @@
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/navigation/ic_close_black_24dp.xml" />
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_exit_to_app_black_24dp.xml" />
</map>
</option>
</PersistentState>
@ -29,7 +29,7 @@
<option name="values">
<map>
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_close_24dp" />
<entry key="outputName" value="ic_logout_24dp" />
<entry key="overrideSize" value="true" />
<entry key="sourceFile" value="C:\Users\GiuseppeS" />
</map>

Binary file not shown.

View File

@ -1,7 +1,7 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "it.integry.integrywmsnative"
@ -17,6 +17,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
dependencies {
@ -24,26 +28,49 @@ dependencies {
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:cardview-v7:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.0.0'
implementation 'org.parceler:parceler-api:1.1.10'
annotationProcessor 'org.parceler:parceler:1.1.10'
//MVVM
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.1.1'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
//FAB
//implementation 'com.getbase:floatingactionbutton:1.10.1'
implementation 'com.github.clans:fab:1.6.4'
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.mahc.custombottomsheetbehavior:googlemaps-like:0.9.1'
implementation 'com.sothree.slidinguppanel:library:3.4.0'
// implementation 'com.mahc.custombottomsheetbehavior:googlemaps-like:0.9.1'
// implementation 'com.sothree.slidinguppanel:library:3.4.0'
implementation 'com.fxn769:stash:1.2'
implementation 'net.cachapa.expandablelayout:expandablelayout:2.9.2'
testImplementation 'junit:junit:4.12'

View File

@ -3,8 +3,10 @@
package="it.integry.integrywmsnative">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:name=".MainApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
@ -24,7 +26,8 @@
</activity>
<activity
android:name=".gest.accettazione_ordine_inevaso.AccettazioneOrdineInevasoActivity"
android:theme="@style/AppTheme.NoActionBar"></activity>
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".gest.login.LoginActivity" android:theme="@style/Theme.AppCompat.Light.NoActionBar"></activity>
</application>
</manifest>

View File

@ -1,5 +1,6 @@
package it.integry.integrywmsnative;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@ -18,13 +19,26 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import net.cachapa.expandablelayout.ExpandableLayout;
import org.xml.sax.ErrorHandler;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import it.integry.integrywmsnative.core.REST.consumers.ISimpleOperationCallback;
import it.integry.integrywmsnative.core.REST.consumers.ISingleValueOperationCallback;
import it.integry.integrywmsnative.core.REST.watcher.ServerStatusChecker;
import it.integry.integrywmsnative.core.exception.ExceptionsHandler;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilitySettings;
import it.integry.integrywmsnative.core.wifi.WiFiCheckerViewHolder;
import it.integry.integrywmsnative.gest.accettazione.MainAccettazioneFragment;
import it.integry.integrywmsnative.gest.accettazione.core.interfaces.ITitledFragment;
import it.integry.integrywmsnative.gest.accettazione.dto.OrdineAccettazioneDTO;
import it.integry.integrywmsnative.gest.accettazione_ordine_inevaso.AccettazioneOrdineInevasoActivity;
import it.integry.integrywmsnative.gest.login.LoginActivity;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
@ -33,34 +47,103 @@ public class MainActivity extends AppCompatActivity
@BindView(R.id.nav_view) NavigationView mNavigationView;
@BindView(R.id.no_connection_top_layout)
ExpandableLayout mNoConnectionLayout;
private ServerStatusChecker serverStatusChecker;
private boolean firstCheckExecution = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ExceptionsHandler.toCatch(this);
setContentView(R.layout.activity_main);
if(SettingsManager.i().user.username == null && SettingsManager.i().user.password == null){
startLoginActivity();
} else {
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
ButterKnife.bind(this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
mNavigationView = (NavigationView) findViewById(R.id.nav_view);
mNavigationView.setNavigationItemSelectedListener(this);
mNavigationView = findViewById(R.id.nav_view);
mNavigationView.setNavigationItemSelectedListener(this);
mSearchView.setVisibility(View.GONE);
mSearchView.setVisibility(View.GONE);
init();
}
}
private void startLoginActivity(){
Intent myIntent = new Intent(this, LoginActivity.class);
startActivity(myIntent);
this.finish();
}
private void init(){
serverStatusChecker = new ServerStatusChecker();
serverStatusChecker.startMonitoring(new ISingleValueOperationCallback<Boolean>() {
@Override
public void onResult(Boolean value) {
if(value && (mNoConnectionLayout.isExpanded() || firstCheckExecution)){
SettingsManager.reloadDBVariables(new ISimpleOperationCallback() {
@Override
public void onSuccess(Object value) {
collapseNoConnectionLayout();
firstCheckExecution = false;
}
@Override
public void onFailed(Exception ex) {
//mNoConnectionLayout.expand(true);
if(!mNoConnectionLayout.isExpanded()) expandNoConnectionLayout();
}
});
} else if(!value && !mNoConnectionLayout.isExpanded()){
expandNoConnectionLayout();
}
}
});
WiFiCheckerViewHolder wiFiCheckerViewHolder = new WiFiCheckerViewHolder(this, R.id.wifi_power);
wiFiCheckerViewHolder.startMonitoring();
}
private void collapseNoConnectionLayout(){
runOnUiThread(new Runnable() {
@Override
public void run() {
mNoConnectionLayout.collapse(true);
}
});
}
private void expandNoConnectionLayout(){
runOnUiThread(new Runnable() {
@Override
public void run() {
mNoConnectionLayout.expand(true);
}
});
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
@ -94,17 +177,10 @@ public class MainActivity extends AppCompatActivity
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
// resetAllMenuItemsTextColor(mNavigationView);
// int[] menuColorArray = this.getResources().getIntArray(R.array.menuColors);
Fragment fragment = null;
int id = item.getItemId();
if (id == R.id.nav_accettazione) {
// setTextColorForMenuItem(item, menuColorArray[0]);
fragment = MainAccettazioneFragment.newInstance();
this.adaptViewToFragment(fragment);
} else if (id == R.id.nav_gallery) {
@ -119,6 +195,12 @@ public class MainActivity extends AppCompatActivity
}
else if(id == R.id.nav_logout){
UtilitySettings.logout();
startLoginActivity();
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
@ -126,29 +208,11 @@ public class MainActivity extends AppCompatActivity
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private void resetAllMenuItemsTextColor(NavigationView navigationView) {
for (int i = 0; i < navigationView.getMenu().size(); i++)
setTextColorForMenuItem(navigationView.getMenu().getItem(i), R.color.colorPrimary);
}
private void setTextColorForMenuItem(MenuItem menuItem, int color) {
SpannableString spanString = new SpannableString(menuItem.getTitle().toString());
spanString.setSpan(new ForegroundColorSpan(color), 0, spanString.length(), 0);
menuItem.setTitle(spanString);
if(menuItem.getIcon() != null){
Drawable icon = menuItem.getIcon();
icon.mutate();
icon.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
}
private void adaptViewToFragment(Fragment fragment){
if(fragment instanceof SearchView.OnQueryTextListener) {
mSearchView.setOnQueryTextListener((SearchView.OnQueryTextListener) fragment);

View File

@ -0,0 +1,40 @@
package it.integry.integrywmsnative;
import android.app.Application;
import android.content.res.Configuration;
import android.text.SpannableString;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.settings.Stash;
import it.integry.integrywmsnative.view.dialogs.DialogSimpleMessageHelper;
public class MainApplication extends Application {
// Called when the application is starting, before any other application objects have been created.
// Overriding this method is totally optional!
@Override
public void onCreate() {
super.onCreate();
Stash.init(this);
SettingsManager.init();
}
// Called by the system when the device configuration changes while your component is running.
// Overriding this method is totally optional!
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
// This is called when the overall system is running low on memory,
// and would like actively running processes to tighten their belts.
// Overriding this method is totally optional!
@Override
public void onLowMemory() {
super.onLowMemory();
}
}

View File

@ -0,0 +1,14 @@
package it.integry.integrywmsnative.core;
public class CommonConst {
public static class Login {
public static class Azienda {
public static String host = "192.168.2.13";
public static int port = 8080;
}
}
}

View File

@ -4,6 +4,7 @@ import android.util.Base64;
import java.io.IOException;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
@ -15,12 +16,13 @@ import okhttp3.Response;
public class HttpInterceptor implements Interceptor {
private final String USERNAME = "magazzino";
private final String PASSWORD = "m";
private final String PROFILE_DB = "IME_TE";
@Override
public Response intercept(Chain chain) throws IOException {
final String PROFILE_DB = SettingsManager.i().userSession.profileDB;
final String USERNAME = SettingsManager.i().user.username;
final String PASSWORD = SettingsManager.i().user.password;
final Request request = chain.request();
final HttpUrl url = request.url().newBuilder()
.addQueryParameter("profileDb", PROFILE_DB)

View File

@ -1,5 +1,6 @@
package it.integry.integrywmsnative.core.REST;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@ -11,11 +12,22 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class RESTBuilder {
public static <T> T getService(final Class<T> service) {
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new HttpInterceptor()).build();
// return getService(service, "192.168.2.13", 8080);
return getService(service, SettingsManager.i().server.host, SettingsManager.i().server.port, true);
}
public static <T> T getService(final Class<T> service, String host, int port, boolean addInterceptors){
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
if(addInterceptors) clientBuilder.addInterceptor(new HttpInterceptor());
OkHttpClient client = clientBuilder.build();
String endpoint = "http://" + host + ":" + port + "/ems-api/";
Retrofit retrofit = new Retrofit.Builder()
// .baseUrl("http://192.168.2.13:8080/ems-api/")
.baseUrl("http://www2.studioml.it/ems-api/")
.baseUrl(endpoint)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();

View File

@ -35,7 +35,7 @@ public class EntityRESTConsumer {
callback.onSuccess((T) gson.fromJson(json, clazzType));
} else {
Log.e("EntityRESTConsumer", response.body().getErrorMessage());
callback.onFailed(new Exception(response.message()));
callback.onFailed(new Exception(response.body().getErrorMessage()));
}
} else {
Log.e("EntityRESTConsumer", response.message());

View File

@ -0,0 +1,9 @@
package it.integry.integrywmsnative.core.REST.consumers;
public interface ISingleOperationDoubleCallback<T, U> {
void onSuccess(T firstValue, U secondValue);
void onFailed(Exception ex );
}

View File

@ -0,0 +1,7 @@
package it.integry.integrywmsnative.core.REST.consumers;
public interface ISingleValueOperationCallback<T> {
void onResult(T value);
}

View File

@ -0,0 +1,59 @@
package it.integry.integrywmsnative.core.REST.consumers;
import android.util.Log;
import java.util.List;
import it.integry.integrywmsnative.core.REST.RESTBuilder;
import it.integry.integrywmsnative.core.REST.model.EsitoType;
import it.integry.integrywmsnative.core.REST.model.ServiceRESTResponse;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class SystemRESTConsumer {
public static void getAvailableProfiles(final ISimpleOperationCallback<List<String>> callback){
SystemRESTConsumerService service = RESTBuilder.getService(SystemRESTConsumerService.class);
service.getAvailableProfiles(SettingsManager.i().user.username, SettingsManager.i().user.password).enqueue(new Callback<ServiceRESTResponse<List<String>>>() {
@Override
public void onResponse(Call<ServiceRESTResponse<List<String>>> call, Response<ServiceRESTResponse<List<String>>> response) {
if(response.isSuccessful()) {
if(response.body() != null) {
if(response.body().getEsito() == EsitoType.OK) {
callback.onSuccess(response.body().getDto());
} else {
Log.e("ProfilesAvailable", response.body().getErrorMessage());
callback.onFailed(new Exception(response.body().getErrorMessage()));
}
} else {
Log.e("ProfilesAvailable", response.message());
callback.onFailed(new Exception(response.message()));
}
} else {
Log.e("ProfilesAvailable", "Status " + response.code() + ": " + response.message());
callback.onFailed(new Exception("Status " + response.code() + ": " + response.message()));
}
}
@Override
public void onFailure(Call<ServiceRESTResponse<List<String>>> call, final Throwable t) {
Log.e("ProfilesAvailable", t.toString());
callback.onFailed(new Exception(t));
}
});
}
}

View File

@ -0,0 +1,16 @@
package it.integry.integrywmsnative.core.REST.consumers;
import java.util.List;
import it.integry.integrywmsnative.core.REST.model.ServiceRESTResponse;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface SystemRESTConsumerService {
@GET("getAvailableProfiles")
Call<ServiceRESTResponse<List<String>>> getAvailableProfiles(@Query("username") String username, @Query("password") String password);
}

View File

@ -0,0 +1,39 @@
package it.integry.integrywmsnative.core.REST.watcher;
import android.os.Handler;
import it.integry.integrywmsnative.core.REST.consumers.ISingleValueOperationCallback;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilityServer;
public class ServerStatusChecker {
private ISingleValueOperationCallback<Boolean> mCallback;
private boolean shouldExecute = true;
private final long MILLIS_DELAY = 5 * 1000;
private Handler handler = new Handler();
private Runnable runnableCode = new Runnable() {
@Override
public void run() {
if(shouldExecute) {
UtilityServer.isHostReachable(SettingsManager.i().server.host, SettingsManager.i().server.port, mCallback);
handler.postDelayed(this, MILLIS_DELAY);
}
}
};
public void startMonitoring(ISingleValueOperationCallback<Boolean> callback){
this.mCallback = callback;
shouldExecute = true;
handler.post(runnableCode);
}
public void stopMonitoring(){
shouldExecute = false;
}
}

View File

@ -0,0 +1,22 @@
package it.integry.integrywmsnative.core.di;
import android.databinding.BaseObservable;
import org.parceler.Parcel;
@Parcel
public class BindableBoolean extends BaseObservable {
boolean mValue;
public boolean get() {
return mValue;
}
public void set(boolean value) {
if (mValue != value) {
this.mValue = value;
notifyChange();
}
}
}

View File

@ -0,0 +1,25 @@
package it.integry.integrywmsnative.core.di;
import android.databinding.BaseObservable;
import org.parceler.Parcel;
@Parcel
public class BindableString extends BaseObservable {
String value;
public String get() {
return value != null ? value : "";
}
public void set(String value) {
if (!Objects.equals(this.value, value)) {
this.value = value;
notifyChange();
}
}
public boolean isEmpty() {
return value == null || value.isEmpty();
}
}

View File

@ -0,0 +1,107 @@
package it.integry.integrywmsnative.core.di;
import android.databinding.BindingAdapter;
import android.databinding.BindingConversion;
import android.support.design.widget.TextInputEditText;
import android.support.v4.util.Pair;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import it.integry.integrywmsnative.R;
public class Converters {
@BindingConversion
public static String convertBindableToString(BindableString bindableString) {
return bindableString.get();
}
@BindingConversion
public static boolean convertBindableToBoolean(BindableBoolean bindableBoolean) {
return bindableBoolean.get();
}
@BindingAdapter("app:binding")
public static void bindEditText(EditText view, final BindableString bindableString) {
Pair<BindableString, TextWatcherAdapter> pair = (Pair) view.getTag(R.id.bound_observable);
if (pair == null || pair.first != bindableString) {
if (pair != null) {
view.removeTextChangedListener(pair.second);
}
TextWatcherAdapter watcher = new TextWatcherAdapter() {
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
bindableString.set(s.toString());
}
};
view.setTag(R.id.bound_observable, new Pair<>(bindableString, watcher));
view.addTextChangedListener(watcher);
}
String newValue = bindableString.get();
if (!view.getText().toString().equals(newValue)) {
view.setText(newValue);
}
}
@BindingAdapter("app:binding")
public static void bindTextInputEditText(TextInputEditText view, final BindableString bindableString) {
Pair<BindableString, TextWatcherAdapter> pair = (Pair) view.getTag(R.id.bound_observable);
if (pair == null || pair.first != bindableString) {
if (pair != null) {
view.removeTextChangedListener(pair.second);
}
TextWatcherAdapter watcher = new TextWatcherAdapter() {
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
bindableString.set(s.toString());
}
};
view.setTag(R.id.bound_observable, new Pair<>(bindableString, watcher));
view.addTextChangedListener(watcher);
}
String newValue = bindableString.get();
if (!view.getText().toString().equals(newValue)) {
view.setText(newValue);
}
}
@BindingAdapter("app:binding")
public static void bindRadioGroup(RadioGroup view, final BindableBoolean bindableBoolean) {
if (view.getTag(R.id.bound_observable) != bindableBoolean) {
view.setTag(R.id.bound_observable, bindableBoolean);
view.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override public void onCheckedChanged(RadioGroup group, int checkedId) {
bindableBoolean.set(checkedId == group.getChildAt(1).getId());
}
});
}
Boolean newValue = bindableBoolean.get();
((RadioButton) view.getChildAt(newValue ? 1 : 0)).setChecked(true);
}
@BindingAdapter("app:checked")
public static void bindCheckbox(CheckBox view, final BindableBoolean bindableBoolean) {
if (view.getTag(R.id.bound_observable) != bindableBoolean) {
view.setTag(R.id.bound_observable, bindableBoolean);
view.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
bindableBoolean.set(b);
}
});
}
Boolean newValue = bindableBoolean.get();
view.setChecked(newValue);
}
@BindingAdapter({"app:onClick"})
public static void bindOnClick(View view, final Runnable runnable) {
view.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
runnable.run();
}
});
}
}

View File

@ -0,0 +1,7 @@
package it.integry.integrywmsnative.core.di;
public class Objects {
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
}

View File

@ -0,0 +1,19 @@
package it.integry.integrywmsnative.core.di;
import android.text.Editable;
import android.text.TextWatcher;
public class TextWatcherAdapter implements TextWatcher
{
public void afterTextChanged(Editable editable)
{
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3)
{
}
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3)
{
}
}

View File

@ -0,0 +1,41 @@
package it.integry.integrywmsnative.core.di.binders;
import android.databinding.BindingAdapter;
import android.support.design.widget.TextInputEditText;
import android.support.v4.util.Pair;
import net.cachapa.expandablelayout.ExpandableLayout;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.di.BindableBoolean;
public class ExpandableLayoutBinders {
@BindingAdapter("app:el_expanded_bind")
public static void bindExpandableLayout(final ExpandableLayout view, final BindableBoolean bindableBoolean) {
Pair<BindableBoolean, ExpandableLayout.OnExpansionUpdateListener> pair = (Pair) view.getTag(R.id.bound_observable);
if (pair == null || pair.first != bindableBoolean) {
if (pair != null) {
view.setOnExpansionUpdateListener(null);
}
ExpandableLayout.OnExpansionUpdateListener watcher = new ExpandableLayout.OnExpansionUpdateListener() {
@Override
public void onExpansionUpdate(float expansionFraction, int state) {
if(view.isExpanded() == bindableBoolean.get()) return;
bindableBoolean.set(state == 1);
}
};
view.setTag(R.id.bound_observable, new Pair<>(bindableBoolean, watcher));
view.setOnExpansionUpdateListener(watcher);
}
boolean newValue = bindableBoolean.get();
if (!view.isExpanded() == newValue) {
if(newValue) view.expand(true);
else view.collapse(true);
}
}
}

View File

@ -0,0 +1,13 @@
package it.integry.integrywmsnative.core.di.binders;
import android.databinding.BindingAdapter;
import android.support.design.widget.TextInputLayout;
public class TextInputLayoutBinders {
@BindingAdapter("app:errorText")
public static void setErrorMessage(TextInputLayout view, String errorMessage) {
view.setError(errorMessage);
}
}

View File

@ -0,0 +1,25 @@
package it.integry.integrywmsnative.core.settings;
import java.util.List;
public class DBSettingsModel {
private List<String> availableProfiles = null;
private List<String> availableCodMdep = null;
public List<String> getAvailableProfiles() {
return availableProfiles;
}
public void setAvailableProfiles(List<String> availableProfiles) {
this.availableProfiles = availableProfiles;
}
public List<String> getAvailableCodMdep() {
return availableCodMdep;
}
public void setAvailableCodMdep(List<String> availableCodMdep) {
this.availableCodMdep = availableCodMdep;
}
}

View File

@ -0,0 +1,69 @@
package it.integry.integrywmsnative.core.settings;
import java.util.List;
import it.integry.integrywmsnative.core.REST.consumers.ISimpleOperationCallback;
import it.integry.integrywmsnative.core.REST.consumers.SystemRESTConsumer;
public class SettingsManager {
private static String TAG = "SETTINGS";
private static SettingsModel settingsModelIstance;
private static DBSettingsModel dbSettingsModelIstance;
private static boolean firstStart = false;
public static void init(){
settingsModelIstance = (SettingsModel) Stash.getObject(TAG, SettingsModel.class);
if(settingsModelIstance == null) {
settingsModelIstance = new SettingsModel();
settingsModelIstance.server = new SettingsModel.Server();
settingsModelIstance.user = new SettingsModel.User();
settingsModelIstance.userSession = new SettingsModel.UserSession();
dbSettingsModelIstance = new DBSettingsModel();
firstStart = true;
}
dbSettingsModelIstance = new DBSettingsModel();
}
public static SettingsModel i(){
return settingsModelIstance;
}
public static DBSettingsModel iDB(){
return dbSettingsModelIstance;
}
public static boolean isFirstStart(){
return firstStart;
}
public static void update(){
Stash.put(TAG, settingsModelIstance);
}
public static void reloadDBVariables(final ISimpleOperationCallback callback){
dbSettingsModelIstance = new DBSettingsModel();
SystemRESTConsumer.getAvailableProfiles(new ISimpleOperationCallback<List<String>>() {
@Override
public void onSuccess(List<String> availableProfiles) {
dbSettingsModelIstance.setAvailableProfiles(availableProfiles);
if(callback != null) callback.onSuccess(null);
}
@Override
public void onFailed(Exception ex) {
//BOH
if(callback != null) callback.onFailed(ex);
}
});
}
}

View File

@ -2,7 +2,26 @@ package it.integry.integrywmsnative.core.settings;
public class SettingsModel {
public static String currentUserCodMdep = "01";
public static String currentUsername = "Magazzino";
public Server server;
public User user;
public UserSession userSession;
public static class Server {
public String codAzienda;
public String host;
public int port;
}
public static class User {
public String username;
public String password;
}
public static class UserSession {
public String profileDB;
public String codMdep;
}
}

View File

@ -0,0 +1,241 @@
package it.integry.integrywmsnative.core.settings;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Set;
public class Stash {
private static Stash stash;
private SharedPreferences sp;
public static void init(Context context) {
stash = new Stash();
if (stash.sp == null) {
stash.sp = PreferenceManager.getDefaultSharedPreferences(context);
}
}
private static void checkfornull() {
if (stash == null)
throw new NullPointerException("Call init() method in application class");
}
//putString
public static void put(String key, String value) {
checkfornull();
try {
stash.sp.edit().putString(key, value).apply();
} catch (Exception e) {
e.printStackTrace();
}
}
//putStringSet
public static void put(String key, Set<String> value) {
checkfornull();
try {
stash.sp.edit().putStringSet(key, value).apply();
} catch (Exception e) {
e.printStackTrace();
}
}
//putInt
public static void put(String key, int value) {
checkfornull();
try {
stash.sp.edit().putInt(key, value).apply();
} catch (Exception e) {
e.printStackTrace();
}
}
//putLong
public static void put(String key, long value) {
checkfornull();
try {
stash.sp.edit().putLong(key, value).apply();
} catch (Exception e) {
e.printStackTrace();
}
}
//putFloat
public static void put(String key, float value) {
checkfornull();
try {
stash.sp.edit().putFloat(key, value).apply();
} catch (Exception e) {
e.printStackTrace();
}
}
//putBoolean
public static void put(String key, boolean value) {
checkfornull();
try {
stash.sp.edit().putBoolean(key, value).apply();
} catch (Exception e) {
e.printStackTrace();
}
}
//putObject or arrayList
public static void put(String key, Object value) {
checkfornull();
try {
Gson gson = new GsonBuilder().create();
stash.sp.edit().putString(key, gson.toJson(value).toString()).apply();
} catch (Exception e) {
e.printStackTrace();
}
}
//getString
public static String getString(String key, String defaultvalue) {
checkfornull();
try {
return stash.sp.getString(key, defaultvalue);
} catch (Exception e) {
e.printStackTrace();
return defaultvalue;
}
}
//getStringSet
public static Set<String> getStringSet(String key, Set<String> defaultvalue) {
checkfornull();
try {
return getStringSet(key, defaultvalue);
} catch (Exception e) {
e.printStackTrace();
return defaultvalue;
}
}
//getInt
public static int getInt(String key, int defaultvalue) {
checkfornull();
try {
return stash.sp.getInt(key, defaultvalue);
} catch (Exception e) {
e.printStackTrace();
return defaultvalue;
}
}
//getLong
public static long getLong(String key, long defaultvalue) {
checkfornull();
try {
return stash.sp.getLong(key, defaultvalue);
} catch (Exception e) {
e.printStackTrace();
return defaultvalue;
}
}
//getFloat
public static float getFloat(String key, float defaultvalue) {
checkfornull();
try {
return stash.sp.getFloat(key, defaultvalue);
} catch (Exception e) {
e.printStackTrace();
return defaultvalue;
}
}
//getBoolean
public static boolean getBoolean(String key, boolean defaultvalue) {
checkfornull();
try {
return stash.sp.getBoolean(key, defaultvalue);
} catch (Exception e) {
e.printStackTrace();
return defaultvalue;
}
}
//getObject
public static <T> Object getObject(String key, Class<?> tClass) {
checkfornull();
try {
Gson gson = new GsonBuilder().create();
return gson.fromJson(stash.sp.getString(key, ""), tClass);
} catch (Exception e) {
Log.e("gson", e.getMessage());
return "";
}
}
//getArrayList
public static <T> ArrayList<T> getArrayList(String key, Class<?> tClass) {
Log.e("_+_++__+_+", "" + tClass.getName());
Gson gson = new Gson();
String data = stash.sp.getString(key, "");
if (!data.trim().isEmpty()) {
Type type = new GenericType(tClass);
return (ArrayList<T>) gson.fromJson(data, type);
}
return new ArrayList<T>();
}
//clear single value
public static void clear(String key) {
checkfornull();
try {
stash.sp.edit().remove(key).apply();
} catch (Exception e) {
e.printStackTrace();
}
}
//clear all preference
public static void clearAll() {
checkfornull();
try {
stash.sp.edit().clear().apply();
} catch (Exception e) {
e.printStackTrace();
}
}
private static class GenericType implements ParameterizedType {
private Type type;
GenericType(Type type) {
this.type = type;
}
@Override
public Type[] getActualTypeArguments() {
return new Type[]{type};
}
@Override
public Type getRawType() {
return ArrayList.class;
}
@Override
public Type getOwnerType() {
return null;
}
// implement equals method too! (as per javadoc)
}
}

View File

@ -0,0 +1,41 @@
package it.integry.integrywmsnative.core.utility;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import it.integry.integrywmsnative.core.REST.consumers.ISingleValueOperationCallback;
public class UtilityServer {
public static void isHostReachable(final String serverAddress, final int serverTCPport, final ISingleValueOperationCallback<Boolean> callback){
new Thread(new Runnable() {
@Override
public void run() {
boolean connected = false;
Socket socket;
try {
socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(serverAddress, serverTCPport);
socket.connect(socketAddress, 10000);
if (socket.isConnected()) {
connected = true;
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
socket = null;
}
callback.onResult(connected);
}
}).start();
}
}

View File

@ -0,0 +1,16 @@
package it.integry.integrywmsnative.core.utility;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.settings.SettingsModel;
public class UtilitySettings {
public static void logout(){
SettingsManager.i().user = new SettingsModel.User();
SettingsManager.i().userSession = new SettingsModel.UserSession();
SettingsManager.update();
}
}

View File

@ -0,0 +1,14 @@
package it.integry.integrywmsnative.core.utility;
import android.app.Activity;
import android.view.Window;
import android.view.WindowManager;
public class UtilityWindow {
public static void maximizeToFullScreen(Activity activity){
activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}

View File

@ -0,0 +1,50 @@
package it.integry.integrywmsnative.core.wifi;
import android.app.Activity;
import android.widget.TextView;
import it.integry.integrywmsnative.core.REST.consumers.ISingleValueOperationCallback;
public class WiFiCheckerViewHolder implements ISingleValueOperationCallback<WiFiStatusChecker.SIGNAL>{
private TextView mWifiSignalTextView;
private WiFiStatusChecker mWiFiStatusChecker;
public WiFiCheckerViewHolder(Activity activity, int rsid){
mWifiSignalTextView = activity.findViewById(rsid);
mWiFiStatusChecker = new WiFiStatusChecker(activity);
}
public void startMonitoring(){
mWiFiStatusChecker.startMonitoring(this);
}
public void stopMonitoring(){
mWiFiStatusChecker.stopMonitoring();
}
@Override
public void onResult(WiFiStatusChecker.SIGNAL value) {
switch (value){
case EXCELLENT:
mWifiSignalTextView.setText("EXCELLENT");
break;
case GOOD:
mWifiSignalTextView.setText("GOOD");
break;
case FAIR:
mWifiSignalTextView.setText("FAIR");
break;
case WEAK:
mWifiSignalTextView.setText("WEAK");
break;
case NONE:
mWifiSignalTextView.setText("NONE");
break;
}
}
}

View File

@ -0,0 +1,70 @@
package it.integry.integrywmsnative.core.wifi;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import it.integry.integrywmsnative.core.REST.consumers.ISingleValueOperationCallback;
public class WiFiStatusChecker {
public enum SIGNAL {
EXCELLENT,
GOOD,
FAIR,
WEAK,
NONE
}
private ISingleValueOperationCallback<SIGNAL> mCallback;
private WifiManager mWifiManager;
private int mNumberOfLevels = 4;
private boolean shouldExecute = true;
private final long MILLIS_DELAY = 5 * 1000;
private Handler handler = new Handler();
private Runnable runnableCode = new Runnable() {
@Override
public void run() {
if(shouldExecute) {
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
int level = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), mNumberOfLevels);
SIGNAL signal;
switch (level){
case 0: signal = SIGNAL.WEAK; break;
case 1: signal = SIGNAL.FAIR; break;
case 2: signal = SIGNAL.GOOD; break;
case 3: signal = SIGNAL.EXCELLENT; break;
default: signal = SIGNAL.NONE; break;
}
mCallback.onResult(signal);
handler.postDelayed(this, MILLIS_DELAY);
}
}
};
public WiFiStatusChecker(Context context){
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
public void startMonitoring(ISingleValueOperationCallback<SIGNAL> callback){
this.mCallback = callback;
shouldExecute = true;
handler.post(runnableCode);
}
public void stopMonitoring(){
shouldExecute = false;
}
}

View File

@ -248,9 +248,20 @@ public class MainAccettazioneFragment extends Fragment implements ICheckBoxCallb
public void onLoadSuccess(final List<OrdineAccettazioneDTO> ordini) {
progress.dismiss();
int artsCounter = ordini.size();
List<String> ordersKeys = new ArrayList<>();
for(OrdineAccettazioneDTO ordine : ordini){
if(!ordersKeys.contains(ordine.data + " " + ordine.numero + " " + ordine.gestione)){
ordersKeys.add(ordine.data + " " + ordine.numero + " " + ordine.gestione);
}
}
DialogSimpleMessageHelper.makeInfoDialog(getActivity(),
getText(R.string.orders).toString(),
Html.fromHtml(String.format(getText(R.string.loaded_orders_message).toString(), ordini.size())),
Html.fromHtml(String.format(getActivity().getResources().getQuantityString(R.plurals.loaded_orders_message, ordersKeys.size()), ordersKeys.size())
+ "<br /><br />" +
"<b>" + artsCounter + "</b> " + getActivity().getResources().getQuantityString(R.plurals.available_articles, artsCounter)),
null,
new DialogInterface.OnClickListener() {
@Override

View File

@ -35,6 +35,7 @@ import it.integry.integrywmsnative.core.REST.consumers.ISimpleOperationCallback;
import it.integry.integrywmsnative.core.model.CommonModelConsts;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.model.secondary.GestioneEnum;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.settings.SettingsModel;
import it.integry.integrywmsnative.gest.accettazione.dto.OrdineAccettazioneDTO;
import it.integry.integrywmsnative.gest.accettazione_ordine_inevaso.core.AccettazioneOrdineInevasoHelper;
@ -218,8 +219,8 @@ public class AccettazioneOrdineInevasoActivity extends AppCompatActivity {
MtbColt mtbColt = new MtbColt();
mtbColt .setDataCollo(new Date())
.setGestione(GestioneEnum.ACQUISTO)
.setCodMdep(SettingsModel.currentUserCodMdep)
.setPreparatoDa(SettingsModel.currentUsername)
.setCodMdep(SettingsManager.i().userSession.codMdep)
.setPreparatoDa(SettingsManager.i().user.username)
.setOraInizPrep(new Date())
.setAnnotazioni(noteString)
.setOperation(CommonModelConsts.OPERATION.INSERT_OR_UPDATE);

View File

@ -0,0 +1,32 @@
package it.integry.integrywmsnative.gest.login;
import android.databinding.DataBindingUtil;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import it.integry.integrywmsnative.BR;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.utility.UtilityWindow;
import it.integry.integrywmsnative.databinding.ActivityLoginBinding;
import it.integry.integrywmsnative.gest.login.viewmodel.LoginViewModel;
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UtilityWindow.maximizeToFullScreen(this);
ActivityLoginBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
LoginViewModel loginViewModel = new LoginViewModel(this);
binding.setVariable(BR.loginViewModel, loginViewModel);
}
@Override
public void onBackPressed() {
// disable going back to the MainActivity
moveTaskToBack(true);
}
}

View File

@ -0,0 +1,113 @@
package it.integry.integrywmsnative.gest.login.core;
import android.content.Context;
import android.util.Log;
import it.integry.integrywmsnative.core.CommonConst;
import it.integry.integrywmsnative.core.REST.RESTBuilder;
import it.integry.integrywmsnative.core.REST.consumers.ISimpleOperationCallback;
import it.integry.integrywmsnative.core.REST.consumers.ISingleOperationDoubleCallback;
import it.integry.integrywmsnative.core.REST.model.EsitoType;
import it.integry.integrywmsnative.core.REST.model.ServiceRESTResponse;
import it.integry.integrywmsnative.gest.login.dto.LoginAziendaDTO;
import it.integry.integrywmsnative.gest.login.dto.LoginDTO;
import it.integry.integrywmsnative.gest.login.rest.LoginRESTConsumerService;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class LoginHelper {
private Context mContext;
private String mCodAzienda;
private String mUsername;
private String mPassword;
public LoginHelper(Context context, String codAzienda, String username, String password){
this.mContext = context;
this.mCodAzienda = codAzienda;
this.mUsername = username;
this.mPassword = password;
}
public void retrieveServerData(final ISimpleOperationCallback<LoginAziendaDTO> callback){
String host = CommonConst.Login.Azienda.host;
int port = CommonConst.Login.Azienda.port;
LoginRESTConsumerService service = RESTBuilder.getService(LoginRESTConsumerService.class, host, port, false);
service.loginAzienda(mCodAzienda).enqueue(new Callback<ServiceRESTResponse<LoginAziendaDTO>>() {
@Override
public void onResponse(Call<ServiceRESTResponse<LoginAziendaDTO>> call, Response<ServiceRESTResponse<LoginAziendaDTO>> response) {
if(response.isSuccessful()) {
if(response.body() != null) {
if(response.body().getEsito() == EsitoType.OK) {
callback.onSuccess(response.body().getDto());
} else {
Log.e("LoginAzienda", response.body().getErrorMessage());
callback.onFailed(new Exception(response.body().getErrorMessage()));
}
} else {
Log.e("LoginAzienda", response.message());
callback.onFailed(new Exception(response.message()));
}
} else {
Log.e("LoginAzienda", "Status " + response.code() + ": " + response.message());
callback.onFailed(new Exception("Status " + response.code() + ": " + response.message()));
}
}
@Override
public void onFailure(Call<ServiceRESTResponse<LoginAziendaDTO>> call, Throwable t) {
Log.e("LoginAzienda", t.toString());
callback.onFailed(new Exception(t));
}
});
}
public void doLogin(String host, int port, final ISimpleOperationCallback<LoginDTO> callback){
LoginRESTConsumerService service = RESTBuilder.getService(LoginRESTConsumerService.class, host, port, false);
service.login(mUsername, mPassword).enqueue(new Callback<ServiceRESTResponse<LoginDTO>>() {
@Override
public void onResponse(Call<ServiceRESTResponse<LoginDTO>> call, Response<ServiceRESTResponse<LoginDTO>> response) {
if(response.isSuccessful()) {
if(response.body() != null) {
if(response.body().getEsito() == EsitoType.OK) {
callback.onSuccess(response.body().getDto());
} else {
Log.e("Login", response.body().getErrorMessage());
callback.onFailed(new Exception(response.body().getErrorMessage()));
}
} else {
Log.e("Login", response.message());
callback.onFailed(new Exception(response.message()));
}
} else {
Log.e("Login", "Status " + response.code() + ": " + response.message());
callback.onFailed(new Exception("Status " + response.code() + ": " + response.message()));
}
}
@Override
public void onFailure(Call<ServiceRESTResponse<LoginDTO>> call, final Throwable t) {
Log.e("Login", t.toString());
callback.onFailed(new Exception(t));
}
});
}
}

View File

@ -0,0 +1,11 @@
package it.integry.integrywmsnative.gest.login.dto;
public class LoginAziendaDTO {
public String profileDb;
public String endpointRestApi;
public String phpApi;
public String repoPhoto;
public String endpointPvm;
}

View File

@ -0,0 +1,10 @@
package it.integry.integrywmsnative.gest.login.dto;
import java.util.List;
public class LoginDTO {
public String full_name;
public List<String> availableProfiles;
}

View File

@ -0,0 +1,21 @@
package it.integry.integrywmsnative.gest.login.rest;
import it.integry.integrywmsnative.core.REST.model.ServiceRESTResponse;
import it.integry.integrywmsnative.gest.login.dto.LoginAziendaDTO;
import it.integry.integrywmsnative.gest.login.dto.LoginDTO;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
public interface LoginRESTConsumerService {
@GET("loginAziendaWms")
Call<ServiceRESTResponse<LoginAziendaDTO>> loginAzienda(@Query("codHash") String codHash);
@POST("loginWeb")
Call<ServiceRESTResponse<LoginDTO>> login(@Query("username") String username, @Query("password") String password);
}

View File

@ -0,0 +1,236 @@
package it.integry.integrywmsnative.gest.login.viewmodel;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import it.integry.integrywmsnative.MainActivity;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.REST.consumers.ISimpleOperationCallback;
import it.integry.integrywmsnative.core.REST.consumers.ISingleValueOperationCallback;
import it.integry.integrywmsnative.core.di.BindableBoolean;
import it.integry.integrywmsnative.core.di.BindableString;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilityServer;
import it.integry.integrywmsnative.gest.login.LoginActivity;
import it.integry.integrywmsnative.gest.login.core.LoginHelper;
import it.integry.integrywmsnative.gest.login.dto.LoginAziendaDTO;
import it.integry.integrywmsnative.gest.login.dto.LoginDTO;
import it.integry.integrywmsnative.view.dialogs.DialogSimpleMessageHelper;
public class LoginViewModel {
private static final String TAG = LoginViewModel.class.getSimpleName();
public BindableString username = new BindableString();
public BindableString password = new BindableString();
public BindableString codAzienda = new BindableString();
public BindableBoolean customSettingsCheckboxEnabled = new BindableBoolean();
public BindableBoolean customSettingsCheckboxChecked = new BindableBoolean();
public BindableBoolean loginButtonEnabled = new BindableBoolean();
public BindableString usernameError = new BindableString();
public BindableString passwordError = new BindableString();
public BindableString codAziendaError = new BindableString();
private LoginActivity mActivity;
private ProgressDialog mProgress;
public LoginViewModel(LoginActivity activity) {
this.mActivity = activity;
loginButtonEnabled.set(true);
codAzienda.set(SettingsManager.i().server.codAzienda);
customSettingsCheckboxChecked.set(SettingsManager.i().server.host == null);
customSettingsCheckboxEnabled.set(SettingsManager.i().server.host != null);
}
public boolean validate() {
if (username.isEmpty() || username.get().length() < 3) {
usernameError.set(mActivity.getText(R.string.username_error_not_valid).toString());
return false;
} else usernameError.set(null);
if (codAzienda.isEmpty() || codAzienda.get().length() < 3) {
codAziendaError.set(mActivity.getText(R.string.server_cod_azienda_not_valid).toString());
return false;
} else codAziendaError.set(null);
return true;
}
public void login(boolean areValidData){
if(areValidData){
loginButtonEnabled.set(false);
mProgress = ProgressDialog.show(mActivity, mActivity.getText(R.string.waiting),
mActivity.getText(R.string.loading) + " ...", true);
final LoginHelper loginHelper = new LoginHelper(mActivity, codAzienda.get(), username.get(), password.get());
loginHelper.retrieveServerData(new ISimpleOperationCallback<LoginAziendaDTO>() {
@Override
public void onSuccess(LoginAziendaDTO value) {
final String serverEndpoint = value.endpointRestApi;
URL u;
try {
u = new URL(serverEndpoint);
} catch (final MalformedURLException e) {
e.printStackTrace();
onLoginFailed(new SpannableString(e.toString()));
return;
}
final String host = u.getHost();
final int port = u.getPort();
UtilityServer.isHostReachable(host, port, new ISingleValueOperationCallback<Boolean>() {
@Override
public void onResult(Boolean value) {
if(value){ //Is online
loginHelper.doLogin(host, port, new ISimpleOperationCallback<LoginDTO>() {
@Override
public void onSuccess(final LoginDTO value) {
SettingsManager.iDB().setAvailableProfiles(value.availableProfiles);
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
onLoginSuccess(
"Benvenuto",
Html.fromHtml("Ciao <b>" + value.full_name + "</b>, la Integry le augura di svolgere al meglio il suo lavoro"),
host, port, value.availableProfiles);
}
});
}
@Override
public void onFailed(final Exception ex) {
onLoginFailed(new SpannableString(ex.getMessage().toString()));
}
});
} else { //Is not online
onLoginFailed(Html.fromHtml(String.format(mActivity.getText(R.string.server_not_reachable).toString(), host, port)));
}
}
});
}
@Override
public void onFailed(Exception ex) {
onLoginFailed(Html.fromHtml(String.format(mActivity.getText(R.string.server_cod_azienda_not_valid).toString(), codAzienda)));
}
});
}
}
private void onLoginFailed(final Spanned message){
mProgress.dismiss();
loginButtonEnabled.set(false);
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
DialogSimpleMessageHelper.makeErrorDialog(
mActivity,
message,
null,
null).show();
}
});
}
private void onLoginSuccess(final String title, final Spanned message, final String host, final int port, final List<String> availableProfiles){
mProgress.dismiss();
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
DialogSimpleMessageHelper.makeSuccessDialog(
mActivity,
title,
message,
null,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
showProfileDBSelectionDialog(host, port, availableProfiles);
}
}).show();
}
});
}
private void showProfileDBSelectionDialog(final String host, final int port, final List<String> availableProfiles){
// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(R.string.action_choose_profile_db);
// add a list
String[] profiles = new String[availableProfiles.size()];
profiles = availableProfiles.toArray(profiles);
builder.setItems(profiles, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SettingsManager.i().userSession.profileDB = availableProfiles.get(which);
onLoginCompleted(host, port);
}
});
// create and show the alert dialog
AlertDialog dialog = builder.create();
dialog.show();
}
public void onLoginCompleted(String host, int port) {
loginButtonEnabled.set(true);
SettingsManager.i().server.codAzienda = codAzienda.get();
SettingsManager.i().server.host = host;
SettingsManager.i().server.port = port;
SettingsManager.i().user.username = username.get();
SettingsManager.i().user.password = password.get();
SettingsManager.update();
Intent myIntent = new Intent(mActivity, MainActivity.class);
mActivity.startActivity(myIntent);
mActivity.finish();
}
}

View File

@ -76,7 +76,7 @@ public class DialogSimpleMessageHelper {
case ERROR:
colorBackgroundTitle = ContextCompat.getColor(mContext, R.color.red_600);
titleIconRes = mContext.getResources().getDrawable(R.drawable.ic_error_white_24dp);
titleIconRes = mContext.getResources().getDrawable(R.drawable.ic_mood_bad_24dp);
break;
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#EFEFEF" />
<padding
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<corners android:radius="5dp" />
</shape>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="100dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="100dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM15.5,11c0.83,0 1.5,-0.67 1.5,-1.5S16.33,8 15.5,8 14,8.67 14,9.5s0.67,1.5 1.5,1.5zM8.5,11c0.83,0 1.5,-0.67 1.5,-1.5S9.33,8 8.5,8 7,8.67 7,9.5 7.67,11 8.5,11zM12,14c-2.33,0 -4.31,1.46 -5.11,3.5h10.22c-0.8,-2.04 -2.78,-3.5 -5.11,-3.5z"/>
</vector>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="636.577dp"
android:height="271.126dp"
android:viewportWidth="636.577"
android:viewportHeight="271.126">
<path
android:fillColor="#FF9900"
android:pathData="M207.414,61.361c-18.867-18.878-44.938-30.555-73.736-30.555c-12.746,0-24.957,2.287-36.245,6.474 l-8.88-23.535c14.332-5.453,29.88-8.438,46.125-8.438c35.734,0,68.094,14.445,91.559,37.814L207.414,61.361z" />
<path
android:fillColor="#349933"
android:pathData="M63.193,211.868c14.326,13.152,32.343,22.35,52.318,25.859l-4.326,24.957 c-24.722-4.521-46.996-16.049-64.689-32.449L63.193,211.868z" />
<path
android:fillColor="#0199CB"
android:pathData="M33.563,216.368C15.648,194.12,4.928,165.84,4.928,135.055c0-48.096,26.17-90.081,65.047-112.49 l12.32,21.762c-31.569,17.917-52.867,51.835-52.867,90.728c0,24.906,8.734,47.771,23.306,65.701L33.563,216.368z" />
<path
android:fillColor="#EC0200"
android:pathData="M131.927,239.29c0.582,0.01,1.166,0.016,1.75,0.016c24.691,0,47.377-8.586,65.238-22.932l15.982,20.666 c-22.076,17.391-49.938,27.766-80.221,27.766c-1.115,0-2.227-0.014-3.336-0.043L131.927,239.29z" />
<path
android:fillColor="#000000"
android:pathData="M101.414,95.458H75.426V72.165h25.987V95.458z M101.414,199.928H75.426v-93.78h25.987V199.928z" />
<path
android:fillColor="#000000"
android:pathData="M114.606,106.148h46.586c14.08,0,24.132,2.651,30.159,7.953c6.025,5.302,9.039,14.095,9.039,26.378v59.449H175.62v-56.406 c0-7.01-1.086-11.561-3.259-13.646c-2.173-2.086-6.534-3.129-13.081-3.129h-19.903v73.181h-24.771V106.148z" />
<path
android:fillColor="#000000"
android:pathData="M203.937,106.148h17.47V72.165h24.771v33.983h26.161v18.687h-26.161v37.894c0,6.953,1.187,11.777,3.563,14.471 c2.375,2.695,6.519,4.043,12.429,4.043h10.169v18.686H249.74c-9.156,0-16.166-2.533-21.033-7.605 c-4.867-5.068-7.301-12.326-7.301-21.771v-45.716h-17.47V106.148z" />
<path
android:fillColor="#000000"
android:pathData="M320.557,199.928c-15.529,0-27.277-3.955-35.244-11.863c-7.967-7.91-11.95-19.568-11.95-34.982 c0-15.412,3.998-27.087,11.994-35.027c7.996-7.938,19.729-11.907,35.2-11.907h36.156v19.556h-32.767 c-8.982,0-15.022,1.275-18.122,3.824c-3.1,2.55-4.767,7.158-4.997,13.82h55.886v19.555h-55.886 c0.23,6.723,1.782,11.314,4.649,13.775c2.869,2.465,8.966,3.695,18.296,3.695h32.94v19.555H320.557z" />
<path
android:fillColor="#000000"
android:pathData="M452.301,196.54c0,12.863-2.868,22.307-8.604,28.334c-5.736,6.025-14.688,9.039-26.856,9.039h-48.585v-19.035h44.326 c4.75,0,8.4-1.145,10.951-3.434c2.549-2.289,3.824-5.605,3.824-9.951v-1.564h-20.164c-10.43,0-17.935-0.781-22.511-2.346 c-4.578-1.564-8.809-4.229-12.689-7.996c-4.463-4.229-7.896-9.502-10.3-15.818c-2.404-6.314-3.606-13.152-3.606-20.512 c0-7.242,1.202-14.008,3.606-20.295c2.404-6.287,5.837-11.544,10.3-15.775c3.998-3.939,8.691-6.764,14.08-8.474 c5.389-1.708,12.429-2.564,21.12-2.564h45.108V196.54z M414.493,180.547h12.863v-54.322h-12.863 c-6.201,0-10.547,0.232-13.037,0.695c-2.492,0.465-4.665,1.247-6.519,2.347c-3.824,2.319-6.62,5.375-8.388,9.168 c-1.768,3.797-2.65,8.736-2.65,14.82c0,10.025,2.229,17.078,6.692,21.162C395.053,178.504,403.021,180.547,414.493,180.547z" />
<path
android:fillColor="#000000"
android:pathData="M464.711,106.148h41.632c9.734,0,16.557,1.753,20.469,5.258c3.91,3.506,5.866,9.634,5.866,18.382v15.645h-23.641v-12.082 c0-3.65-0.651-6.097-1.956-7.343c-1.303-1.246-4.273-1.869-8.908-1.869h-8.691v75.789h-24.771V106.148z" />
<path
android:fillColor="#000000"
android:pathData="M580.463,179.243h19.903v-73.094h24.771v91.26c0,12.398-2.898,21.582-8.691,27.551c-5.795,5.967-14.66,8.953-26.596,8.953 h-48.585v-19.035h44.326c4.75,0,8.4-1.145,10.951-3.434c2.549-2.289,3.824-5.605,3.824-9.951v-1.564h-21.902 c-14.023,0-24.019-2.766-29.985-8.301c-5.969-5.531-8.952-14.76-8.952-27.682v-57.797h24.51v55.885 c0,7.07,1.057,11.705,3.173,13.906C569.323,178.143,573.74,179.243,580.463,179.243z" />
</vector>

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="loginViewModel" type="it.integry.integrywmsnative.gest.login.viewmodel.LoginViewModel" />
</data>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="56dp"
android:paddingLeft="24dp"
android:paddingRight="24dp">
<ImageView android:src="@drawable/logo_integry_testo"
android:layout_width="wrap_content"
android:layout_height="72dp"
android:layout_marginBottom="24dp"
android:layout_gravity="center_horizontal" />
<!-- Username Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:errorText="@{loginViewModel.usernameError}"
app:hintTextAppearance="@style/hint_text">
<android.support.design.widget.TextInputEditText
android:id="@+id/input_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="Username"
app:binding="@{loginViewModel.username}"/>
</android.support.design.widget.TextInputLayout>
<!-- Password Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:hintTextAppearance="@style/hint_text"
app:errorText="@{loginViewModel.passwordError}"
app:passwordToggleEnabled="true">
<android.support.design.widget.TextInputEditText
android:id="@+id/input_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="Password"
app:binding="@{loginViewModel.password}"/>
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatCheckBox
android:id="@+id/login_checkbox_custom_server"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_customize_server_settings"
android:enabled="@{loginViewModel.customSettingsCheckboxEnabled}"
app:checked="@{loginViewModel.customSettingsCheckboxChecked}"/>
<net.cachapa.expandablelayout.ExpandableLayout
android:id="@+id/login_layout_server_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gray_detail_background"
app:el_duration="400"
app:el_expanded_bind="@{loginViewModel.customSettingsCheckboxChecked}"
android:paddingTop="6dp"
android:paddingBottom="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--Host Label-->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:errorText="@{loginViewModel.codAziendaError}"
app:hintTextAppearance="@style/hint_text">
<android.support.design.widget.TextInputEditText
android:id="@+id/input_cod_azienda"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:hint="Codice azienda"
app:binding="@{loginViewModel.codAzienda}"/>
</android.support.design.widget.TextInputLayout>
<!-- Host Label -->
<!--<android.support.design.widget.TextInputLayout-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_marginTop="8dp"-->
<!--app:hintTextAppearance="@style/hint_text">-->
<!--<android.support.design.widget.TextInputEditText-->
<!--android:id="@+id/iput_server_host"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:inputType="text"-->
<!--android:hint="Host" />-->
<!--</android.support.design.widget.TextInputLayout>-->
<!--&lt;!&ndash; Port Label &ndash;&gt;-->
<!--<android.support.design.widget.TextInputLayout-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_marginTop="8dp"-->
<!--app:hintTextAppearance="@style/hint_text">-->
<!--<android.support.design.widget.TextInputEditText-->
<!--android:id="@+id/iput_server_port"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:inputType="number|none"-->
<!--android:hint="Port" />-->
<!--</android.support.design.widget.TextInputLayout>-->
</LinearLayout>
</net.cachapa.expandablelayout.ExpandableLayout>
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_login"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:enabled="@{loginViewModel.loginButtonEnabled}"
app:onClick="@{() -> loginViewModel.login(loginViewModel.validate())}"
android:text="Login"/>
</LinearLayout>
</ScrollView>
</layout>

View File

@ -13,10 +13,111 @@
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.design.widget.TextInputEditText
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<net.cachapa.expandablelayout.ExpandableLayout
android:id="@+id/no_connection_top_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="hint" />
android:background="@drawable/gray_detail_background"
app:el_duration="400"
app:el_expanded="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="8dp"
android:background="@color/red_600">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:text="NESSUNA CONNESSIONE DISPONIBILE, RIPROVA"/>
</LinearLayout>
</net.cachapa.expandablelayout.ExpandableLayout>
<android.support.v7.widget.CardView
app:cardBackgroundColor="@android:color/white"
app:cardCornerRadius="4dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textColor="@android:color/black"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Informazioni generali"
android:textAllCaps="true"
android:textStyle="bold"/>
<LinearLayout
android:padding="15dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.constraint.Guideline
android:id="@+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.40"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="Segnale WI-FI"
android:textColor="@android:color/black"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/wifi_power"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:text="N/A"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="@+id/guideline1"
app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</FrameLayout>
</android.support.constraint.ConstraintLayout>

View File

@ -33,4 +33,13 @@
</menu>
</item>
<item android:title="Other">
<menu>
<item
android:id="@+id/nav_logout"
android:icon="@drawable/ic_logout_24dp"
android:title="Logout" />
</menu>
</item>
</menu>

View File

@ -8,12 +8,16 @@
<string name="accettazione_title_fragment">Accettazione</string>
<string name="accettazione_ordine_inevaso_title_empty">Ordine di accettazione</string>
<string name="accettazione_ordine_inevaso_title_multiple_order">Ordini di accettazione</string>
<string name="error">Errore</string>
<string name="error">Ops</string>
<string name="warning">Attenzione</string>
<string name="ok">OK</string>
<string name="abort">Annulla</string>
<string name="dispatched">Evasi</string>
<string name="action_settings">Impostazioni</string>
<string name="action_customize_server_settings">Personalizza impostazioni azienda</string>
<string name="no_description">Nessuna descrizione</string>
<string name="stock">Stock</string>
<string name="action_filter">Filtra</string>
@ -32,13 +36,31 @@
<item quantity="one">articolo</item>
<item quantity="other">articoli</item>
</plurals>
<plurals name="available_articles">
<item quantity="one">articolo disponibile</item>
<item quantity="other">articoli disponibili</item>
</plurals>
<plurals name="loaded_orders_message">
<item quantity="one"><![CDATA[&#200; stato caricato <b>%d</b> ordine]]></item>
<item quantity="other"><![CDATA[Sono stati caricati <b>%d</b> ordini]]></item>
</plurals>
<string name="action_close_ul">Chiudi UL</string>
<string name="already_read_articles">Articoli presenti</string>
<string name="orders">Ordini</string>
<string name="loaded_orders_message"><![CDATA[Sono stati caricati <b>%d</b> ordini]]></string>
<string name="articoli_in_collo_sheet_title"><![CDATA[Unità numero %d]]></string>
<string name="details_text">Dettagli</string>
<string name="date_text">Data</string>
<string name="position_text">Posizione</string>
<string name="prepared_by_text">Preparato da</string>
<string name="password_error_length">deve essere tra 3 e 30 caratteri</string>
<string name="username_error_not_valid">inserire un username valido</string>
<string name="server_cod_azienda_error_not_valid">inserire un codice azienda valido</string>
<string name="server_host_error_not_valid">inserire un host valido</string>
<string name="server_port_error_not_valid">inserire una porta valida</string>
<string name="server_cod_azienda_not_valid"><![CDATA[Il codice azienda <b>%s</b> non è valido. Controllalo e riprova]]></string>
<string name="server_not_reachable"><![CDATA[L\'host <b>%s</b> sulla porta <b>%d</b> non è al momento raggiungibile. Riprova più tardi]]></string>
<string name="action_choose_profile_db">Seleziona un database</string>
</resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="bound_observable" type="id" />
</resources>

View File

@ -5,6 +5,7 @@
<string name="navigation_drawer_close">Close navigation drawer</string>
<string name="action_settings">Settings</string>
<string name="action_customize_server_settings">Custom company settings</string>
<!-- Generic strings -->
<string name="waiting">Waiting</string>
@ -13,10 +14,10 @@
<string name="ord_acq_testata"><![CDATA[Pur. Ord. <b>%s</b> of <b>%s</b>]]></string>
<string name="accettazione_title_fragment">Acceptance</string>
<string name="accettazione_ordine_inevaso_title_empty">Acceptance order</string>
<string name="accettazione_title_fragment">Check in</string>
<string name="accettazione_ordine_inevaso_title_empty">Check in order</string>
<string name="accettazione_ordine_inevaso_title_multiple_order">Multiple acceptance orders</string>
<string name="error">Error</string>
<string name="error">Ops</string>
<string name="warning">Warning</string>
<string name="ok">OK</string>
<string name="abort">Abort</string>
@ -43,14 +44,32 @@
<item quantity="one">item</item>
<item quantity="other">items</item>
</plurals>
<plurals name="available_articles">
<item quantity="one">available item</item>
<item quantity="other">available items</item>
</plurals>
<plurals name="loaded_orders_message">
<item quantity="one"><![CDATA[<b>%d</b> order loaded]]></item>
<item quantity="other"><![CDATA[<b>%d</b> orders loaded]]></item>
</plurals>
<string name="action_close_ul">Close LU</string>
<string name="already_read_articles">Submitted items</string>
<string name="orders">Orders</string>
<string name="loaded_orders_message"><![CDATA[<b>%d</b> orders loaded]]></string>
<string name="articoli_in_collo_sheet_title"><![CDATA[Unit #%d]]></string>
<string name="details_text">Details</string>
<string name="date_text">Date</string>
<string name="position_text">Position</string>
<string name="prepared_by_text">Prepared by</string>
<string name="password_error_length">between 3 and 30 alphanumeric characters</string>
<string name="username_error_not_valid">enter a valid username</string>
<string name="server_cod_azienda_error_not_valid">enter a valid code</string>
<string name="server_host_error_not_valid">enter a valid host</string>
<string name="server_port_error_not_valid">enter a valid port</string>
<string name="server_cod_azienda_not_valid"><![CDATA[Code <b>%s</b> is not valid. Check and retry later]]></string>
<string name="server_not_reachable"><![CDATA[The host <b>%s</b> on port <b>%d</b> is not reachable. Retry later]]></string>
<string name="action_choose_profile_db">Choose a database</string>
</resources>

View File

@ -30,6 +30,10 @@
<item name="colorButtonNormal">@android:color/transparent</item>
</style>
<style name="hint_text" parent="TextAppearance.Design.Hint">
<item name="android:textColor">@color/colorPrimary</item>
</style>

View File

@ -11,6 +11,9 @@
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
android.databinding.enableV2=true
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects