commit 8d1ab2ccc6e719829eac34510cb88e1cb944ed53 Author: dolivaresr Date: Thu May 23 08:24:38 2024 -0600 inicial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b75303 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml new file mode 100644 index 0000000..23b2e1f --- /dev/null +++ b/.idea/appInsightsSettings.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..ab12f90 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..8e78a60 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..d212623 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f267912 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Almacen.zip b/Almacen.zip new file mode 100644 index 0000000..c9f372d Binary files /dev/null and b/Almacen.zip differ diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..2b8bb89 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,72 @@ +apply plugin: 'com.android.application' + +android { + + namespace 'jumapacelaya.gob.mx.almacen' + compileSdk 34 + defaultConfig { + applicationId "jumapacelaya.gob.mx.almacen" + minSdkVersion 23 + targetSdkVersion 33 + versionCode 1 + versionName "1.0" + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.debug + } + } + compileOptions { + sourceCompatibility = 11 + targetCompatibility = 11 + } +} + + + +repositories { + mavenCentral() + + maven { + url "http://dl.bintray.com/journeyapps/maven" + allowInsecureProtocol = true + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.12.0' + implementation 'androidx.recyclerview:recyclerview:1.3.2' + implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + implementation 'com.google.code.gson:gson:2.10.1' + implementation 'com.android.volley:volley:1.2.1' + implementation 'androidx.room:room-runtime:2.6.1' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + annotationProcessor 'androidx.room:room-compiler:2.6.1' + + implementation('com.journeyapps:zxing-android-embedded:3.6.0') { transitive = false } + implementation 'com.google.zxing:core:3.3.2' + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + + + implementation 'androidx.core:core:1.13.1' + implementation 'com.daimajia.easing:library:2.0@aar' + implementation 'com.daimajia.androidanimations:library:2.3@aar' + + implementation "androidx.compose.material3:material3:1.2.1" + + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation 'com.google.code.gson:gson:2.10.1' + + +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c6df613 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_codebar_icon-web.png b/app/src/main/ic_codebar_icon-web.png new file mode 100644 index 0000000..fa114ec Binary files /dev/null and b/app/src/main/ic_codebar_icon-web.png differ diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ConteoActivity.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ConteoActivity.java new file mode 100644 index 0000000..04edf1d --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ConteoActivity.java @@ -0,0 +1,635 @@ +package jumapacelaya.gob.mx.almacen; + +import android.Manifest; +import android.app.ActivityOptions; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.AsyncTask; + +import androidx.annotation.NonNull; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.core.app.ActivityCompat; +import androidx.appcompat.app.AppCompatActivity; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.provider.Settings; +import android.telephony.TelephonyManager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.AuthFailureError; +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonObjectRequest; +import com.android.volley.toolbox.Volley; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.Serializable; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import jumapacelaya.gob.mx.almacen.bean.Conteo; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.bean.Inventario; +import jumapacelaya.gob.mx.almacen.dao.AppDatabase; +import jumapacelaya.gob.mx.almacen.dao.inventarioDao; +import jumapacelaya.gob.mx.almacen.request.DetalleRequest; +import jumapacelaya.gob.mx.almacen.ui.main.Constant; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class ConteoActivity extends AppCompatActivity { + + ConstraintLayout root_conteo_layout; + Spinner cbxConteo; + Spinner cbxInventarios; + TextView lbtitle; + Button btniniciar; + + String imei; + private final int MY_PERMISSIONS_REQUEST_STATUS = 80; + + inventarioDao database; + ArrayAdapter dataAdapter; + ArrayAdapter dataAdapterinv; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_conteo); + + root_conteo_layout = findViewById(R.id.root_conteo_layout); + cbxConteo = findViewById(R.id.cbxConteos); + cbxInventarios = findViewById(R.id.cbxInventarios); + lbtitle = findViewById(R.id.lbConteo); + btniniciar = findViewById(R.id.btnIniciar); + + database = AppDatabase.getAppDatabaseDB(getApplicationContext()).inventarioDao(); + + /*android.support.v7.app.ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setBackgroundDrawable(new ColorDrawable(R.drawable.gradient_fondo)); + actionBar.setElevation(0); + + //Activar Flecha atras + //actionBar.setDisplayHomeAsUpEnabled(true); + //actionBar.setTitle("Predio :" + predioLectura.getPredioid()); + }*/ + + /*AnimationDrawable animDrawable = (AnimationDrawable) root_conteo_layout.getBackground(); + animDrawable.setEnterFadeDuration(10); + animDrawable.setExitFadeDuration(5000); + animDrawable.start();*/ + + btniniciar.setOnClickListener(e -> { + if(cbxConteo.getSelectedItem() != null) + ConteoActivity.this.onClick(e); + }); + + cbxInventarios.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int i, long l) { + Inventario inv = (Inventario) adapterView.getSelectedItem(); + mostrarConteo(inv.getInventariopk()); + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + + } + }); + + cargarPreferencias(); + + } + + private void onClick(View view){ + //Obtenemos los articulo para el conteo desde DB + loadArticulosConteo( ((Inventario)cbxInventarios.getSelectedItem()).getInventariopk()); + Conteo c= (Conteo) cbxConteo.getSelectedItem(); + + Intent intent = new Intent(ConteoActivity.this, MainActivity.class); + intent.putExtra(Constant.CONTEODET,(Serializable) c); + + startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(ConteoActivity.this).toBundle()); + } + + @Override + protected void onStart() { + super.onStart(); + cargarPreferencias(); + mostrarInventarios(); + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_reload, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + int idxml = R.id.action_reload; + + if (id == idxml) { + mostrarInventarios(); + return true; + } + + return true; + } + + private void cargarPreferencias() { + imei = getIMEI(); + } + + private void mostrarInventarios(){ + JSONObject jsonObject = new JSONObject(); + + if (imei != null) { + + try { + jsonObject.put("imei", getIMEI()); + JsonObjectRequest requestarr = new JsonObjectRequest(Request.Method.POST, restAlmacen.instance(this).URL_inventarios, jsonObject, + s -> { + try { + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + executor.execute(() -> { + String msg; + boolean flag; + + try { + if (s.has("inventarios")) { + saveInventarios(s); + } else { + throw new Exception("no se encontro información de predios en la consulta"); + } + } catch (Exception ex) { + System.out.println(ex.getMessage()); + msg = ex.getMessage(); + flag = true; + } + + + handler.post(() -> { + loadComboboxInv(); + }); + }); + + + + } catch (Exception e) { + Toast.makeText(ConteoActivity.this, "Incorrect Details", Toast.LENGTH_LONG).show(); + loadComboboxInv(); + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + if(error.getMessage() == null) { + if(error.networkResponse != null){ + try { + if (error.networkResponse.headers.containsKey("Content-Type") && error.networkResponse.headers.get("Content-Type").equals("application/json")) + { + JSONObject json = new JSONObject(new String(error.networkResponse.data)); + + Toast.makeText(getApplicationContext(), json.getString("message"), Toast.LENGTH_LONG).show(); + }else{ + Toast.makeText(getApplicationContext(), "Metodo no Permitido, " + error.networkResponse.headers.get("X-Android-Response-Source"), Toast.LENGTH_LONG).show(); + } + } catch (JSONException e) { + Toast.makeText(getApplicationContext(), "Unable to connect to server, try again later", Toast.LENGTH_LONG).show(); + } + + }else { + Toast.makeText(getApplicationContext(), "Unable to connect to server, try again later", Toast.LENGTH_LONG).show(); + } + }else{ + Log.d("Volley Error:", "Volley Error:" + (error.getMessage() == null?"": error.getMessage()) + ", Code:" + (error.networkResponse == null? "": error.networkResponse.statusCode) ); + + if(error.networkResponse != null) { + switch (error.networkResponse.statusCode) { + case 401: + Toast.makeText(getApplicationContext(), "No tiene permiso para realizar esta operación", Toast.LENGTH_LONG).show(); + break; + case 404: + Toast.makeText(getApplicationContext(), "Servicio tiene Errores para la Solicitud.", Toast.LENGTH_LONG).show(); + break; + default: + Toast.makeText(getApplicationContext(), "Unable to connect to server. codigo :" + error.networkResponse.statusCode, Toast.LENGTH_LONG).show(); + + } + }else{ + Toast.makeText(getApplicationContext(), (error.getMessage() == null?"Unable to connect to server": error.getMessage()) , Toast.LENGTH_LONG).show(); + } + } + + //cargar informacion db si existe en el spinner + loadComboboxInv(); + + } + }); + + RequestQueue rQueue = Volley.newRequestQueue(ConteoActivity.this); + rQueue.add(requestarr); + + + } catch (JSONException e) { + Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + loadComboboxInv(); + } + } else { + Toast.makeText(getApplicationContext(), "No se tiene permiso para obtener informacion sin IMEI", Toast.LENGTH_LONG).show(); + } + } + + private void mostrarConteo(final int inventariopk){ + JSONObject jsonObject = new JSONObject(); + + if (imei != null) { + + try { + jsonObject.put("imei", getIMEI()); + jsonObject.put("inventariopk", inventariopk); + + + JsonObjectRequest requestarr = new JsonObjectRequest(Request.Method.POST, restAlmacen.instance(this).URL_conteos, jsonObject, + s -> { + try { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + executor.execute(() -> { + String msg; + boolean flag; + + try { + if (s.has("conteos")) { + saveConteos(s); + + } else { + throw new Exception("no se encontro información de predios en la consulta"); + } + } catch (Exception ex) { + System.out.println(ex.getMessage()); + msg = ex.getMessage(); + flag = true; + } + + + handler.post(() -> { + loadCombobox(inventariopk); + }); + }); + + + + } catch (Exception e) { + Toast.makeText(ConteoActivity.this, "Incorrect Details", Toast.LENGTH_LONG).show(); + loadCombobox(inventariopk); + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + if(error.getMessage() == null) { + if(error.networkResponse != null){ + try { + if (error.networkResponse.headers.containsKey("Content-Type") && error.networkResponse.headers.get("Content-Type").equals("application/json")) + { + JSONObject json = new JSONObject(new String(error.networkResponse.data)); + + Toast.makeText(getApplicationContext(), json.getString("message"), Toast.LENGTH_LONG).show(); + }else{ + Toast.makeText(getApplicationContext(), "Metodo no Permitido, " + error.networkResponse.headers.get("X-Android-Response-Source"), Toast.LENGTH_LONG).show(); + } + } catch (JSONException e) { + Toast.makeText(getApplicationContext(), "Unable to connect to server, try again later", Toast.LENGTH_LONG).show(); + } + + }else { + Toast.makeText(getApplicationContext(), "Unable to connect to server, try again later", Toast.LENGTH_LONG).show(); + } + }else{ + Log.d("Volley Error:", "Volley Error:" + (error.getMessage() == null?"": error.getMessage()) + ", Code:" + (error.networkResponse == null? "": error.networkResponse.statusCode) ); + + if(error.networkResponse != null) { + switch (error.networkResponse.statusCode) { + case 401: + Toast.makeText(getApplicationContext(), "No tiene permiso para realizar esta operación", Toast.LENGTH_LONG).show(); + break; + case 404: + Toast.makeText(getApplicationContext(), "Servicio tiene Errores para la Solicitud.", Toast.LENGTH_LONG).show(); + break; + default: + Toast.makeText(getApplicationContext(), "Unable to connect to server. codigo :" + error.networkResponse.statusCode, Toast.LENGTH_LONG).show(); + + } + }else{ + Toast.makeText(getApplicationContext(), (error.getMessage() == null?"Unable to connect to server": error.getMessage()) , Toast.LENGTH_LONG).show(); + } + } + + //cargar informacion db si existe en el spinner + loadCombobox(inventariopk); + + } + }); + + RequestQueue rQueue = Volley.newRequestQueue(ConteoActivity.this); + rQueue.add(requestarr); + + + } catch (JSONException e) { + Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + loadCombobox(inventariopk); + } + } else { + Toast.makeText(getApplicationContext(), "No se tiene permiso para obtener informacion sin IMEI", Toast.LENGTH_LONG).show(); + } + } + + private void loadCombobox(int inventarioPk) { + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + executor.execute(() -> { + + //Background work here + String msg; + boolean flag; + List db = null; + + //load database data + try { + //load database data + db = database.listInventariosInv(inventarioPk); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + msg = ex.getMessage(); + flag = true; + } + + + List finalDb = db; + handler.post(() -> { + if(finalDb != null) { + + // Creating adapter for spinner + dataAdapter = new ArrayAdapter(ConteoActivity.this, + android.R.layout.simple_spinner_item, finalDb); + + dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + // attaching data adapter to spinner + cbxConteo.setAdapter(dataAdapter); + } + }); + }); + + } + + private void loadComboboxInv() { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + executor.execute(() -> { + //Background work here + String msg; + boolean flag; + List db = null; + + //load database data + try { + //load database data + db = database.listInventariosActivos(); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + msg = ex.getMessage(); + flag = true; + } + + + List finalDb = db; + handler.post(() -> { + if(finalDb != null) { + // Creating adapter for spinner + dataAdapterinv = new ArrayAdapter<>(ConteoActivity.this, + android.R.layout.simple_spinner_item, finalDb); + + dataAdapterinv.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + // attaching data adapter to spinner + cbxInventarios.setAdapter(dataAdapterinv); + + if(cbxInventarios.getSelectedItem() != null) + loadCombobox(((Inventario)cbxInventarios.getSelectedItem()).getInventariopk() ); + } + }); + }); + + } + + private void saveConteos(JSONObject s) throws JSONException { + JSONArray jsonconteos = s.getJSONArray("conteos"); + + final List l; + Type listType = new TypeToken>() { + }.getType(); + + Gson gson= new GsonBuilder().setDateFormat("yyyy-MM-dd").create(); + + l = gson.fromJson(jsonconteos.toString(), listType); + + //insertar en lote desde el primer registro + if (l.size() >= 1) { + //conteos.clear(); + //si existe se borra la informacion + for (Conteo c : l) { + database.upsertConteo(c); + //conteos.add(c); + } + } + } + + private void saveInventarios(JSONObject s) throws JSONException { + JSONArray jsoninventario = s.getJSONArray("inventarios"); + + final List l; + Type listType = new TypeToken>() { + }.getType(); + + Gson gson= new GsonBuilder().setDateFormat("dd/MM/yyyy").create(); + + l = gson.fromJson(jsoninventario.toString(), listType); + + //estado a C + database.updateInventarioN(); + + //insertar en lote desde el primer registro + if (l.size() >= 1) { + //conteos.clear(); + //si existe se borra la informacion + for (Inventario c : l) { + database.upsertInventario(c); + //conteos.add(c); + } + } + } + + public String getIMEI() { + String ID = Settings.Secure.getString(getContentResolver(), + Settings.Secure.ANDROID_ID); + + return ID; + } + + // + // Carga los articulos del conteo + private void loadArticulosConteo(final int inventarioPk){ + JSONObject jsonObject = new JSONObject(); + + //Obtener el conteo seleccionado + Conteo conteo = (Conteo) cbxConteo.getSelectedItem(); + + if (imei != null && conteo != null) { + + // try { + /*jsonObject.put("imei", getIMEI()); + jsonObject.put("invanteriopk", inventarioPk); + jsonObject.put("conteopk", conteo.getConteopk()); + jsonObject.put("foliopk", 0);*/ + + //RequestQueue rQueue = Volley.newRequestQueue(this); + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(restAlmacen.instance(this).BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .build(); + + InventarioService postService = retrofit.create(InventarioService.class); + Call< List > call = postService.getDetalleConteo(new DetalleRequest(getIMEI(), inventarioPk, conteo.getConteopk(), 0)); + + call.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + + executor.execute(() -> { + String msg = ""; + boolean flag = false; + + try { + if (response.body() != null) { + saveArticulosObj( response.body()); + } else { + throw new Exception("no se encontro información de inventario"); + } + } catch (Exception ex) { + System.out.println(ex.getMessage()); + msg = ex.getMessage(); + flag = true; + } + + boolean finalFlag = flag; + String finalMsg = msg; + handler.post(() -> { + if (finalFlag) + Toast.makeText(ConteoActivity.this, finalMsg, Toast.LENGTH_LONG).show(); + }); + }); + } + + @Override + public void onFailure(Call> call, Throwable t) { + Toast.makeText(ConteoActivity.this, t.getMessage(), Toast.LENGTH_LONG).show(); + } + }); + + } else { + Toast.makeText(getApplicationContext(), "No se tiene permiso para obtener informacion sin IMEI", Toast.LENGTH_LONG).show(); + } + } + + private void saveArticulos(JSONObject s) throws JSONException { + JSONArray jsonconteos = s.getJSONArray("inventario"); + + final List l; + Type listType = new TypeToken>() { + }.getType(); + + Gson gson= new GsonBuilder().setDateFormat("yyyy-MM-dd").create(); + + l = gson.fromJson(jsonconteos.toString(), listType); + + //insertar en lote desde el primer registro + if (l.size() >= 1) { + DetalleConteo c1 = l.get(0); + database.clearConteo(c1.getAlmacenpk(), c1.getConteopk()); + //conteos.clear(); + //si existe se borra la informacion + for (DetalleConteo c : l) { + c.setEnviado(false); + if(database.exist(c.getAlmacenpk(),c.getConteopk(),c.getFolio(),c.getArticulopk(), c.getInventariopk()) != null) + database.updateCantidad(c.getCantidad(),c.getAlmacenpk(), c.getConteopk(),c.getFolio(), c.getArticulopk(), c.getInventariopk(), false, false ); + else + database.isertDetalleConteo(c); + //conteos.add(c); + } + } + } + + private void saveArticulosObj(List l) { + + + //insertar en lote desde el primer registro + if (!l.isEmpty()) { + DetalleConteo c1 = l.get(0); + database.clearConteo(c1.getAlmacenpk(), c1.getConteopk()); + //conteos.clear(); + //si existe se borra la informacion + for (DetalleConteo c : l) { + c.setEnviado(false); + if(database.exist(c.getAlmacenpk(),c.getConteopk(),c.getFolio(),c.getArticulopk(), c.getInventariopk()) != null){ + //revisar que si enciado es 0 entocens no realiza actualizacion + if(database.existSinenviar(c.getAlmacenpk(),c.getConteopk(),c.getFolio(),c.getArticulopk(), c.getInventariopk(), false, true) == null) { + database.updateCantidad(c.getCantidad(), c.getAlmacenpk(), c.getConteopk(), c.getFolio(), c.getArticulopk(), c.getInventariopk(), false, false); + } + }else { + database.isertDetalleConteo(c); + } + } + } + } + +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/InventarioService.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/InventarioService.java new file mode 100644 index 0000000..60f5538 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/InventarioService.java @@ -0,0 +1,24 @@ +package jumapacelaya.gob.mx.almacen; + +import java.util.List; + +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.bean.Inventario; +import jumapacelaya.gob.mx.almacen.request.DetalleRequest; +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.POST; + +public interface InventarioService { + + String API_ROUTE = "/rest/almservice/listConteoArticulo"; + String API_UPDINVENTARIO = "/rest/almservice/saveFolio"; + + @POST(API_ROUTE) + Call< List > getDetalleConteo(@Body DetalleRequest body); + + @POST(API_UPDINVENTARIO) + Call updateDetalle(@Body DetalleConteo body); + +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/LocalDateDeserializer.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/LocalDateDeserializer.java new file mode 100644 index 0000000..1f025e4 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/LocalDateDeserializer.java @@ -0,0 +1,25 @@ +package jumapacelaya.gob.mx.almacen; + +import android.os.Build; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; + +import java.lang.reflect.Type; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + +public class LocalDateDeserializer implements JsonDeserializer { + @Override + public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return LocalDate.parse(json.getAsString(), + DateTimeFormatter.ofPattern("d-MMM-yyyy").withLocale(new Locale("es","MX"))); + } + return null; + } +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/MainActivity.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/MainActivity.java new file mode 100644 index 0000000..59ee4b2 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/MainActivity.java @@ -0,0 +1,356 @@ +package jumapacelaya.gob.mx.almacen; + +import static android.widget.Toast.LENGTH_SHORT; + +import android.Manifest; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; + +import com.google.android.material.appbar.MaterialToolbar; +import com.google.android.material.badge.BadgeDrawable; +import com.google.android.material.badge.BadgeUtils; +import com.google.android.material.badge.ExperimentalBadgeUtils; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.tabs.TabLayout; + +import androidx.annotation.NonNull; +import androidx.annotation.OptIn; +import androidx.viewpager.widget.ViewPager; +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Handler; +import android.os.Looper; +import android.view.MenuItem; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.Toast; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentResult; + +import java.lang.ref.WeakReference; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import jumapacelaya.gob.mx.almacen.bean.ArticuloScan; +import jumapacelaya.gob.mx.almacen.bean.Conteo; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.dao.AppDatabase; +import jumapacelaya.gob.mx.almacen.dao.inventarioDao; +import jumapacelaya.gob.mx.almacen.ui.main.avance.AvanceFragment; +import jumapacelaya.gob.mx.almacen.ui.main.Constant; +import jumapacelaya.gob.mx.almacen.ui.main.PendienteFragment; +import jumapacelaya.gob.mx.almacen.ui.main.PlaceholderFragment; +import jumapacelaya.gob.mx.almacen.ui.main.SectionsPagerAdapter; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + + +public class MainActivity extends AppCompatActivity implements PendienteFragment.OnListFragmentInteractionListener, AvanceFragment.OnListAvanceFragmentInteractionListener { + private static final int REQUEST_CAMERARESULT=201; + + private Conteo conteo; + TabLayout tabs; + + private MaterialToolbar topAppBar; + private BadgeDrawable badge; + private Animation rotation; + private MenuItem refreshItem; + inventarioDao database; + + @OptIn(markerClass = ExperimentalBadgeUtils.class) + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle bundle = getIntent().getExtras(); + conteo = (Conteo) bundle.get(Constant.CONTEODET); + + setContentView(R.layout.activity_main); + SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager()); + ViewPager viewPager = findViewById(R.id.view_pager); + viewPager.setAdapter(sectionsPagerAdapter); + viewPager.setOffscreenPageLimit(10); + tabs = findViewById(R.id.tabs); + tabs.setupWithViewPager(viewPager); + + topAppBar = findViewById(R.id.topAppBar); + + topAppBar.inflateMenu(R.menu.top_app_bar); + topAppBar.setOnMenuItemClickListener(item -> { + if (item.getItemId() == R.id.refresh) { + actualizarPendientes(); + return true; + } + return true; + }); + + + badge = BadgeDrawable.create(this); + BadgeUtils.attachBadgeDrawable(badge, topAppBar, R.id.refresh); + + rotation = AnimationUtils.loadAnimation(this, R.anim.anim_rotate); + rotation.setRepeatCount(Animation.INFINITE); + + + if(conteo != null){ + topAppBar.setTitle("Almacen " + conteo.getNombre()); + } + + FloatingActionButton fab = findViewById(R.id.fab); + + fab.setOnClickListener(view -> { + IntentIntegrator scanIntegrator = new IntentIntegrator(MainActivity.this); + //IntentIntegrator scanIntegrator = IntentIntegrator.forSupportFragment(this); + + //scanIntegrator.setDesiredBarcodeFormats(CustomIntegrator.PDF_417); + scanIntegrator.setPrompt("Escanear Articulo"); + //scanIntegrator.setCameraId(0); // Use a specific camera of the device + scanIntegrator.setOrientationLocked(false); + + /*scanIntegrator.setOrientationLocked(true); + scanIntegrator.setBeepEnabled(true); + scanIntegrator.setCaptureActivity(CaptureActivityPortrait.class);*/ + scanIntegrator.initiateScan(); + }); + + database = AppDatabase.getAppDatabaseDB(getApplicationContext()).inventarioDao(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if(getApplicationContext().checkSelfPermission(Manifest.permission.CAMERA)== PackageManager.PERMISSION_GRANTED){ + ///method to get Images + + }else{ + if(shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)){ + Toast.makeText(getApplicationContext(),"Your Permission is needed to get access the camera",Toast.LENGTH_LONG).show(); + } + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA}, REQUEST_CAMERARESULT); + } + }else{ + + } + + //refreshBadge(); + } + + @Override + protected void onResume() { + super.onResume(); + + refreshBadge(); + } + + public void refreshBadge(){ + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + View refreshitem = findViewById(R.id.refresh); + + refreshitem.startAnimation(rotation); + + executor.execute(() -> { + int cantidad = 0; + try { + cantidad = database.pendienteEnviar(conteo.getConteopk(), conteo.getInventariopk(), false, true); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + Toast.makeText(MainActivity.this, "Error al consultar los pendietes", Toast.LENGTH_LONG).show(); + } + + int finalCantidad = cantidad; + handler.post(() -> { + badge.clearNumber(); + badge.setText(String.valueOf(finalCantidad)); + rotation.cancel(); + }); + }); + } + + private void actualizarPendientes(){ + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + View refreshitem = findViewById(R.id.refresh); + refreshitem.startAnimation(rotation); + + executor.execute(() -> { + + List detalles = database.lstpendienteEnviar(conteo.getConteopk(), conteo.getInventariopk(), false, true); + + GsonBuilder builder = new GsonBuilder(); + builder.excludeFieldsWithoutExposeAnnotation(); + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(restAlmacen.instance(MainActivity.this).BASE_URL) + .addConverterFactory(GsonConverterFactory.create(builder.create())) + .build(); + + InventarioService postService = retrofit.create(InventarioService.class); + + if(detalles.size() == 0) + refreshBadge(); + + for(DetalleConteo d:detalles){ + Call call = postService.updateDetalle(d); + call.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + + executor.execute(() -> { + String msg = ""; + boolean flag = false; + if (response.code() == 200){ + d.setEnviado(true); + database.updateDetalle(d); + + } + + handler.post(() -> { + refreshBadge(); + }); + }); + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_LONG).show(); + refreshBadge(); + } + }); + } + + }); + } + + + @Override + public void onListFragmentInteraction(DetalleConteo item) { + //Toast.makeText(MainActivity.this, item.getDescFamilia() + ":" + item.getFolio() + " - " +item.getDescArticulo(), Toast.LENGTH_LONG).show(); + + String tag = "android:switcher:" + R.id.view_pager + ":" + 0; + PlaceholderFragment ff = (PlaceholderFragment) getSupportFragmentManager().findFragmentByTag(tag); + ff.displayReceivedData(item); + + TabLayout.Tab tab= tabs.getTabAt(0); + tab.select(); + + } + + @Override + public void onListAvanceFragmentInteraction(DetalleConteo item) { + //Toast.makeText(MainActivity.this, item.getDescFamilia() + ":" + item.getFolio() + " - " +item.getDescArticulo(), Toast.LENGTH_LONG).show(); + + String tag = "android:switcher:" + R.id.view_pager + ":" + 0; + PlaceholderFragment f = (PlaceholderFragment) getSupportFragmentManager().findFragmentByTag(tag); + f.displayReceivedData(item); + + TabLayout.Tab tab= tabs.getTabAt(0); + tab.select(); + + } + + public Conteo getConteo(){ + return conteo; + } + + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + try { + final IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); + if(scanResult != null) + handleResult(scanResult); + else + super.onActivityResult(requestCode, resultCode, intent); + }catch (Exception ex){ + Toast.makeText(getApplicationContext(), ex.getMessage(), LENGTH_SHORT).show(); + } + } + + private void handleResult(IntentResult scanResult) { + if (scanResult != null) { + + Gson gson = new Gson(); + ArticuloScan articuloScan = gson.fromJson(scanResult.getContents(), ArticuloScan.class); + + if(articuloScan != null){ + + final inventarioDao db = AppDatabase.getAppDatabaseDB(this).inventarioDao(); + + //consultar base de datos + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + + executor.execute(() -> { + DetalleConteo detalle = null; + detalle = db.getDetalleID(conteo.getInventariopk(), conteo.getConteopk(), articuloScan.getArticuloid()); + DetalleConteo finalDetalle = detalle; + handler.post(() -> { + String tag = "android:switcher:" + R.id.view_pager + ":" + 0; + PlaceholderFragment f = (PlaceholderFragment) getSupportFragmentManager().findFragmentByTag(tag); + f.displayReceivedData(finalDetalle); + + TabLayout.Tab tab= tabs.getTabAt(0); + assert tab != null; + tab.select(); + }); + }); + + }else{ + Toast.makeText(this, "Información Incorrecta :(", LENGTH_SHORT).show(); + } + + } else { + Toast.makeText(this, "No se ha leído nada :(", LENGTH_SHORT).show(); + } + } + + private class SelectDetalleTask extends AsyncTask { + + private WeakReference activityReference; + private Conteo conteo; + private String folio; + + // only retain a weak reference to the activity + SelectDetalleTask(MainActivity context, Conteo conteo,String folio) { + activityReference = new WeakReference<>(context); + this.conteo = conteo; + this.folio = folio; + } + + // doInBackground methods runs on a worker thread + @Override + protected DetalleConteo doInBackground(Void... objs) { + return AppDatabase.getAppDatabaseDB(activityReference.get()).inventarioDao().getDetalle(conteo.getInventariopk(),conteo.getConteopk(),folio); + + } + + // onPostExecute runs on main thread + @Override + protected void onPostExecute(DetalleConteo det) { + if (det != null){ + String tag = "android:switcher:" + R.id.view_pager + ":" + 0; + PlaceholderFragment f = (PlaceholderFragment) getSupportFragmentManager().findFragmentByTag(tag); + f.displayReceivedData(det); + TabLayout.Tab tab = tabs.getTabAt(0); + tab.select(); + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/ArticuloScan.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/ArticuloScan.java new file mode 100644 index 0000000..2e4ab75 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/ArticuloScan.java @@ -0,0 +1,42 @@ +package jumapacelaya.gob.mx.almacen.bean; + +import java.io.Serializable; + +public class ArticuloScan implements Serializable { + private int articuloid; + private String nombre; + private int cogid; + private String unidad; + + public int getArticuloid() { + return articuloid; + } + + public void setArticuloid(int articuloid) { + this.articuloid = articuloid; + } + + public String getNombre() { + return nombre; + } + + public void setNombre(String nombre) { + this.nombre = nombre; + } + + public int getCogid() { + return cogid; + } + + public void setCogid(int cogid) { + this.cogid = cogid; + } + + public String getUnidad() { + return unidad; + } + + public void setUnidad(String unidad) { + this.unidad = unidad; + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/Conteo.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/Conteo.java new file mode 100644 index 0000000..cadc503 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/Conteo.java @@ -0,0 +1,48 @@ +package jumapacelaya.gob.mx.almacen.bean; + + +import androidx.room.Entity; +import androidx.room.PrimaryKey; +import androidx.annotation.NonNull; + +import java.io.Serializable; + +@Entity +public class Conteo implements Serializable { + + @PrimaryKey + @NonNull + private Integer conteopk; + private String nombre; + + private Integer inventariopk; + + public Integer getConteopk() { + return conteopk; + } + + public void setConteopk(Integer conteopk) { + this.conteopk = conteopk; + } + + public String getNombre() { + return nombre; + } + + public void setNombre(String nombre) { + this.nombre = nombre; + } + + @Override + public String toString() { + return getNombre(); + } + + public Integer getInventariopk() { + return inventariopk; + } + + public void setInventariopk(Integer inventariopk) { + this.inventariopk = inventariopk; + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/DetalleConteo.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/DetalleConteo.java new file mode 100644 index 0000000..661e3a6 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/DetalleConteo.java @@ -0,0 +1,162 @@ +package jumapacelaya.gob.mx.almacen.bean; + +import androidx.room.Embedded; +import androidx.room.Entity; +import androidx.annotation.NonNull; + +import com.google.gson.annotations.Expose; + +import java.io.Serializable; +import java.math.BigDecimal; + +@Entity(primaryKeys = {"almacenpk","articulopk","conteopk"}) +public class DetalleConteo implements Serializable { + + + @NonNull + @Expose + private Integer folio; + @Expose + private String clave; + @Expose + private String descArticulo; + @Expose + private String descunidad; + @Expose + @NonNull + private Integer inventariopk; + @NonNull + @Expose + private Integer almacenpk; + @NonNull + @Expose + private Integer articulopk; + @Expose + private BigDecimal cantidad; + @Expose + private String descFamilia; + @Expose + private String descSubFamilia; + + @NonNull + @Expose + private Integer conteopk; + + + @NonNull + @Expose(deserialize = false, serialize = false) + private Boolean enviado = false; + @NonNull + @Expose(deserialize = false, serialize = false) + private Boolean actualizado = false; + + + public Integer getAlmacenpk() { + return almacenpk; + } + + public void setAlmacenpk(Integer almacenpk) { + this.almacenpk = almacenpk; + } + + public Integer getArticulopk() { + return articulopk; + } + + public void setArticulopk(Integer articulopk) { + this.articulopk = articulopk; + } + + public Integer getConteopk() { + return conteopk; + } + + public void setConteopk(Integer conteopk) { + this.conteopk = conteopk; + } + + public Integer getFolio() { + return folio; + } + + public void setFolio(Integer folio) { + this.folio = folio; + } + + public BigDecimal getCantidad() { + return cantidad; + } + + public void setCantidad(BigDecimal cantidad) { + this.cantidad = cantidad; + } + + + @NonNull + public Boolean getEnviado() { + return enviado; + } + + public void setEnviado(@NonNull Boolean enviado) { + this.enviado = enviado; + } + + + public String getClave() { + return clave; + } + + public void setClave(String clave) { + this.clave = clave; + } + + public String getDescArticulo() { + return descArticulo; + } + + public void setDescArticulo(String descArticulo) { + this.descArticulo = descArticulo; + } + + public String getDescunidad() { + return descunidad; + } + + public void setDescunidad(String descunidad) { + this.descunidad = descunidad; + } + + public String getDescFamilia() { + return descFamilia; + } + + public void setDescFamilia(String descFamilia) { + this.descFamilia = descFamilia; + } + + public String getDescSubFamilia() { + return descSubFamilia; + } + + public void setDescSubFamilia(String descSubFamilia) { + this.descSubFamilia = descSubFamilia; + } + + @NonNull + public Integer getInventariopk() { + return inventariopk; + } + + public void setInventariopk(@NonNull Integer inventariopk) { + this.inventariopk = inventariopk; + } + + @NonNull + public Boolean getActualizado() { + return actualizado; + } + + public void setActualizado(@NonNull Boolean actualizado) { + this.actualizado = actualizado; + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/Inventario.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/Inventario.java new file mode 100644 index 0000000..b229f31 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/bean/Inventario.java @@ -0,0 +1,96 @@ +package jumapacelaya.gob.mx.almacen.bean; + + +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +import java.time.LocalDate; +import java.util.Date; + + +@Entity +public class Inventario { + + @PrimaryKey + private int inventariopk; + private String descripcion; + + + private Date fecha; + private String estado; + private int polizapk; + private String usuario; + private int folio; + private int folioFResp; + + public int getInventariopk() { + return inventariopk; + } + + public void setInventariopk(int inventariopk) { + this.inventariopk = inventariopk; + } + + public String getDescripcion() { + return descripcion; + } + + public void setDescripcion(String descripcion) { + this.descripcion = descripcion; + } + + + + public String getEstado() { + return estado; + } + + public void setEstado(String estado) { + this.estado = estado; + } + + public int getPolizapk() { + return polizapk; + } + + public void setPolizapk(int polizapk) { + this.polizapk = polizapk; + } + + public String getUsuario() { + return usuario; + } + + public void setUsuario(String usuario) { + this.usuario = usuario; + } + + public int getFolio() { + return folio; + } + + public void setFolio(int folio) { + this.folio = folio; + } + + public int getFolioFResp() { + return folioFResp; + } + + public void setFolioFResp(int folioFResp) { + this.folioFResp = folioFResp; + } + + public Date getFecha() { + return fecha; + } + + public void setFecha(Date fecha) { + this.fecha = fecha; + } + + @Override + public String toString() { + return this.descripcion; // What to display in the Spinner list. + } +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/AppDatabase.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/AppDatabase.java new file mode 100644 index 0000000..de05a4d --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/AppDatabase.java @@ -0,0 +1,45 @@ +package jumapacelaya.gob.mx.almacen.dao; + + + + +import androidx.room.Database; +import androidx.room.Room; +import androidx.room.RoomDatabase; +import androidx.room.TypeConverters; +import android.content.Context; + +import jumapacelaya.gob.mx.almacen.bean.Inventario; +import jumapacelaya.gob.mx.almacen.dao.converts.BigdecimalToLong; +import jumapacelaya.gob.mx.almacen.dao.converts.BooleanTointeger; +import jumapacelaya.gob.mx.almacen.bean.Conteo; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.dao.converts.DateConverter; +import jumapacelaya.gob.mx.almacen.dao.converts.LocalDateConverter; + +@Database(entities = {Conteo.class, DetalleConteo.class, Inventario.class}, version = 8, exportSchema = false) +@TypeConverters({BooleanTointeger.class, BigdecimalToLong.class, DateConverter.class}) + +public abstract class AppDatabase extends RoomDatabase { + private static AppDatabase INSTANCE; + + public abstract inventarioDao inventarioDao(); + + + public static AppDatabase getAppDatabaseDB(Context context){ + if(INSTANCE == null){ + INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "Inventario.DB") //.addMigrations(MIGRATION_1_2) + .fallbackToDestructiveMigration().build(); //Esta opcion incremetala version pero elimina todos los datos de la base de datos. + /*INSTANCE = Room.databaseBuilder(context.getApplicationContext(), Lecturasdb.class, consNamesDB.NAME_DATABASE).addMigrations(MIGRATION_19_20) + .build();*/ + } + + return INSTANCE; + } + + public static void destroyInstance(){ + INSTANCE = null; + } + + +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/PostViewModel.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/PostViewModel.java new file mode 100644 index 0000000..ff9c3f3 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/PostViewModel.java @@ -0,0 +1,60 @@ +package jumapacelaya.gob.mx.almacen.dao; + +import android.app.Application; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.annotation.NonNull; + +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; + +public class PostViewModel extends AndroidViewModel { + + public inventarioDao postDao; + private ExecutorService executorService; + private Application app; + + public PostViewModel(@NonNull Application application) { + super(application); + postDao = AppDatabase.getAppDatabaseDB(application).inventarioDao(); + executorService = Executors.newSingleThreadExecutor(); + } + + public LiveData> getAllConteo() { + return postDao.liveDetalleConteos(); + } + + public LiveData> getPendientesConteo(int inventariopk, Integer conteo) { + return postDao.livePendiente_Detalles(inventariopk, conteo); + } + + public LiveData> getAvanceConteo(int inventariopk, Integer conteo) { + return postDao.liveAvance_Detalles(inventariopk, conteo); + } + + public void saveDetalleConteo(final DetalleConteo detalleConteo) { + executorService.execute(new Runnable() { + @Override + public void run() { + postDao.insertDetalleConteos(detalleConteo); + } + }); + } + + public void deleteDetalleConteo(final DetalleConteo detalleConteo) { + executorService.execute(new Runnable() { + @Override + public void run() { + postDao.deleteDetalleConteo(detalleConteo); + } + }); + } + + + + + +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/BigdecimalToLong.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/BigdecimalToLong.java new file mode 100644 index 0000000..1911642 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/BigdecimalToLong.java @@ -0,0 +1,21 @@ +package jumapacelaya.gob.mx.almacen.dao.converts; + +import androidx.room.TypeConverter; + +import java.math.BigDecimal; + +public class BigdecimalToLong { + @TypeConverter + public BigDecimal fromLong(Long value) { + return value == null ? null : new BigDecimal(value).divide(new BigDecimal(100)); + } + + @TypeConverter + public Long toLong(BigDecimal bigDecimal) { + if (bigDecimal == null) { + return null; + } else { + return bigDecimal.multiply(new BigDecimal(100)).longValue(); + } + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/BooleanTointeger.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/BooleanTointeger.java new file mode 100644 index 0000000..5a27138 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/BooleanTointeger.java @@ -0,0 +1,20 @@ +package jumapacelaya.gob.mx.almacen.dao.converts; + +import androidx.room.TypeConverter; + +public class BooleanTointeger { + + @TypeConverter + public Boolean fromTimestamp(Integer value) { + return value == null ? null : value > 0? new Boolean(true): new Boolean(false); + } + + @TypeConverter + public Integer dateToTimestamp(Boolean value) { + if (value == null) { + return null; + } else { + return value? 1: 0; + } + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/DateConverter.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/DateConverter.java new file mode 100644 index 0000000..5807339 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/DateConverter.java @@ -0,0 +1,19 @@ +package jumapacelaya.gob.mx.almacen.dao.converts; + +import androidx.room.TypeConverter; + +import java.time.LocalDate; +import java.util.Date; + +public class DateConverter { + + @TypeConverter + public static Date toDate(Long dateLong){ + return dateLong == null ? null: new Date(dateLong); + } + + @TypeConverter + public static Long fromDate(Date date){ + return date == null ? null : date.getTime(); + } +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/LocalDateConverter.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/LocalDateConverter.java new file mode 100644 index 0000000..5cf0eaf --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/converts/LocalDateConverter.java @@ -0,0 +1,27 @@ +package jumapacelaya.gob.mx.almacen.dao.converts; + +import androidx.room.TypeConverter; + +import java.time.LocalDate; + +public class LocalDateConverter { + + @TypeConverter + public static LocalDate toDate(String dateString) { + if (dateString == null) { + return null; + } else { + return LocalDate.parse(dateString); + } + } + + @TypeConverter + public static String toDateString(LocalDate date) { + if (date == null) { + return null; + } else { + return date.toString(); + } + } + +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/inventarioDao.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/inventarioDao.java new file mode 100644 index 0000000..6137c14 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/dao/inventarioDao.java @@ -0,0 +1,156 @@ +package jumapacelaya.gob.mx.almacen.dao; + +import android.database.sqlite.SQLiteConstraintException; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; +import androidx.room.Transaction; +import androidx.room.Update; + +import java.math.BigDecimal; +import java.util.List; + +import jumapacelaya.gob.mx.almacen.bean.Conteo; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.bean.Inventario; + +@Dao +public abstract class inventarioDao { + + + @Query("Select * from Conteo") + public abstract List listConteos(); + + @Query("Select * from Inventario") + public abstract List listInventarios(); + + @Query("Select * from Inventario Where estado = 'A' ") + public abstract List listInventariosActivos(); + + @Query("Select * from Conteo Where inventariopk = :pinventariopk ") + public abstract List listInventariosInv(int pinventariopk); + + @Query("Select * from Conteo Where conteopk= :conteopk ") + public abstract Conteo listConteos(Integer conteopk); + + @Insert + public abstract void insertConteos(Conteo... conteos); + + @Insert + public abstract void insertConteo(Conteo conteo); + + @Update + public abstract void updateConteo(Conteo conteo); + + + public void upsertConteo(Conteo conteo) { + try { + insertConteo(conteo); + } + catch (SQLiteConstraintException e) { + updateConteo(conteo); + } + } + + //@Insert(onConflict = OnConflictStrategy.REPLACE) + @Insert + public abstract void insertInventarios(Inventario... inventarios); + + + @Insert + public abstract void insertInventario(Inventario inventario); + + @Update + public abstract void updateInventario(Inventario inventario); + + public void upsertInventario(Inventario inventario) { + try { + insertInventario(inventario); + } + catch (SQLiteConstraintException e) { + updateInventario(inventario); + } + } + + @Insert + public abstract void isertConteo(Conteo conteo); + + @Delete + public abstract void deleteConteo(Conteo conteo); + + @Query("Select * from DetalleConteo") + public abstract List listDetalleConteos(); + + @Query("Select * from DetalleConteo ") + public abstract LiveData> liveDetalleConteos(); + + @Query("Select * from DetalleConteo Where inventariopk = :inventariopk And conteopk= :conteopk and folio = :folio") + public abstract DetalleConteo getDetalle(Integer inventariopk, Integer conteopk, String folio); + + @Query("Select * from DetalleConteo Where inventariopk = :inventariopk And conteopk= :conteopk and articulopk = :articulo") + public abstract DetalleConteo getDetalleID(Integer inventariopk, Integer conteopk, Integer articulo); + + + @Query("Select * from DetalleConteo Where almacenpk = :almacenpk And conteopk= :conteopk ") + public abstract List listDetalles(Integer almacenpk, Integer conteopk); + + @Query("Select * from DetalleConteo Where almacenpk = :almacenpk And conteopk= :conteopk ") + public abstract LiveData> liveDetalles(Integer almacenpk, Integer conteopk); + + @Query("Select * from DetalleConteo Where inventariopk = :inventariopk And conteopk= :conteopk and (cantidad == null or cantidad <> 0) ") + public abstract List listPendiente_Detalles(Integer inventariopk, Integer conteopk); + + @Query("Select * from DetalleConteo Where inventariopk = :inventariopk And conteopk= :conteopk and (cantidad is null or cantidad = 0) Order by folio") + public abstract LiveData> livePendiente_Detalles(Integer inventariopk, Integer conteopk); + + @Query("Select * from DetalleConteo Where inventariopk = :inventariopk And conteopk= :conteopk ") + public abstract List listContados_Detalles(Integer inventariopk, Integer conteopk); + + @Query("Select * from DetalleConteo Where inventariopk = :inventariopk And conteopk= :conteopk and (CASE WHEN Cantidad IS NULL THEN 0 ELSE Cantidad END) <> 0 Order by folio") + public abstract LiveData> liveAvance_Detalles(Integer inventariopk, Integer conteopk ); + + + @Insert + public abstract void insertDetalleConteos(DetalleConteo... detalleConteos); + + @Insert + public abstract void isertDetalleConteo(DetalleConteo detalleConteo); + + @Query("Update detalleconteo Set cantidad= :cantidad, enviado = :enviado, actualizado = :actualizado Where almacenpk = :almacen And conteopk = :conteo And folio = :folio And articulopk= :articulo And inventariopk = :inventariopk ") + public abstract void updateCantidad(BigDecimal cantidad,Integer almacen, Integer conteo, Integer folio,Integer articulo, int inventariopk, boolean actualizado, boolean enviado); + + @Query("Select * From detalleconteo Where almacenpk = :almacen And conteopk = :conteo And folio = :folio And articulopk= :articulo And inventariopk = :inventariopk ") + public abstract Conteo exist(Integer almacen, Integer conteo, Integer folio,Integer articulo, Integer inventariopk); + + @Query("Select * From detalleconteo Where almacenpk = :almacen And conteopk = :conteo And folio = :folio And articulopk= :articulo And inventariopk = :inventariopk And enviado = :enviado And actualizado = :actualizado") + public abstract Conteo existSinenviar(Integer almacen, Integer conteo, Integer folio,Integer articulo, Integer inventariopk, boolean enviado, boolean actualizado); + + @Query("Select count(*) From detalleconteo Where conteopk = :conteo And inventariopk = :inventariopk And enviado = :enviado And actualizado = :actualizado") + public abstract int pendienteEnviar(Integer conteo, Integer inventariopk, boolean enviado, boolean actualizado); + + @Query("Select * From detalleconteo Where conteopk = :conteo And inventariopk = :inventariopk And enviado = :enviado And actualizado = :actualizado") + public abstract List lstpendienteEnviar(Integer conteo, Integer inventariopk, boolean enviado, boolean actualizado); + + @Query("Update inventario Set estado= 'C'") + public abstract void updateInventarioN(); + + @Delete + public abstract void deleteDetalleConteo(DetalleConteo detalleConteo); + + @Query("Delete from detalleconteo where almacenpk = :almacen And conteopk = :conteo") + public abstract void clearConteo(Integer almacen, Integer conteo); + + @Update + public abstract void updateDetalle(DetalleConteo detalleConteo); + + @Transaction + public void setLoggedInUser(DetalleConteo detalleConteo, Conteo conteo ) { + deleteDetalleConteo(detalleConteo); + deleteConteo(conteo); + } + + +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/request/DetalleRequest.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/request/DetalleRequest.java new file mode 100644 index 0000000..d3bd2cb --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/request/DetalleRequest.java @@ -0,0 +1,20 @@ +package jumapacelaya.gob.mx.almacen.request; + + + +public class DetalleRequest { + String imei; + Integer inventariopk; + Integer conteopk; + Integer foliopk; + + public DetalleRequest(String imei, Integer inventariopk, Integer conteopk, Integer foliopk){ + this.imei = imei; + this.inventariopk = inventariopk; + this.conteopk = conteopk; + this.foliopk = foliopk; + + } + + +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/restAlmacen.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/restAlmacen.java new file mode 100644 index 0000000..818b631 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/restAlmacen.java @@ -0,0 +1,42 @@ +package jumapacelaya.gob.mx.almacen; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +public class restAlmacen { + public String URL_conteos = ""; + public String URL_inventarios = ""; + public String URL_Articulos = ""; + public String URL_updateDetalle = ""; + public String BASE_URL = ""; + + String server; + String port; + String servicio; + SharedPreferences pref; + + + public static restAlmacen instance(Context context){ + restAlmacen rest = new restAlmacen(); + + + SharedPreferences pref;// = PreferenceManager.getDefaultSharedPreferences(context); + pref = PreferenceManager.getDefaultSharedPreferences(context); + + rest.server = pref.getString("server_text", "172.16.0.9"); + rest.port = pref.getString("port_text", "85"); + rest.servicio = pref.getString("servicio_text",""); + + rest.BASE_URL = "http://"+rest.server+":"+rest.port+ (rest.servicio.equals("")?"" : "/" + rest.servicio); + + rest.URL_inventarios = rest.BASE_URL + "/rest/almservice/listInventarios"; // Muestra los invnetarios activos de un almacen + rest.URL_conteos = rest.BASE_URL + "/rest/almservice/listConteos"; // Muestra la lista de conteos + rest.URL_Articulos = rest.BASE_URL + "/rest/almservice/listConteoArticulo"; //muestra los articulos del conteo + rest.URL_updateDetalle = rest.BASE_URL + "/rest/almservice/saveFolio"; //Actualiza el inventario con los conteos realizados. + + rest.BASE_URL = "http://"+rest.server+":"+rest.port+ (rest.servicio.equals("")?"" : "/" + rest.servicio); + + return rest; + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/splash.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/splash.java new file mode 100644 index 0000000..1abe6f6 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/splash.java @@ -0,0 +1,28 @@ +package jumapacelaya.gob.mx.almacen; + +import android.app.Activity; +import android.content.Intent; +import android.os.Handler; +import androidx.appcompat.app.AppCompatActivity; +import android.os.Bundle; + +public class splash extends Activity { + + private final int SPLASH_DISPLAY_LENGHT = 3000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_splash); + + new Handler().postDelayed(new Runnable(){ + @Override + public void run() { + /* Create an Intent that will start the Menu-Activity. */ + Intent mainIntent = new Intent(splash.this,ConteoActivity.class); + splash.this.startActivity(mainIntent); + splash.this.finish(); + } + }, SPLASH_DISPLAY_LENGHT); + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/CaptureActivityPortrait.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/CaptureActivityPortrait.java new file mode 100644 index 0000000..92a574d --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/CaptureActivityPortrait.java @@ -0,0 +1,10 @@ +package jumapacelaya.gob.mx.almacen.ui.main; + + +import com.journeyapps.barcodescanner.CaptureActivity; + +public class CaptureActivityPortrait extends CaptureActivity { +//Nothing in side. + + +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/Constant.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/Constant.java new file mode 100644 index 0000000..e74b257 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/Constant.java @@ -0,0 +1,8 @@ +package jumapacelaya.gob.mx.almacen.ui.main; + +public class Constant { + public static String CONTEODET = "conteodet"; + + +} + diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PageViewModel.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PageViewModel.java new file mode 100644 index 0000000..47d152b --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PageViewModel.java @@ -0,0 +1,18 @@ +package jumapacelaya.gob.mx.almacen.ui.main; + +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class PageViewModel extends ViewModel { + + private MutableLiveData mIndex = new MutableLiveData<>(); + //private LiveData mText = Transformations.map(mIndex, (Function) input -> "Hello world from section: " + input); + + public void setIndex(int index) { + mIndex.setValue(index); + } + + /*public LiveData getText() { + return mText; + }*/ +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PendienteFragment.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PendienteFragment.java new file mode 100644 index 0000000..9ca1e60 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PendienteFragment.java @@ -0,0 +1,124 @@ +package jumapacelaya.gob.mx.almacen.ui.main; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModelProviders; +import android.content.Context; +import android.os.Bundle; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import jumapacelaya.gob.mx.almacen.MainActivity; +import jumapacelaya.gob.mx.almacen.R; +import jumapacelaya.gob.mx.almacen.bean.Conteo; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.dao.PostViewModel; + +/** + * A fragment representing a list of Items. + *

+ * Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener} + * interface. + */ +public class PendienteFragment extends Fragment { + + // TODO: Customize parameter argument names + private static final String ARG_COLUMN_COUNT = "column-count"; + // TODO: Customize parameters + private int mColumnCount = 1; + PostViewModel postViewModel; + PendienteViewAdapter adapter; + + Conteo conteo; + MainActivity activity; + + private OnListFragmentInteractionListener mListener; + + /** + * Mandatory empty constructor for the fragment manager to instantiate the + * fragment (e.g. upon screen orientation changes). + */ + public PendienteFragment() { + } + + // TODO: Customize parameter initialization + @SuppressWarnings("unused") + public static PendienteFragment newInstance(int columnCount, Conteo conteo, MainActivity activity) { + PendienteFragment fragment = new PendienteFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_COLUMN_COUNT, columnCount); + fragment.setArguments(args); + fragment.conteo = conteo; + fragment.activity = activity; + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + postViewModel = ViewModelProviders.of(this).get(PostViewModel.class); + + + if (getArguments() != null) { + mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_item_list, container, false); + + // Set the adapter + if (view instanceof RecyclerView) { + Context context = view.getContext(); + RecyclerView recyclerView = (RecyclerView) view; + //if (mColumnCount <= 1) { + recyclerView.setLayoutManager(new LinearLayoutManager(context)); + //} else { + // recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount)); + //} + adapter = new PendienteViewAdapter( mListener); + postViewModel.getPendientesConteo(conteo.getInventariopk(),conteo.getConteopk()).observe(getViewLifecycleOwner(), detalleConteos -> adapter.setData(detalleConteos)); + recyclerView.setAdapter(adapter); + } + return view; + } + + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (context instanceof OnListFragmentInteractionListener) { + mListener = (OnListFragmentInteractionListener) context; + } else { + throw new RuntimeException(context.toString() + + " must implement OnListFragmentInteractionListener"); + } + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + /** + * This interface must be implemented by activities that contain this + * fragment to allow an interaction in this fragment to be communicated + * to the activity and potentially other fragments contained in that + * activity. + *

+ * See the Android Training lesson Communicating with Other Fragments for more information. + */ + public interface OnListFragmentInteractionListener { + // TODO: Update argument type and name + void onListFragmentInteraction(DetalleConteo item); + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PendienteViewAdapter.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PendienteViewAdapter.java new file mode 100644 index 0000000..9d21723 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PendienteViewAdapter.java @@ -0,0 +1,88 @@ +package jumapacelaya.gob.mx.almacen.ui.main; + +import androidx.recyclerview.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import jumapacelaya.gob.mx.almacen.R; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.ui.main.PendienteFragment.OnListFragmentInteractionListener; + +import java.util.ArrayList; +import java.util.List; + +/** + * {@link RecyclerView.Adapter} that can display a {@link DetalleConteo} and makes a call to the + * specified {@link OnListFragmentInteractionListener}. + * TODO: Replace the implementation with code for your data type. + */ +public class PendienteViewAdapter extends RecyclerView.Adapter { + + private List mValues; + private final OnListFragmentInteractionListener mListener; + + public PendienteViewAdapter(OnListFragmentInteractionListener listener) { + mValues = new ArrayList<>(); + mListener = listener; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.fragment_item, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, int position) { + holder.mItem = mValues.get(position); + holder.mIdView.setText(mValues.get(position).getFolio().toString()); + holder.mContentView.setText(mValues.get(position).getDescArticulo()); + holder.mclave.setText(mValues.get(position).getClave()); + holder.mcantidad.setText(mValues.get(position).getCantidad().toString()); + + holder.mView.setOnClickListener(v -> { + if (null != mListener) { + // Notify the active callbacks interface (the activity, if the + // fragment is attached to one) that an item has been selected. + mListener.onListFragmentInteraction(holder.mItem); + } + }); + } + + @Override + public int getItemCount() { + return mValues.size(); + } + + public void setData(List newData) { + this.mValues = newData; + notifyDataSetChanged(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + public final View mView; + public final TextView mIdView; + public final TextView mContentView; + public final TextView mclave; + public final TextView mcantidad; + public DetalleConteo mItem; + + public ViewHolder(View view) { + super(view); + mView = view; + mIdView = view.findViewById(R.id.item_number); + mContentView = view.findViewById(R.id.content); + mclave = view.findViewById(R.id.item_clave); + mcantidad = view.findViewById(R.id.item_cantidad); + } + + @Override + public String toString() { + return super.toString() + " '" + mContentView.getText() + "'"; + } + } + +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PlaceholderFragment.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PlaceholderFragment.java new file mode 100644 index 0000000..ff4c725 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/PlaceholderFragment.java @@ -0,0 +1,363 @@ +package jumapacelaya.gob.mx.almacen.ui.main; + +import android.app.Activity; +import android.app.Dialog; + +import androidx.lifecycle.ViewModelProviders; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.appcompat.app.AlertDialog; + +import android.os.Handler; +import android.os.Looper; +import android.text.util.Linkify; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.toolbox.JsonObjectRequest; +import com.android.volley.toolbox.Volley; +import com.google.android.material.snackbar.Snackbar; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentResult; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.math.BigDecimal; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import jumapacelaya.gob.mx.almacen.ConteoActivity; +import jumapacelaya.gob.mx.almacen.InventarioService; +import jumapacelaya.gob.mx.almacen.MainActivity; +import jumapacelaya.gob.mx.almacen.R; +import jumapacelaya.gob.mx.almacen.bean.ArticuloScan; +import jumapacelaya.gob.mx.almacen.bean.Conteo; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.dao.AppDatabase; +import jumapacelaya.gob.mx.almacen.dao.inventarioDao; +import jumapacelaya.gob.mx.almacen.restAlmacen; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +import static android.app.ProgressDialog.show; +import static android.widget.Toast.LENGTH_SHORT; +import static androidx.core.content.ContextCompat.getSystemService; + +/** + * A placeholder fragment containing a simple view. + */ +public class PlaceholderFragment extends Fragment { + + private static final String ARG_SECTION_NUMBER = "section_number"; + static final String SCAN = "com.google.zxing.client.android"; + + + private PageViewModel pageViewModel; + + TextView txtfolio; + TextView txtclave; + TextView txtarticulo; + TextView txtfamilia; + TextView txtsubfamilia; + EditText txtCantidad; + Button btnAceptar; + + DetalleConteo detalle; + MainActivity activity; + Conteo conteo; + + //ImageView code; + public PlaceholderFragment() { + } + + public static PlaceholderFragment newInstance(int index, Conteo conteo, MainActivity activity) { + + PlaceholderFragment fragment = new PlaceholderFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(ARG_SECTION_NUMBER, index); + fragment.setArguments(bundle); + fragment.conteo = conteo; + fragment.activity = activity; + + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + pageViewModel = ViewModelProviders.of(this).get(PageViewModel.class); + int index = 1; + if (getArguments() != null) { + index = getArguments().getInt(ARG_SECTION_NUMBER); + } + pageViewModel.setIndex(index); + } + + @Override + public View onCreateView( + @NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_main, container, false); + + //controles + txtfolio = root.findViewById(R.id.txtcap_folio); + txtclave = root.findViewById(R.id.txtcap_clave); + txtarticulo = root.findViewById(R.id.txtcap_articulo); + //code = root.findViewById(R.id.imageView); + txtfamilia = root.findViewById(R.id.txtcap_descfamilia); + txtsubfamilia= root.findViewById(R.id.txtcap_subfamilia); + txtCantidad= root.findViewById(R.id.txtcap_Cantidad); + btnAceptar = root.findViewById(R.id.btncap_aceptar); + + btnAceptar.setOnClickListener(event -> { + //guardar y enviar los datos + if(txtCantidad.getText().toString().trim().equals("")){ + Toast.makeText(getContext(), "El valor de cantidad no es valido", LENGTH_SHORT).show(); + return; + } + + saveconteo(); + }); + + + /*pageViewModel.getText().observe(this, new Observer() { + @Override + public void onChanged(@Nullable String s) { + //textView.setText(s); + } + });*/ + return root; + } + + /*@Override + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + try { + final IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); + if(scanResult != null) + handleResult(scanResult); + else + super.onActivityResult(requestCode, resultCode, intent); + }catch (Exception ex){ + Toast.makeText(getContext(), ex.getMessage(), LENGTH_SHORT).show(); + } + } + + private void handleResult(IntentResult scanResult) { + if (scanResult != null) { + + Gson gson = new Gson(); + ArticuloScan articuloScan = gson.fromJson(scanResult.getContents(), ArticuloScan.class); + + if(articuloScan != null){ + final inventarioDao db = AppDatabase.getAppDatabaseDB(getContext()).inventarioDao(); + + //consultar bae de datos + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + + executor.execute(() -> { + detalle = db.getDetalleID(conteo.getInventariopk(), conteo.getConteopk(), articuloScan.getArticuloID()); + handler.post(() -> { + updateUITextViews(detalle); + }); + }); + + }else{ + Toast.makeText(getContext(), "Información Incorrecta :(", LENGTH_SHORT).show(); + } + + } else { + Toast.makeText(getContext(), "No se ha leído nada :(", LENGTH_SHORT).show(); + } + }*/ + + private void updateUITextViews(DetalleConteo d) { + txtfolio.setText(d.getFolio()); + txtclave.setText(d.getClave()); + txtarticulo.setText(d.getArticulopk()); + + Linkify.addLinks(txtfolio, Linkify.ALL); + } + + private Dialog showDialog (final Activity act, CharSequence title, CharSequence message, CharSequence yes, CharSequence no ) { + + // a subclass of dialog that can display buttons and message + AlertDialog.Builder download = new AlertDialog.Builder( act ); + download.setTitle( title ); + download.setMessage ( message ); + download.setPositiveButton ( yes, new DialogInterface.OnClickListener ( ) { + @Override + public void onClick( DialogInterface dialog, int i ) { + // TODO Auto-generated method stub + //uri to download barcode scanner + Uri uri = Uri.parse( "market://search?q=pname:" + "com.google.zxing.client.android" ); + Intent in = new Intent ( Intent.ACTION_VIEW, uri ); + try { + act.startActivity ( in ); + } catch ( ActivityNotFoundException e) { + + } + } + }); + download.setNegativeButton ( no, new DialogInterface.OnClickListener() { + @Override + public void onClick ( DialogInterface dialog, int i ) { + // TODO Auto-generated method stub + } + }); + return download.show(); + } + + //recibir datos + public void displayReceivedData(DetalleConteo detalle) + { + + this.detalle = detalle; + txtfolio.setText(detalle.getFolio().toString()); + txtclave.setText(detalle.getClave()); + txtarticulo.setText(detalle.getDescArticulo()); + txtfamilia.setText(detalle.getDescFamilia()); + txtsubfamilia.setText(detalle.getDescSubFamilia()); + txtCantidad.setText(detalle.getCantidad() == null ? "0.0": detalle.getCantidad().toString()); + + //txtCantidad.requestFocus(); + txtCantidad.selectAll(); + + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(txtCantidad, InputMethodManager.SHOW_IMPLICIT); + + Toast.makeText(getContext(),detalle.getDescArticulo(), LENGTH_SHORT).show(); + } + + + private void saveconteo(){ + if(detalle != null) { + detalle.setCantidad(new BigDecimal(txtCantidad.getText().toString())); + detalle.setEnviado(false); + + new UpdateTask().execute(detalle); + + } + + } + + private void updateServerDetalle(inventarioDao db, DetalleConteo d){ + final Activity thisactivity = getActivity(); + + GsonBuilder builder = new GsonBuilder(); + builder.excludeFieldsWithoutExposeAnnotation(); + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(restAlmacen.instance(activity).BASE_URL) + .addConverterFactory(GsonConverterFactory.create(builder.create())) + .build(); + + InventarioService postService = retrofit.create(InventarioService.class); + Call call = postService.updateDetalle(d); + + call.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Handler handler = new Handler(Looper.getMainLooper()); + + + executor.execute(() -> { + String msg = ""; + boolean flag = false; + if (response.code() == 200){ + flag = true; + d.setEnviado(true); + db.updateDetalle(d); + } + + boolean finalFlag = flag; + String finalMsg = msg; + + + + handler.post(() -> { + //if (finalFlag) + + //Toast.makeText(thisactivity, "Articulo enviado", Toast.LENGTH_LONG).show(); + + activity.refreshBadge(); + }); + }); + } + + @Override + public void onFailure(Call call, Throwable t) { + //Toast.makeText(thisactivity, t.getMessage(), Toast.LENGTH_LONG).show(); + activity.refreshBadge(); + } + }); + + } + + + private class UpdateTask extends AsyncTask { + + Boolean tag = false; + + /* + Ejecución del ordenamiento y transmision de progreso + */ + @Override + protected Integer doInBackground(DetalleConteo... params) { + final inventarioDao db = AppDatabase.getAppDatabaseDB(getContext()).inventarioDao(); + int i = 0; + for (DetalleConteo d:params) { + d.setActualizado(true); + d.setEnviado(false); + db.updateCantidad(d.getCantidad(), d.getAlmacenpk(), d.getConteopk(), d.getFolio(), d.getArticulopk(), d.getInventariopk(), d.getActualizado(), d.getEnviado()); + tag = true; + i++; + } + + for (DetalleConteo d:params) { + //update server + updateServerDetalle(db, d); + } + + //si ho hay error + activity.refreshBadge(); + return i; + } + + @Override + protected void onPostExecute(Integer integer) { + if(tag) + Snackbar.make(activity.getCurrentFocus(), "Guardado", Snackbar.LENGTH_LONG) + .setBackgroundTint(Color.parseColor("#008000")) + .setActionTextColor(Color.parseColor("#000000")) + .show(); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/SectionsPagerAdapter.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/SectionsPagerAdapter.java new file mode 100644 index 0000000..0a04db2 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/SectionsPagerAdapter.java @@ -0,0 +1,65 @@ +package jumapacelaya.gob.mx.almacen.ui.main; + +import android.content.Context; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import jumapacelaya.gob.mx.almacen.MainActivity; +import jumapacelaya.gob.mx.almacen.R; +import jumapacelaya.gob.mx.almacen.ui.main.avance.AvanceFragment; + +/** + * A [FragmentPagerAdapter] that returns a fragment corresponding to + * one of the sections/tabs/pages. + */ +public class SectionsPagerAdapter extends FragmentPagerAdapter { + + @StringRes + private static final int[] TAB_TITLES = new int[]{R.string.tab_captura,R.string.tab_Avance, R.string.tab_Pendietnes}; + private final Context mContext; + + public SectionsPagerAdapter(Context context, FragmentManager fm) { + super(fm); + mContext = context; + } + + @Override + public Fragment getItem(int position) { + // getItem is called to instantiate the fragment for the given page. + // Return a PlaceholderFragment (defined as a static inner class below). + Fragment fragment; + + switch (position){ + case 0: + fragment = PlaceholderFragment.newInstance(position + 1, ((MainActivity)mContext).getConteo(), (MainActivity)mContext); + break; + case 2: + fragment = PendienteFragment.newInstance(position , ((MainActivity)mContext).getConteo(), (MainActivity)mContext); + break; + case 1: + fragment = AvanceFragment.newInstance(position , ((MainActivity)mContext).getConteo(), (MainActivity)mContext); + break; + default: + throw new IllegalStateException("Unexpected value: " + position); + } + + return fragment; + } + + @Nullable + @Override + public CharSequence getPageTitle(int position) { + return mContext.getResources().getString(TAB_TITLES[position]); + } + + @Override + public int getCount() { + // Show 2 total pages. + return 3; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/avance/AvanceFragment.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/avance/AvanceFragment.java new file mode 100644 index 0000000..fa85104 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/avance/AvanceFragment.java @@ -0,0 +1,124 @@ +package jumapacelaya.gob.mx.almacen.ui.main.avance; + +import androidx.lifecycle.ViewModelProviders; +import android.content.Context; +import android.os.Bundle; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import jumapacelaya.gob.mx.almacen.MainActivity; +import jumapacelaya.gob.mx.almacen.R; +import jumapacelaya.gob.mx.almacen.bean.Conteo; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; +import jumapacelaya.gob.mx.almacen.dao.PostViewModel; + +/** + * A fragment representing a list of Items. + *

+ * Activities containing this fragment MUST implement the {@link OnListAvanceFragmentInteractionListener} + * interface. + */ +public class AvanceFragment extends Fragment { + + // TODO: Customize parameter argument names + private static final String ARG_COLUMN_COUNT = "column-count"; + // TODO: Customize parameters + private int mColumnCount = 1; + PostViewModel postViewModel; + AvanceViewAdapter adapter; + + Conteo conteo; + MainActivity activity; + + private OnListAvanceFragmentInteractionListener mListener; + + /** + * Mandatory empty constructor for the fragment manager to instantiate the + * fragment (e.g. upon screen orientation changes). + */ + public AvanceFragment() { + } + + // TODO: Customize parameter initialization + @SuppressWarnings("unused") + public static AvanceFragment newInstance(int columnCount, Conteo conteo, MainActivity activity) { + AvanceFragment fragment = new AvanceFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_COLUMN_COUNT, columnCount); + fragment.setArguments(args); + fragment.conteo = conteo; + fragment.activity = activity; + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + postViewModel = ViewModelProviders.of(this).get(PostViewModel.class); + + + + if (getArguments() != null) { + mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_item_avance_list, container, false); + + // Set the adapter + if (view instanceof RecyclerView) { + Context context = view.getContext(); + RecyclerView recyclerView = (RecyclerView) view; + //if (mColumnCount <= 1) { + recyclerView.setLayoutManager(new LinearLayoutManager(context)); + //} else { + // recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount)); + //} + adapter = new AvanceViewAdapter(mListener); + postViewModel.getAvanceConteo(conteo.getInventariopk(),conteo.getConteopk()).observe(getViewLifecycleOwner(), detalleConteos -> adapter.setData(detalleConteos)); + recyclerView.setAdapter(adapter); + } + return view; + } + + + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof OnListAvanceFragmentInteractionListener) { + mListener = (OnListAvanceFragmentInteractionListener) context; + } else { + throw new RuntimeException(context.toString() + + " must implement OnListFragmentInteractionListener"); + } + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + /** + * This interface must be implemented by activities that contain this + * fragment to allow an interaction in this fragment to be communicated + * to the activity and potentially other fragments contained in that + * activity. + *

+ * See the Android Training lesson Communicating with Other Fragments for more information. + */ + public interface OnListAvanceFragmentInteractionListener { + // TODO: Update argument type and name + void onListAvanceFragmentInteraction(DetalleConteo item); + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/avance/AvanceViewAdapter.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/avance/AvanceViewAdapter.java new file mode 100644 index 0000000..b99235a --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/ui/main/avance/AvanceViewAdapter.java @@ -0,0 +1,95 @@ +package jumapacelaya.gob.mx.almacen.ui.main.avance; + +import androidx.recyclerview.widget.RecyclerView; + +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import jumapacelaya.gob.mx.almacen.R; +import jumapacelaya.gob.mx.almacen.bean.DetalleConteo; + + +/** + * {@link RecyclerView.Adapter} that can display a {@link DetalleConteo} and makes a call to the + * specified {@link AvanceFragment.OnListAvanceFragmentInteractionListener}. + * TODO: Replace the implementation with code for your data type. + */ +public class AvanceViewAdapter extends RecyclerView.Adapter { + + private List mValues; + private final AvanceFragment.OnListAvanceFragmentInteractionListener mListener; + + public AvanceViewAdapter(AvanceFragment.OnListAvanceFragmentInteractionListener listener) { + mValues = new ArrayList<>(); + mListener = listener; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.fragment_avance_item, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, int position) { + holder.mItem = mValues.get(position); + holder.mIdView.setText(mValues.get(position).getFolio().toString()); + holder.mContentView.setText(mValues.get(position).getDescArticulo()); + holder.mclave.setText(mValues.get(position).getClave()); + holder.mCantidad.setText(mValues.get(position).getCantidad().toString()); + + if(!mValues.get(position).getEnviado() && mValues.get(position).getActualizado()) { + holder.mclave.setBackgroundColor(Color.parseColor("#9b2226")); + }else{ + holder.mclave.setBackgroundColor(Color.parseColor("#FFFFFF")); + } + + holder.mView.setOnClickListener(v -> { + if (null != mListener) { + // Notify the active callbacks interface (the activity, if the + // fragment is attached to one) that an item has been selected. + mListener.onListAvanceFragmentInteraction(holder.mItem); + } + }); + } + + @Override + public int getItemCount() { + return mValues.size(); + } + + public void setData(List newData) { + this.mValues = newData; + notifyDataSetChanged(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + public final View mView; + public final TextView mIdView; + public final TextView mContentView; + public final TextView mclave; + public final TextView mCantidad; + public DetalleConteo mItem; + + public ViewHolder(View view) { + super(view); + mView = view; + mIdView = view.findViewById(R.id.item_number); + mContentView = view.findViewById(R.id.content); + mclave = view.findViewById(R.id.item_clave); + mCantidad = view.findViewById(R.id.item_cantidad); + } + + @Override + public String toString() { + return super.toString() + " '" + mContentView.getText() + "'"; + } + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/AutoUpdateActivity.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/AutoUpdateActivity.java new file mode 100644 index 0000000..100589e --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/AutoUpdateActivity.java @@ -0,0 +1,229 @@ +package jumapacelaya.gob.mx.almacen.updatepp; + +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import androidx.core.content.FileProvider; +import androidx.appcompat.app.AppCompatActivity; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.zxing.client.android.BuildConfig; + +import java.io.File; + + +import jumapacelaya.gob.mx.almacen.R; + + + +public class AutoUpdateActivity extends AppCompatActivity { + + // Handler para la actualización de la interfaz desde el hilo en segundo + // plano + private Handler handler = new Handler(); + + // Objeto de nuestra clase de utilidad + private VersionCheck mVC = new VersionCheck(); + + // Elementos de la interfaz + private View mActualizada, mActualizacion, mProgressBar; + private TextView mVersionActual, mVersionNueva; + private Button mObtenerDatos, mDescargar; + + + // Runnable que se ejecutará desde el hilo principal cuando termina la + // obtención de datos en segundo plano. Equivalente al onPostExecute() de AsyncTask + private Runnable finishBackgroundDownload = new Runnable() { + @Override + public void run() { + mProgressBar.setVisibility(View.GONE); + if(mVC.isNewVersionAvailable()){ + // Hay una nueva versión disponible + mActualizacion.setVisibility(View.VISIBLE); + mActualizada.setVisibility(View.GONE); + // Mostramos los datos + mVersionActual.setText("Versión actual: " + mVC.getCurrentVersionName()); + mVersionNueva.setText("Versión disponible: " + mVC.getLatestVersionName()); + }else{ + // La aplicación está actualizada + mActualizacion.setVisibility(View.GONE); + mActualizada.setVisibility(View.VISIBLE); + } + } + }; + + // Runnable encargado de descargar los datos en un hilo en segundo plano. + // Equivalente al doInBackground() de AsyncTask + private Runnable backgroundDownload = new Runnable() { + @Override + public void run() { + mVC.getData(AutoUpdateActivity.this); + // Cuando acabe la descarga actualiza la interfaz + handler.post(finishBackgroundDownload); + } + }; + + // Runnable encargado de descargar los datos en un hilo en segundo plano. + // Equivalente al doInBackground() de AsyncTask + private Runnable backgroundDownloadAPK = new Runnable() { + @Override + public void run() { + try { + + File storageDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); + String pathapk = storageDir.getAbsolutePath() + "/almacen.apk"; //AutoUpdateActivity.this.getFilesDir() + "/lectura.apk"; + mVC.getDownloadURL(pathapk); + + //final Uri uri = Uri.parse(pathapk); + //File toInstall = new File(pathapk); + + File toInstall = new File(pathapk); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Uri apkUri = FileProvider.getUriForFile(AutoUpdateActivity.this, BuildConfig.APPLICATION_ID + ".provider", toInstall); + Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); + intent.setData(apkUri); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + AutoUpdateActivity.this.startActivity(intent); + finish(); + } else { + Uri apkUri = Uri.fromFile(toInstall); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + AutoUpdateActivity.this.startActivity(intent); + finish(); + } + + + ///data/user/0/mx.gob.jumapacelaya.lecturas/files/lectura.apk + /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Uri contentUri = FileProvider.getUriForFile(getBaseContext(), BuildConfig.APPLICATION_ID + ".provider", new File(finalDestination)); + Intent openFileIntent = new Intent(Intent.ACTION_VIEW); + openFileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + openFileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + openFileIntent.setData(contentUri); + startActivity(openFileIntent); + + finish(); + } else { + /*Uri apkUri = Uri.fromFile(new File(pathapk)); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + finish(); + + Uri apkUri = Uri.fromFile(new File(pathapk)); + Intent install = new Intent(Intent.ACTION_VIEW); + install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + install.setDataAndType(apkUri, + "application/vnd.android.package-archive"); + startActivity(install); + finish(); + }*/ + + + }catch (Exception ex){ + ex.printStackTrace(); + Toast t = Toast.makeText(getApplicationContext(), ex.getMessage(), Toast.LENGTH_LONG); + t.show(); + } + } + }; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Inicializa la interfaz + setContentView(R.layout.activity_auto_update); + mActualizada = findViewById(R.id.actualizada); + mActualizacion = findViewById(R.id.actualizacion); + mProgressBar = findViewById(R.id.progress_datos); + mDescargar = (Button)findViewById(R.id.bt_descarga); + mObtenerDatos = (Button)findViewById(R.id.bt_obtener_datos); + mVersionActual = (TextView)findViewById(R.id.actualizacion_version_actual); + mVersionNueva = (TextView)findViewById(R.id.actualizacion_version_nueva); + + // Coloca listeners en los dos botones + mObtenerDatos.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // Crea un nuevo hilo para descargar los datos + mProgressBar.setVisibility(View.VISIBLE); + Thread downloadThread = new Thread(backgroundDownload, "VersionChecker"); + downloadThread.start(); + } + }); + mDescargar.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Thread downloadThread = new Thread(backgroundDownloadAPK, "APK Donwload"); + downloadThread.start(); + + // Lanza un Intent con el enlace de la descarga, Android se + // encargará del resto + //startActivity(new Intent("android.intent.action.VIEW", Uri.parse(mVC.getDownloadURL()))); + + /*String uri = "googlechrome://navigate?url=" + mVC.getDownloadURL(); + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(uri)); + + //i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + //i.setPackage("com.android.chrome"); + startActivity(i); + */ + + /*Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse("ftp://172.16.0.9:21")); + + //You can add FTP credentials: + intent.putExtra("ftp_username", "lecturas"); + intent.putExtra("ftp_password", "lec134med"); + //intent.putExtra("ftp_keyfile", "/sdcard/rsakey.txt"); + //intent.putExtra("ftp_keypass", "optionalkeypassword"); + //If credentials are not provided but required then AndFTP will prompt for login and password. + + //Setup optional FTP preferences: + intent.putExtra("ftp_pasv", "true"); + //intent.putExtra("ftps_mode", "implicit"); + //intent.putExtra("ftp_encoding", "UTF-8"); + + //Finally start the Activity: + //startActivityForResult(intent, BROWSE_REQUEST); + startActivity(intent);*/ + + /*Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(mVC.getDownloadURL())); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + i.setPackage("com.android.chrome");*/ + /*PackageManager packageManager = AutoUpdateActivity.this.getPackageManager(); + File file = new File(AutoUpdateActivity.this.getFilesDir(),"lecturas.apk"); + String mimeType = "application/vnd.android.package-archive"; + String target= mVC.getDownloadURL(); + Intent intent = new Intent(android.content.Intent.ACTION_SENDTO); + intent.setDataAndType(android.net.Uri.parse(target),mimeType); + //intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); + startActivity(intent); + if (packageManager.queryIntentActivities(intent,0).size() == 0) { + Toast.makeText(getBaseContext(), + "", Toast.LENGTH_LONG) + .show(); + } else { + startActivity(intent); + }*/ + + } + }); + + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/Version.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/Version.java new file mode 100644 index 0000000..2071df2 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/Version.java @@ -0,0 +1,41 @@ +package jumapacelaya.gob.mx.almacen.updatepp; + +import com.google.gson.Gson; + +public class Version { + private double versionCode; + private String versionName; + private String downloadURL; + + public static Version fromJson(String s){ + return new Gson().fromJson(s, Version.class); + } + + public String toString(){ + return new Gson().toJson(this); + } + + public double getVersionCode() { + return versionCode; + } + + public void setVersionCode(double versionCode) { + this.versionCode = versionCode; + } + + public String getVersionName() { + return versionName; + } + + public void setVersionName(String versionName) { + this.versionName = versionName; + } + + public String getDownloadURL() { + return downloadURL; + } + + public void setDownloadURL(String downloadURL) { + this.downloadURL = downloadURL; + } +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/VersionCheck.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/VersionCheck.java new file mode 100644 index 0000000..0e4da63 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/updatepp/VersionCheck.java @@ -0,0 +1,294 @@ +package jumapacelaya.gob.mx.almacen.updatepp; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.util.Log; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +public class VersionCheck { + + /** + * Enlace al archivo publico de la version + */ + public static final String INFO_FILE = "https://www.dropbox.com/s/8xp3jss13vfpvd3/versionApp.txt?dl=0"; + public static final String SERVER = "172.16.0.9"; + public static final String FTP_INFO_FILE = "versionApp.txt"; + public static final String FTP_USER = "almacen"; + public static final String FTP_PWD = "alm134jumapa"; + + /** + * El código de versión establecido en el AndroidManifest.xml de la versión + * instalada de la aplicación. Es el valor numérico que usa Android para + * diferenciar las versiones. + */ + private int currentVersionCode; + /** + * El nombre de versión establecido en el AndroidManifest.xml de la versión + * instalada. Es la cadena de texto que se usa para identificar al versión + * de cara al usuario. + */ + private String currentVersionName; + + /** + * El código de versión establecido en el AndroidManifest.xml de la última + * versión disponible de la aplicación. + */ + private int latestVersionCode; + /** + * El nombre de versión establecido en el AndroidManifest.xml de la última + * versión disponible. + */ + private String latestVersionName; + + /** + * Enlace de descarga directa de la última versión disponible. + */ + private String downloadURL; + + /** + * Método para inicializar el objeto. Se debe llamar antes que a cualquie + * otro, y en un hilo propio (o un AsyncTask) para no bloquear al interfaz + * ya que hace uso de Internet. + * + * @param context + * El contexto de la aplicación, para obtener la información de + * la versión actual. + */ + public void getData(Context context) { + try{ + // Datos locales + PackageInfo pckginfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + currentVersionCode = pckginfo.versionCode; + currentVersionName = pckginfo.versionName; + + // Datos remotos + //String data = downloadHttp(new URL(INFO_FILE)); + //Por FTP + String data = downloadFtp2(); + JSONObject json = new JSONObject(data); + + if(json.has("lecturas")){ + json = json.getJSONObject("lecturas"); + + latestVersionCode = json.getInt("versionCode"); + latestVersionName = json.getString("versionName"); + downloadURL = json.getString("downloadURL"); + Log.d("AutoUpdate", "Datos obtenidos con éxito"); + } + + }catch(JSONException e){ + Log.e("AutoUpdate", "Ha habido un error con el JSON", e); + }catch(PackageManager.NameNotFoundException e){ + Log.e("AutoUpdate", "Ha habido un error con el packete :S", e); + }catch(IOException e){ + Log.e("AutoUpdate", "Ha habido un error con la descarga", e); + } + } + + /** + * Método para comparar la versión actual con la última . + * + * @return true si hay una versión más nueva disponible que la actual. + */ + public boolean isNewVersionAvailable() { + if(getLatestVersionCode() > getCurrentVersionCode()) + return true; + else if(getLatestVersionCode() == getCurrentVersionCode()) + return !getLatestVersionName().equals(getCurrentVersionName()); + else + return false; + } + + /** + * Devuelve el código de versión actual. + * + * @return + */ + public int getCurrentVersionCode() { + return currentVersionCode; + } + + /** + * Devuelve el nombre de versión actual. + * + * @return + */ + public String getCurrentVersionName() { + return currentVersionName; + } + + /** + * Devuelve el código de la última versión disponible. + * + * @return + */ + public int getLatestVersionCode() { + return latestVersionCode; + } + + /** + * Devuelve el nombre de la última versión disponible. + * + * @return + */ + public String getLatestVersionName() { + return latestVersionName; + } + + /** + * Devuelve el enlace de descarga de la última versión disponible + * + * @return + */ + public boolean getDownloadURL(String path) throws IOException { + String ftpUrl = String.format( + "ftp://"+FTP_USER+":"+FTP_PWD+"@"+SERVER+":%d/" + downloadURL, 21); + + URLConnection urlConnection = new URL(ftpUrl).openConnection(); + InputStream inputStream = urlConnection.getInputStream(); + + File file = new File(path); + if (file.exists()) + file.delete(); + + //write file + OutputStream out = new BufferedOutputStream(new FileOutputStream(path)); + byte[] buffer = new byte[1024]; + int lengthRead; + while((lengthRead = inputStream.read(buffer))>0) + + { + out.write(buffer, 0, lengthRead); + out.flush(); + } + + out.close(); + inputStream.close(); + + return true; + + } + + /** + * Método auxiliar usado por getData() para leer el archivo de información. + * Encargado de conectarse a la red, descargar el archivo y convertirlo a + * String. + * + * @param url + * La URL del archivo que se quiere descargar. + * @return Cadena de texto con el contenido del archivo + * @throws IOException + * Si hay algún problema en la conexión + */ + private static String downloadHttp(URL url) throws IOException { + HttpURLConnection c = (HttpURLConnection)url.openConnection(); + c.setRequestMethod("GET"); + c.setReadTimeout(15 * 1000); + c.setUseCaches(false); + c.connect(); + BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream())); + StringBuilder stringBuilder = new StringBuilder(); + String line = null; + while((line = reader.readLine()) != null){ + stringBuilder.append(line + "n"); + } + return stringBuilder.toString(); + } + /** + * Método auxiliar usado por getData() para leer el archivo de información. + * Encargado de conectarse a la red, descargar el archivo y convertirlo a + * String. + * + * @return Cadena de texto con el contenido del archivo + * @throws IOException + * Si hay algún problema en la conexión + */ + private static String downloadFtp2() throws IOException { + String ftpUrl = String.format( + "ftp://"+FTP_USER+":"+FTP_PWD+"@"+SERVER+":%d/" + FTP_INFO_FILE, 21); + + URLConnection urlConnection = new URL(ftpUrl).openConnection(); + InputStream inputStream = urlConnection.getInputStream(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + StringBuilder stringBuilder = new StringBuilder(); + String line = null; + while((line = reader.readLine()) != null){ + stringBuilder.append(line + "\n"); + } + return stringBuilder.toString(); + } + + /** + * Método auxiliar usado por getData() para leer el archivo de información. + * Encargado de conectarse a la red, descargar el archivo y convertirlo a + * String. + * + * @param server + * La URL del archivo que se quiere descargar. + * @return Cadena de texto con el contenido del archivo + * @throws IOException + * Si hay algún problema en la conexión + */ + /*private static String downloadFtp(String server, String fileversion) throws IOException { + boolean status = false; + StringBuilder stringBuilder = new StringBuilder(); + + try { + FTPClient ftpClient = new FTPClient(); + ftpClient.setConnectTimeout(10 * 1000); + ftpClient.connect(InetAddress.getByName(server)); + + status = ftpClient.login(FTP_USER, FTP_PWD); + + Log.e("isFTPConnect", String.valueOf(status)); + + if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){ + ftpClient.setFileType(FTP.ASCII_FILE_TYPE); + ftpClient.enterLocalActiveMode(); + + String workingDir = ftpClient.printWorkingDirectory(); + + ftpClient.changeWorkingDirectory("apps"); + + + FileOutputStream desFileStream = new FileOutputStream(desFilePath); + status = ftpClient.retrieveFile(srcFilePath, desFileStream); + desFileStream.close(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream())); + String line = null; + while ((line = reader.readLine()) != null) { + stringBuilder.append(line + "n"); + } + } + + ftpClient.logout(); + ftpClient.disconnect(); + + }catch (SocketException e){ + + }catch (UnknownHostException e){ + + }catch (IOException e){ + + } + return stringBuilder.toString(); + }*/ + +} diff --git a/app/src/main/java/jumapacelaya/gob/mx/almacen/utils/StringUitils.java b/app/src/main/java/jumapacelaya/gob/mx/almacen/utils/StringUitils.java new file mode 100644 index 0000000..c9f5aa0 --- /dev/null +++ b/app/src/main/java/jumapacelaya/gob/mx/almacen/utils/StringUitils.java @@ -0,0 +1,17 @@ +package jumapacelaya.gob.mx.almacen.utils; + +public class StringUitils { + + public static String jsonescape(String raw){ + String escaped = raw; + escaped = escaped.replace("\\", "\\\\"); + escaped = escaped.replace("\"", "\\\""); + escaped = escaped.replace("\b", "\\b"); + escaped = escaped.replace("\f", "\\f"); + escaped = escaped.replace("\n", "\\n"); + escaped = escaped.replace("\r", "\\r"); + escaped = escaped.replace("\t", "\\t"); + // TODO: escape other non-printing characters using uXXXX notation + return escaped; + } +} diff --git a/app/src/main/res/anim/anim_rotate.xml b/app/src/main/res/anim/anim_rotate.xml new file mode 100644 index 0000000..f413be9 --- /dev/null +++ b/app/src/main/res/anim/anim_rotate.xml @@ -0,0 +1,12 @@ + + diff --git a/app/src/main/res/drawable-v24/barcode.png b/app/src/main/res/drawable-v24/barcode.png new file mode 100644 index 0000000..d4dab27 Binary files /dev/null and b/app/src/main/res/drawable-v24/barcode.png differ diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg.xml b/app/src/main/res/drawable/bg.xml new file mode 100644 index 0000000..32d5b8a --- /dev/null +++ b/app/src/main/res/drawable/bg.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/custom_ripple.xml b/app/src/main/res/drawable/custom_ripple.xml new file mode 100644 index 0000000..18b2e80 --- /dev/null +++ b/app/src/main/res/drawable/custom_ripple.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/custom_ripple2.xml b/app/src/main/res/drawable/custom_ripple2.xml new file mode 100644 index 0000000..e7ba127 --- /dev/null +++ b/app/src/main/res/drawable/custom_ripple2.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/gradient_animation.xml b/app/src/main/res/drawable/gradient_animation.xml new file mode 100644 index 0000000..4052612 --- /dev/null +++ b/app/src/main/res/drawable/gradient_animation.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/gradient_center.xml b/app/src/main/res/drawable/gradient_center.xml new file mode 100644 index 0000000..5c3cbee --- /dev/null +++ b/app/src/main/res/drawable/gradient_center.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/gradient_end.xml b/app/src/main/res/drawable/gradient_end.xml new file mode 100644 index 0000000..db8fb0f --- /dev/null +++ b/app/src/main/res/drawable/gradient_end.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/gradient_fondo.xml b/app/src/main/res/drawable/gradient_fondo.xml new file mode 100644 index 0000000..938aa79 --- /dev/null +++ b/app/src/main/res/drawable/gradient_fondo.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/gradient_start.xml b/app/src/main/res/drawable/gradient_start.xml new file mode 100644 index 0000000..78d5a51 --- /dev/null +++ b/app/src/main/res/drawable/gradient_start.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_barcode.xml b/app/src/main/res/drawable/ic_barcode.xml new file mode 100644 index 0000000..e4b7377 --- /dev/null +++ b/app/src/main/res/drawable/ic_barcode.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher.png b/app/src/main/res/drawable/ic_launcher.png new file mode 100644 index 0000000..f74c9a7 Binary files /dev/null and b/app/src/main/res/drawable/ic_launcher.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_plus.xml b/app/src/main/res/drawable/ic_plus.xml new file mode 100644 index 0000000..a68ec6a --- /dev/null +++ b/app/src/main/res/drawable/ic_plus.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/logo_circle.png b/app/src/main/res/drawable/logo_circle.png new file mode 100644 index 0000000..69ec0ab Binary files /dev/null and b/app/src/main/res/drawable/logo_circle.png differ diff --git a/app/src/main/res/drawable/logojumcel.png b/app/src/main/res/drawable/logojumcel.png new file mode 100644 index 0000000..606bc4b Binary files /dev/null and b/app/src/main/res/drawable/logojumcel.png differ diff --git a/app/src/main/res/layout/activity_auto_update.xml b/app/src/main/res/layout/activity_auto_update.xml new file mode 100644 index 0000000..73c95ec --- /dev/null +++ b/app/src/main/res/layout/activity_auto_update.xml @@ -0,0 +1,94 @@ + + + + + + + + + + +