diff --git a/GPOS 700/README.md b/GPOS 700/README.md index 9fae870..c8b0af5 100644 --- a/GPOS 700/README.md +++ b/GPOS 700/README.md @@ -1,2 +1,90 @@ -# flutter +[![](https://pbs.twimg.com/media/EKzBdw7WwAQrq8J.png)](https://www.gertec.com.br/) +# Prezados e parceiros e escovadores de Bits!! + +Obrigado por acessarem nosso github!! + +Nestes code samples, você encontra exemplos de integração com os terminais Gertec GPOS700 e TSG800 em diversas linguagens tais como Java, Delphi, Flutter, React-Native, Ionic, Xamarin-Android e Xamarin-Forms! + +Seja capaz de executar em curto período de tempo as diversas funcionalidades para seu aplicativo: + + - Impressão + - Código de Barras + - Leitura de Cartão NFC + - Integração com TEF Sw Express e Ger7 + +# Gertec Developer +Quero fazer parte da Comunidade e receber informações. +Está bem fácil. + +[Cadastre-se aqui]( https://www.gertec.com.br/login/software-house/cadastro/) + +# GPOS700, TSG800, MP5 +GPOS700 é o POS com PCI e que permite você desenvolver um aplicativo Android nele e colocar a solução de cartão de credito também dentro dele. + +O TSG800 é um terminal sem pagamento, um Smart Printer, mas você pode usar uma “moderninha” e parear a “moderninha” com ele por Bluetooth e fazer o pagamento. + +MP5 em breve teremos novidades sobre este Pinpad Bluetooth para você desenvolver pareando com o celular ou com o TSG800 + +Em nosso site você pode ter acesso a mais informações, seguem links: + +**G700** https://www.gertec.com.br/produtos/gpos700/ + +**G800** https://www.gertec.com.br/produtos/tsg800/ + +**MP5** https://www.gertec.com.br/produtos/mp5/ + +# PILOTO MP5 +Desejo participar o Piloto com o Pinpad Bluetooth MP5, como fazer? Super simples, me envie um e-mail com seu nome e telefone para **claudenir.andrade@gertec.com.br** com o título **“Piloto MP5”**. + +Assim que tivemos disponível peças para desenvolvedor a preço reduzido e funcionando com a SwExpress e Multi-Chave, vamos te enviar a informação. + +# Desejo adquirir o equipamento para meu desenvolvimento +A MP5 (Pinpad Bluetooth) ainda não está disponível pra desenvolvedor, em breve estará, sem dúvida e 100% integrado com a SwExpress. + +O GPOS700 para Desenvolvedor o valor e de R$1.099,00 em até 5x no cartão ou 28Dias no boleto. + +Como adquirir? + 1. Preencha esta planilha em anexo com os dados de sua empresa + 2. pode me enviar Claudenir.andrade@gertec.com.br + +O TSG800 você pode adquirir direto de nosso e-commerce com uma promoção para Desenvolvedor + +[Click aqui adquirir um TSG 800]( +https://loja.gertec.com.br/produto/terminal-smart-g800-para-desenvolvimento/) + +Código de Promoção : **TSG800DEV** + +Aplicando o código acima o preço fica em 999,00 Até 12X no Cartão + +# GITHUB e VIDEOS +Nosso GitHub: [Gertec Developer](https://github.com/gertecdeveloper) + +Nosso Canal de vídeos: [Gertec Developer YouTube](https://www.youtube.com/gertecdeveloper) + - [Video **“Out-Of-box”** do TSG800 e GPOS700]( https://www.youtube.com/watch?v=bW101g2mSgI&t=0s) + - [Playlist completa](https://www.youtube.com/c/GertecDeveloper/videos) + +# TEF no GPOS (MSITEF ou GER7 com GPOS700). +Para saber o preço e a modalidade comercial pra uso do TEF SwExpress ou Ger7 com o GPOS700, favor tratar com + + - **Wilmar Poli** wilmar.poli@gertec.com.br Celular 011 98833 6696 + + +## Software Express +Para ter acesso a documentação, Simuladores e Roteiros de homologação, favor entrar em contato com: + +#### **Fernanda Ramos** +fernanda.ramos@softwareexpress.com.br + +#### **Ger7** + +Para ter acesso a documentação, Simuladores e Roteiros de homologação, favor se cadastrarem no seguinte link: + +https://integracao.ger7.com.br/ + +Fiquem com meu contato, estou a inteira disposição + +#### **Claudenir Andrade** +011 9 8137 0262 + +claudenir.andrade@gertec.com.br. \ No newline at end of file diff --git a/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs b/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs index e889521..27b37ed 100644 --- a/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs +++ b/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs @@ -1,2 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= eclipse.preferences.version=1 +gradle.user.home= +java.home=C\:/Program Files/Java/jdk-11.0.8 +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/GPOS 700/android/app/.classpath b/GPOS 700/android/app/.classpath index eb19361..4a04201 100644 --- a/GPOS 700/android/app/.classpath +++ b/GPOS 700/android/app/.classpath @@ -1,6 +1,6 @@ - + diff --git a/GPOS 700/android/app/.settings/org.eclipse.buildship.core.prefs b/GPOS 700/android/app/.settings/org.eclipse.buildship.core.prefs index b1886ad..c304bf6 100644 --- a/GPOS 700/android/app/.settings/org.eclipse.buildship.core.prefs +++ b/GPOS 700/android/app/.settings/org.eclipse.buildship.core.prefs @@ -1,2 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.3)) connection.project.dir=.. eclipse.preferences.version=1 +gradle.user.home= +java.home=C\:/Program Files/Java/jdk1.8.0_241 +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/GPOS 700/android/app/build.gradle b/GPOS 700/android/app/build.gradle index 575623c..90312f8 100644 --- a/GPOS 700/android/app/build.gradle +++ b/GPOS 700/android/app/build.gradle @@ -32,9 +32,8 @@ android { } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.flutter_gertec" - minSdkVersion 20 + minSdkVersion 22 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -49,21 +48,12 @@ android { keyPassword 'Development@GertecDeveloper2018' } } - defaultConfig { - applicationId "com.example.flutter_gertec" - minSdkVersion 19 - targetSdkVersion 28 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - buildTypes { release { - shrinkResources true - minifyEnabled true - multiDexEnabled true + minifyEnabled false + useProguard false + shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.gertec } @@ -71,7 +61,6 @@ android { signingConfig signingConfigs.gertec } } - } flutter { @@ -80,8 +69,8 @@ flutter { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) -// implementation(name:'libgedi-0.190121.gpos800', ext:'aar') implementation(name: 'payment-1.14.10.181016', ext: 'aar') + implementation(name: 'SatGerLib', ext: 'aar') implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' @@ -89,6 +78,7 @@ dependencies { implementation 'com.google.zxing:core:3.2.0' androidTestImplementation 'androidx.test:runner:1.1.1' implementation 'me.dm7.barcodescanner:zxing:1.9.8' + implementation 'com.google.code.gson:gson:2.8.6' implementation('com.journeyapps:zxing-android-embedded:3.4.0') androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' } diff --git a/GPOS 700/android/app/libs/SatGerLib.aar b/GPOS 700/android/app/libs/SatGerLib.aar new file mode 100644 index 0000000..75f1fbc Binary files /dev/null and b/GPOS 700/android/app/libs/SatGerLib.aar differ diff --git a/GPOS 700/android/app/src/debug/AndroidManifest.xml b/GPOS 700/android/app/src/debug/AndroidManifest.xml index 7806c92..9f04d6b 100644 --- a/GPOS 700/android/app/src/debug/AndroidManifest.xml +++ b/GPOS 700/android/app/src/debug/AndroidManifest.xml @@ -1,8 +1,10 @@ - + + + + + diff --git a/GPOS 700/android/app/src/main/AndroidManifest.xml b/GPOS 700/android/app/src/main/AndroidManifest.xml index 7290d8f..e5de1b1 100644 --- a/GPOS 700/android/app/src/main/AndroidManifest.xml +++ b/GPOS 700/android/app/src/main/AndroidManifest.xml @@ -1,21 +1,31 @@ + + + + + + + + - + + - - + android:icon="@mipmap/gertec_one" + tools:replace="android:icon , android:label" + android:label="GertecOne Flutter"> + + + @@ -32,23 +42,30 @@ android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:windowSoftInputMode="adjustResize"> + - + + + + + + + + + - - - + diff --git a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/CodigoBarrasV2.java b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/CodigoBarrasV2.java index 7ce65c0..7d7a0ed 100644 --- a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/CodigoBarrasV2.java +++ b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/CodigoBarrasV2.java @@ -3,9 +3,7 @@ import android.Manifest; import android.app.AlertDialog; import android.content.DialogInterface; -import android.content.Intent; import android.content.pm.PackageManager; -import android.media.MediaPlayer; import android.os.Build; import android.os.Bundle; import android.view.View; @@ -17,7 +15,6 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; -import com.example.flutter_gertec.R; import com.google.zxing.Result; import me.dm7.barcodescanner.zxing.ZXingScannerView; diff --git a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/GertecPrinter.java b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/GertecPrinter.java index af666ab..461d828 100644 --- a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/GertecPrinter.java +++ b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/GertecPrinter.java @@ -18,7 +18,7 @@ import br.com.gertec.gedi.enums.GEDI_PRNTR_e_BarCodeType; import br.com.gertec.gedi.enums.GEDI_PRNTR_e_Status; import br.com.gertec.gedi.exceptions.GediException; -//import br.com.gertec.gedi.impl.Gedi; +import br.com.gertec.gedi.interfaces.ICL; import br.com.gertec.gedi.interfaces.IGEDI; import br.com.gertec.gedi.interfaces.IPRNTR; import br.com.gertec.gedi.structs.GEDI_PRNTR_st_BarCodeConfig; @@ -27,6 +27,7 @@ public class GertecPrinter { + ICL icl = null; // Definições private final String IMPRESSORA_ERRO = "Impressora com erro."; @@ -82,6 +83,7 @@ private void startIGEDI() { GEDI.init(this.context); this.iGedi = GEDI.getInstance(this.context); this.iPrint = this.iGedi.getPRNTR(); + icl = GEDI.getInstance().getCL(); // Get ICL try { new Thread().sleep(250); } catch (InterruptedException e) { @@ -561,6 +563,7 @@ public boolean isImpressoraOK() { public void ImpressoraInit() throws GediException { try { if (this.iPrint != null && !isPrintInit) { + this.icl.PowerOff(); // Desligar Módulo NFC - comando Mandatório antes de enviar comandos para a impressora." this.iPrint.Init(); isPrintInit = true; } diff --git a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/LeitorNFC.java b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/LeitorNFC.java index 5b0ed5b..d4c0551 100644 --- a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/LeitorNFC.java +++ b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/LeitorNFC.java @@ -75,7 +75,7 @@ protected void LerCartaoNfc() { intent.putExtra("codigoNFCID", idCartao().toString()); setResult(RESULT_OK, intent); finish(); - }else if(IsoDep.get(tag)!=null){ + } else if (IsoDep.get(tag) != null) { isoDep = IsoDep.get(tag); intent.putExtra("codigoNFCID", idCartao().toString()); setResult(RESULT_OK, intent); @@ -88,9 +88,9 @@ public String idCartao() { byte[] idCartao = null; long result = 0; - if(mifareClassic != null){ + if (mifareClassic != null) { idCartao = mifareClassic.getTag().getId(); - }else if (isoDep != null){ + } else if (isoDep != null) { idCartao = isoDep.getTag().getId(); } diff --git a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/MainActivity.java b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/MainActivity.java index a8bda40..4a9cd76 100644 --- a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/MainActivity.java +++ b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/MainActivity.java @@ -1,54 +1,87 @@ package com.example.flutter_gertec; import android.content.Intent; -import android.nfc.Tag; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.PersistableBundle; + +import java.io.IOException; import java.util.List; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; + +import com.google.gson.Gson; import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; + +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; +import java.util.Map; + +import br.com.gertec.gedi.exceptions.GediException; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.GeneratedPluginRegistrant; + import static android.hardware.Camera.Parameters.FLASH_MODE_ON; public class MainActivity extends FlutterActivity { private GertecPrinter gertecPrinter; public static final String G700 = "GPOS700"; - public static final String G800 = "Smart G800"; - private static final String version = "RC03"; - private MethodChannel.Result _result; // private NfcAdapter nfcAdapter; + private MethodChannel.Result _result; // Instanciando uma variavel do tipo Result, para enviar o resultado para o + // flutter public static String Model = Build.MODEL; - private String resultado_Leitor; + private String resultado_Leitor; // Instanciando uma variavel que vai armazenar o resultado ao ler o codigo de + // Barras no V1 private IntentIntegrator qrScan; - private String tipo; + private String tipo; // Armazerna o tipo de codigo de barra que ser lido private ArrayList arrayListTipo; - private static final String[] CHANNEL = { "samples.flutter.dev/gedi" }; + private static final String CHANNEL = "samples.flutter.dev/gedi"; // Canal de comunicação do flutter com o Java private ConfigPrint configPrint = new ConfigPrint(); + private SatLib satLib; + Intent intentGer7 = new Intent(Intent.ACTION_VIEW, Uri.parse("pos7api://pos7")); // Instanciando o Intent da Ger7 -- + // É importante que o apk da Ger7 + // esteje instalado na POS + Intent intentSitef = new Intent("br.com.softwareexpress.sitef.msitef.ACTIVITY_CLISITEF"); // Instanciando o Intent + // do M-Sitef -- É + // importante que o + // programa "Sitef Demo" + // esteja em execução. + Gson gson = new Gson(); public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); gertecPrinter.setConfigImpressao(configPrint); } + @Override + protected void onResume() { + super.onResume(); + satLib = new SatLib(this); // Instancia uma variavel da classe SatLib, que possui todas as funções para + // envio de ações para o Sat. + gertecPrinter = new GertecPrinter(this); + } + public MainActivity() { super(); this.arrayListTipo = new ArrayList(); - gertecPrinter = new GertecPrinter(this); } public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine); - new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL[0]) + new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { _result = result; + Map map; + Bundle bundle = new Bundle(); Intent intent = null; switch (call.method) { + // Inicia o intent que vai fazer a leitura do Nfc pelo metodo Nativo case "lernfcid": try { intent = new Intent(this, LeitorNFC.class); @@ -58,6 +91,7 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { result.notImplemented(); } break; + // Inicia o intent que vai fazer a leitura do Nfc pelo metodo Gedi case "lernfcgedi": try { intent = new Intent(this, NfcExemploGedi.class); @@ -67,6 +101,7 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { result.notImplemented(); } break; + // Verifica o status da impressora case "checarImpressora": try { gertecPrinter.getStatusImpressora(); @@ -75,6 +110,8 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { e.printStackTrace(); } break; + // Inicia a função que vai abrir o leitor de codigo de barra + // Do flutter ele vai pegar o "tipo" de codigo que deseja ser lido case "leitorCodigov1": try { tipo = call.argument("tipoLeitura"); @@ -83,10 +120,116 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { e.printStackTrace(); } break; + // Verifica qual ação do Sat foi solicitada e retorna o codigo de resposta da + // Sefaz + // "satLib" possui todas funções do Sat + case "AtivarSAT": + _result.success(satLib.ativarSat(call.argument("codigoAtivar"), + call.argument("cnpj"), call.argument("random"))); + break; + case "AssociarSAT": + _result.success(satLib.associarSat(call.argument("cnpj"), call.argument("cnpjSoft"), + call.argument("codigoAtivar"), call.argument("assinatura"), + call.argument("random"))); + break; + case "ConsultarSat": + _result.success(satLib.consultarSat(call.argument("random"))); + break; + case "ConsultarStatusOperacional": + String a = call.argument("codigoAtivar"); + int b = call.argument("random"); + _result.success(satLib.consultarStatusOperacional(call.argument("random"), + call.argument("codigoAtivar"))); + break; + case "EnviarTesteFim": + _result.success(satLib.enviarTesteFim(call.argument("codigoAtivar"), + call.argument("xmlVenda"), call.argument("random"))); + break; + case "EnviarTesteVendas": + _result.success(satLib.enviarTesteVendas(call.argument("codigoAtivar"), + call.argument("xmlVenda"), call.argument("random"))); + break; + case "CancelarUltimaVenda": + _result.success(satLib.cancelarUltimaVenda(call.argument("codigoAtivar"), + call.argument("xmlCancelamento"), call.argument("chaveCancelamento"), + call.argument("random"))); + break; + case "ConsultarNumeroSessao": + _result.success(satLib.consultarNumeroSessao(call.argument("codigoAtivar"), + call.argument("chaveSessao"), call.argument("random"))); + break; + case "EnviarConfRede": + try { + _result.success(satLib.enviarConfRede(call.argument("random"), + call.argument("dadosXml"), call.argument("codigoAtivar"))); + } catch (IOException e) { + e.printStackTrace(); + } + break; + case "TrocarCodAtivacao": + _result.success( + satLib.trocarCodAtivacao(call.argument("codigoAtivar"), call.argument("op"), + call.argument("codigoAtivacaoNovo"), call.argument("random"))); + break; + case "BloquearSat": + _result.success( + satLib.bloquearSat(call.argument("codigoAtivar"), call.argument("random"))); + break; + case "DesbloquearSat": + _result.success(satLib.desbloquearSat(call.argument("codigoAtivar"), + call.argument("random"))); + break; + case "ExtrairLog": + _result.success( + satLib.extrairLog(call.argument("codigoAtivar"), call.argument("random"))); + break; + case "AtualizarSoftware": + _result.success(satLib.atualizarSoftware(call.argument("codigoAtivar"), + call.argument("random"))); + break; + case "Versao": + _result.success(satLib.versao()); + break; + // Inicia o intent que vai fazer a leitura do codigo de barras v2 + // Ler qualquer tipo de codigo de barra case "leitorCodigoV2": intent = new Intent(this, CodigoBarrasV2.class); startActivity(intent); break; + // Inicia o intent que vai enviar o Json recebido do flutter para o Ger7 e após + // isto pegar seu retorno (Json) + case "realizarAcaoGer7": + String json = call.argument("json"); + intentGer7.putExtra("jsonReq", json); + startActivityForResult(intentGer7, 4713); + break; + // Inicia o intent que vai enviar o Map recebido do flutter para o M-Sitef e + // após isto pegar seu retorno + case "realizarAcaoMsitef": + map = call.argument("mapMsiTef"); + for (String key : map.keySet()) { + bundle.putString(key, map.get(key)); + } + intentSitef.putExtras(bundle); + startActivityForResult(intentSitef, 4321); + break; + // Esta função vai chamar as classes para realizar as impressões de acordo com + // as configurações recebidas do flutter + case "fimimpressao": + try { + gertecPrinter.ImpressoraOutput(); + result.success("Finalizou impressao"); + } catch (GediException e) { + e.printStackTrace(); + } + break; + case "avancaLinha": + try { + gertecPrinter.avancaLinha(call.argument("quantLinhas")); + } catch (GediException e) { + e.printStackTrace(); + } + break; case "imprimir": try { gertecPrinter.getStatusImpressora(); @@ -95,16 +238,15 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { String mensagem = call.argument("mensagem"); switch (tipoImpressao) { case "Texto": - String alinhar = call.argument("alinhar"); - int size = call.argument("size"); - String fontFamily = call.argument("font"); List options = call.argument("options"); configPrint.setItalico(options.get(1)); configPrint.setSublinhado(options.get(2)); + System.out.println(call.argument("size").toString()); configPrint.setNegrito(options.get(0)); - configPrint.setTamanho(size); - configPrint.setFonte(fontFamily); - configPrint.setAlinhamento(alinhar); + System.out.println(call.argument("font").toString()); + configPrint.setTamanho(call.argument("size")); + configPrint.setFonte(call.argument("font")); + configPrint.setAlinhamento(call.argument("alinhar")); gertecPrinter.setConfigImpressao(configPrint); gertecPrinter.imprimeTexto(mensagem); break; @@ -115,19 +257,15 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { gertecPrinter.imprimeImagem("logogertec"); break; case "CodigoDeBarra": - int height = call.argument("height"); - int width = call.argument("width"); - String barCode = call.argument("barCode"); configPrint.setAlinhamento("CENTER"); gertecPrinter.setConfigImpressao(configPrint); - gertecPrinter.imprimeBarCodeIMG(mensagem, height, width, barCode); + gertecPrinter.imprimeBarCodeIMG(mensagem, call.argument("height"), + call.argument("width"), call.argument("barCode")); break; case "TodasFuncoes": ImprimeTodasAsFucoes(); break; } - gertecPrinter.avancaLinha(200); - gertecPrinter.ImpressoraOutput(); } } catch (Exception e) { e.printStackTrace(); @@ -150,7 +288,6 @@ private void startCamera() { } private void ImprimeTodasAsFucoes() { - configPrint.setItalico(false); configPrint.setNegrito(true); configPrint.setTamanho(20); @@ -286,14 +423,39 @@ private void ImprimeTodasAsFucoes() { gertecPrinter.imprimeTexto("===[Codigo QrCode Gertec IMG]=="); gertecPrinter.imprimeBarCodeIMG("Gertec Developer Partner IMG", 240, 240, "QR_CODE"); - gertecPrinter.avancaLinha(100); + gertecPrinter.avancaLinha(40); } catch (Exception e) { e.printStackTrace(); } } + // O M-Sitef não retorna um json como resposta, logo é criado um json com a + // reposta do Sitef. + public String respSitefToJson(Intent data) throws JSONException { + JSONObject json = new JSONObject(); + json.put("CODRESP", data.getStringExtra("CODRESP")); + json.put("COMP_DADOS_CONF", data.getStringExtra("COMP_DADOS_CONF")); + json.put("CODTRANS", data.getStringExtra("CODTRANS")); + json.put("VLTROCO", data.getStringExtra("VLTROCO")); + json.put("REDE_AUT", data.getStringExtra("REDE_AUT")); + json.put("BANDEIRA", data.getStringExtra("BANDEIRA")); + json.put("NSU_SITEF", data.getStringExtra("NSU_SITEF")); + json.put("NSU_HOST", data.getStringExtra("NSU_HOST")); + json.put("COD_AUTORIZACAO", data.getStringExtra("COD_AUTORIZACAO")); + json.put("NUM_PARC", data.getStringExtra("NUM_PARC")); + json.put("TIPO_PARC", data.getStringExtra("TIPO_PARC")); + // Quando passa esta informação para o flutter os break lines são perdidos logo + // é necessario para outro dado para representar no caso %% + json.put("VIA_ESTABELECIMENTO", data.getStringExtra("VIA_ESTABELECIMENTO")); + json.put("VIA_CLIENTE", data.getStringExtra("VIA_CLIENTE")); + return json.toString(); + } + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + // Pega os resultados obtidos dos intent e envia para o flutter + // ("_result.success") + if (requestCode == 109) { if (resultCode == RESULT_OK && data != null) { _result.success(data.getStringExtra("codigoNFCID")); @@ -306,15 +468,28 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten } else { _result.notImplemented(); } + } else if (requestCode == 4713) { + if (resultCode == RESULT_OK && data != null) { + _result.success(data.getStringExtra("jsonResp")); + } else { + _result.notImplemented(); + } + } else if (requestCode == 4321) { + if (resultCode == RESULT_OK || resultCode == RESULT_CANCELED && data != null) { + try { + _result.success(respSitefToJson(data)); + } catch (JSONException e) { + e.printStackTrace(); + } + } else { + _result.notImplemented(); + } } else { IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if (intentResult != null) { - // if qrcode has nothing in it if (intentResult.getContents() == null) { - // Toast.makeText(this, "Result Not Found", Toast.LENGTH_LONG).show(); resultado_Leitor = (this.tipo + ": Não foi possível ler o código.\n"); } else { - // if qr contains data try { resultado_Leitor = this.tipo + ": " + intentResult.getContents() + "\n"; } catch (Exception e) { diff --git a/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/SatLib.java b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/SatLib.java new file mode 100644 index 0000000..a90944c --- /dev/null +++ b/GPOS 700/android/app/src/main/java/com/example/flutter_gertec/SatLib.java @@ -0,0 +1,337 @@ +package com.example.flutter_gertec; + +import android.content.Context; +import android.util.Base64; + +import com.phi.gertec.sat.satger.SatGerLib; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +public class SatLib { + public static SatGerLib serialComms; + + private String funcao; + Context context; + private File arquivoXml = new File("mnt/sdcard/Gertec/teste_fim_a_fim.xml"); + private File arquivoXmlVendas = new File("mnt/sdcard/Gertec/EnviarDadosVenda.xml"); + private File arquivoXmlCancelamento = new File("mnt/sdcard/Gertec/CancelarVenda.xml"); + + public SatLib(Context context) { + this.context = context; + serialComms = new SatGerLib(context, dataReceivedListener); // Inicializando + } + + public String enviarConfRede(int random, List dadosXml, String codigoAtivacao) throws IOException { + String packageName = "com.example.flutter_gertec"; + String caminhoXML = "data/data/" + packageName + "/configRede.xml"; + File file = new File(caminhoXML); + // Se o arquivo não existe, então cria + if (!file.exists()) { + file.createNewFile(); + } + // Começa a escrever no arquivo + FileWriter fw = new FileWriter(file.getAbsoluteFile()); + BufferedWriter bw = new BufferedWriter(fw); + bw.write(""); + bw.newLine(); + bw.write(""); + bw.newLine(); + bw.write("ETHE"); + bw.newLine(); + bw.write(dadosXml.get(0)); + bw.newLine(); + + if (!dadosXml.get(1).equals("")) { + bw.write(dadosXml.get(1)); + bw.newLine(); + } + if (!dadosXml.get(2).equals("")) { + bw.write(dadosXml.get(2)); + bw.newLine(); + } + if (!dadosXml.get(3).equals("")) { + bw.write(dadosXml.get(3)); + bw.newLine(); + } + if (!dadosXml.get(4).equals("")) { + bw.write(dadosXml.get(4)); + bw.newLine(); + } + if (!dadosXml.get(5).equals("")) { + bw.write(dadosXml.get(5)); + bw.newLine(); + } + + bw.write(dadosXml.get(6)); + bw.newLine(); + + if (!dadosXml.get(7).equals("")) { + bw.write(dadosXml.get(7)); + bw.newLine(); + } + if (!dadosXml.get(8).equals("")) { + bw.write(dadosXml.get(8)); + bw.newLine(); + } + if (!dadosXml.get(9).equals("")) { + bw.write(dadosXml.get(9)); + bw.newLine(); + } + if (!dadosXml.get(10).equals("")) { + bw.write(dadosXml.get(10)); + bw.newLine(); + } + + bw.write(""); + bw.flush(); + bw.close(); + // Chama o método para enviar a configuração de rede + try { + funcao = "EnviarConfRede"; + String configData; + // Abre o arquivo XML + BufferedReader br = new BufferedReader(new FileReader(caminhoXML)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + // Lê linha por linha + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + configData = sb.toString(); + return retornoDaFuncaoSat(serialComms.ConfigurarInterfaceDeRede(random, codigoAtivacao, configData)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String versao() { + try { + funcao = "Versao"; + return retornoDaFuncaoSat(serialComms.VersaoDllGerSAT()); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String atualizarSoftware(String codAtivacao, int random) { + try { + funcao = "AtualizarSoftware"; + return retornoDaFuncaoSat(serialComms.AtualizarSAT(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String extrairLog(String codAtivacao, int random) { + try { + funcao = "ExtrairLog"; + return retornoDaFuncaoSat(serialComms.ExtrairLogs(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String desbloquearSat(String codAtivacao, int random) { + try { + funcao = "DesbloquearSat"; + return retornoDaFuncaoSat(serialComms.DesbloquearSAT(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String bloquearSat(String codAtivacao, int random) { + try { + funcao = "BloquearSat"; + return retornoDaFuncaoSat(serialComms.BloquearSAT(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String trocarCodAtivacao(String codAtual, int opt, String codNovo, int random) { + try { + // Sempre o codigo de confirmação vai ser igual ao novo, pois já foi validado no + // flutter + funcao = "TrocarCodAtivacao"; + return retornoDaFuncaoSat(serialComms.TrocarCodigoDeAtivacao(random, codAtual, opt, codNovo, codNovo)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String consultarNumeroSessao(String codAtivacao, int cNumeroDeSessao, int random) { + try { + funcao = "ConsultarNumeroSessao"; + return retornoDaFuncaoSat(serialComms.ConsultarNumeroSessao(random, codAtivacao, cNumeroDeSessao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String cancelarUltimaVenda(String codAtivacao, String xmlBase64, String chave, int random) { + try { + funcao = "CancelarUltimaVenda"; + String vendaData; + + // Cria um arquivo XML + File file = new File(this.context.getFilesDir().getPath() + "/xmlCancelamento.xml"); + + // Escreve no XML os dados que foram enviados do XML decodificado (Flutter) + FileOutputStream fos = new FileOutputStream(file); + fos.write(Base64.decode(xmlBase64, Base64.NO_WRAP)); + fos.close(); + + BufferedReader br = new BufferedReader(new FileReader(file)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + vendaData = sb.toString(); + vendaData = vendaData.replaceAll("trocarCfe", chave); + System.out.println(vendaData); + return retornoDaFuncaoSat(serialComms.CancelarUltimaVenda(random, codAtivacao, chave, vendaData)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String enviarTesteVendas(String codAtivacao, String xmlBase64, int random) { + try { + funcao = "EnviarTesteVendas"; + String vendaData; + + // Cria um arquivo XML + File file = new File(this.context.getFilesDir().getPath() + "/xmlVenda.xml"); + + // Escreve no XML os dados que foram enviados do XML decodificado (Flutter) + FileOutputStream fos = new FileOutputStream(file); + fos.write(Base64.decode(xmlBase64, Base64.NO_WRAP)); + fos.close(); + + // Carrega o XML + BufferedReader br = new BufferedReader(new FileReader(file)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + vendaData = sb.toString(); + return retornoDaFuncaoSat(serialComms.EnviarDadosVenda(random, codAtivacao, vendaData)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String enviarTesteFim(String codAtivacao, String xmlBase64, int random) { + try { + funcao = "EnviarTesteFim"; + String vendaData; + + // Cria um arquivo XML + File file = new File(this.context.getFilesDir().getPath() + "/xmlVenda.xml"); + + // Escreve no XML os dados que foram enviados do XML decodificado (Flutter) + FileOutputStream fos = new FileOutputStream(file); + fos.write(Base64.decode(xmlBase64, Base64.NO_WRAP)); + fos.close(); + + // Carrega o XML + BufferedReader br = new BufferedReader(new FileReader(file)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + vendaData = sb.toString(); + return retornoDaFuncaoSat(serialComms.TesteFimAFim(random, codAtivacao, vendaData)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String consultarStatusOperacional(int random, String codAtivacao) { + try { + funcao = "ConsultarStatusOperacional"; + return retornoDaFuncaoSat(serialComms.ConsultarStatusOperacional(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String consultarSat(int random) { + try { + funcao = "ConsultarSat"; + return retornoDaFuncaoSat(serialComms.ConsultarSAT(random)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String associarSat(String cnpj, String cnpjSW, String codAtivacao, String assinatura, int random) { + try { + funcao = "AssociarSAT"; + return retornoDaFuncaoSat( + serialComms.AssociarAssinatura(random, codAtivacao, cnpjSW + "" + cnpj, assinatura)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String ativarSat(String codAtivacao, String cnpj, int random) { + try { + funcao = "AtivarSAT"; + return retornoDaFuncaoSat(serialComms.AtivarSAT(random, 1, codAtivacao, cnpj, 35)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String retornoDaFuncaoSat(String s) { + // TODO Fazer algo com a String que foi retornada do sat. + try { + return s; // Retorna a mensagem com os pipes, para ser tratado no Flutter + } catch (Exception e) { + return e.getMessage(); + } + } + + SatGerLib.OnDataReceived dataReceivedListener = new SatGerLib.OnDataReceived() { + public void onError(Exception e) { + System.out.println(e.getMessage()); + } + + @Override + public void onReceivedDataUpdate(String s) { + // TODO Fazer algo com a String que foi retornada do sat. + try { + // Trata o retorno da função + String[] respostaSplited; + respostaSplited = s.split("\\|"); + byte ptext[] = respostaSplited[2].getBytes(); + String value = new String(ptext, "UTF-8"); + } catch (Exception e) { + } + } + }; +} diff --git a/GPOS 700/android/app/src/main/res/layout/activity_leitor_n_f_c.xml b/GPOS 700/android/app/src/main/res/layout/activity_leitor_n_f_c.xml index d3753a6..62e57c4 100644 --- a/GPOS 700/android/app/src/main/res/layout/activity_leitor_n_f_c.xml +++ b/GPOS 700/android/app/src/main/res/layout/activity_leitor_n_f_c.xml @@ -2,7 +2,6 @@ - - - - diff --git a/GPOS 700/android/app/src/main/res/mipmap-xhdpi/gertec_one.png b/GPOS 700/android/app/src/main/res/mipmap-xhdpi/gertec_one.png new file mode 100644 index 0000000..db8a639 Binary files /dev/null and b/GPOS 700/android/app/src/main/res/mipmap-xhdpi/gertec_one.png differ diff --git a/GPOS 700/android/app/src/main/res/values/strings.xml b/GPOS 700/android/app/src/main/res/values/strings.xml index 85b9ddc..0618828 100644 --- a/GPOS 700/android/app/src/main/res/values/strings.xml +++ b/GPOS 700/android/app/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ - Voce Esta na Tela de Ler + Gertec Flutter \ No newline at end of file diff --git a/GPOS 700/android/build.gradle b/GPOS 700/android/build.gradle index e61f16f..0cc686c 100644 --- a/GPOS 700/android/build.gradle +++ b/GPOS 700/android/build.gradle @@ -27,4 +27,4 @@ subprojects { task clean(type: Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/GPOS 700/android/device-2020-03-20-192953.png b/GPOS 700/android/device-2020-03-20-192953.png new file mode 100644 index 0000000..7e0c476 Binary files /dev/null and b/GPOS 700/android/device-2020-03-20-192953.png differ diff --git a/GPOS 700/assets/iconSat.png b/GPOS 700/assets/iconSat.png new file mode 100644 index 0000000..2e9dee0 Binary files /dev/null and b/GPOS 700/assets/iconSat.png differ diff --git a/GPOS 700/assets/pos-terminal.png b/GPOS 700/assets/pos-terminal.png new file mode 100644 index 0000000..3e66328 Binary files /dev/null and b/GPOS 700/assets/pos-terminal.png differ diff --git a/GPOS 700/assets/xmlSat/arq_cancelamento.xml b/GPOS 700/assets/xmlSat/arq_cancelamento.xml new file mode 100644 index 0000000..ddd4dac --- /dev/null +++ b/GPOS 700/assets/xmlSat/arq_cancelamento.xml @@ -0,0 +1,13 @@ + + + + + 16716114000172 + SGR-SAT SISTEMA DE GESTAO E RETAGUARDA DO SAT + 001 + + + + + + \ No newline at end of file diff --git a/GPOS 700/assets/xmlSat/arq_venda_008_Simples_Nacional.xml b/GPOS 700/assets/xmlSat/arq_venda_008_Simples_Nacional.xml new file mode 100644 index 0000000..3ba070e --- /dev/null +++ b/GPOS 700/assets/xmlSat/arq_venda_008_Simples_Nacional.xml @@ -0,0 +1,64 @@ + + + + 16716114000172 + SGR-SAT SISTEMA DE GESTAO E RETAGUARDA DO SAT + 123 + + + 03654119000176 + 000052619494 + 123123 + N + + + + + 0020 + Trib ICMS Isento - PIS e COFINS ST aliquota 0.0250 + 60052300 + 5020 + kg + 1.0000 + 30.00 + A + + + + + 2 + 400 + + + + + 02 + 30.00 + 0.0250 + + + + 30.00 + 0.0250 + + + + 02 + 30.00 + 0.0250 + + + + 30.00 + 0.0250 + + + + + + 01 + 30.00 + + + + diff --git a/GPOS 700/lib/config_tef/operacaoRetorno.dart b/GPOS 700/lib/config_tef/operacaoRetorno.dart new file mode 100644 index 0000000..cb85846 --- /dev/null +++ b/GPOS 700/lib/config_tef/operacaoRetorno.dart @@ -0,0 +1,375 @@ +/// Classe de retorno, utilizada para atribuir o resultado do Tef Ger7 para um Json. +class RetornoGer7 { + String _version; + String _status; + String _config; + String _license; + String _terminal; + String _merchant; + String _id; + String _type; + String _product; + String _response; + String _authorization; + String _amount; + String _installments; + String _instmode; + String _stan; + String _rrn; + String _time; + String _print; + String _track2; + String _aid; + String _cardholder; + String _prefname; + String _errcode; + String _errmsg; + String _label; + + Map toJson() { + final Map data = new Map(); + data['version'] = this.getVersion; + data['status'] = this.getStatus; + data['config'] = this.getConfig; + data['license'] = this.getLicens; + data['terminal'] = this.getTerminal; + data['merchant'] = this.getMerchant; + data['id'] = this.getId; + data['type'] = this.getType; + data['product'] = this.getProduct; + data['response'] = this.getResponse; + data['authorizationType'] = this.getAuthorization; + data['amount'] = this.getAmount; + data['installments'] = this.getInstallments; + data['instmode'] = this.getInstmode; + data['stan'] = this.getStan; + data['rrn'] = this.getRrn; + data['time'] = this.getTime; + data['print'] = this.getPrint; + data['track2'] = this.getTrack2; + data['aid'] = this.getAid; + data['cardholder'] = this.getCardholder; + data['prefname'] = this.getPrefname; + data['errcode'] = this.getErrcode; + data['errmsg'] = this.getErrmsg; + data['label'] = this.getLabel; + return data; + } + + RetornoGer7.fromJson(Map json) { + _version = json['version']; + _status = json['status']; + _config = json['config']; + _license = json['license']; + _terminal = json['terminal']; + _merchant = json['merchant']; + _id = json['id']; + _type = json['type']; + _product = json['product']; + _response = json['response']; + _authorization = json['authorizationType']; + _amount = json['amount']; + _installments = json['installments']; + _instmode = json['instmode']; + _stan = json['stan']; + _rrn = json['rrn']; + _time = json['time']; + _print = json['print']; + _track2 = json['track2']; + _aid = json['aid']; + _cardholder = json['cardholder']; + _prefname = json['prefname']; + _errcode = json['errcode']; + _errmsg = json['errmsg']; + _label = json['label']; + } + + String get getVersion { + return _version ?? ""; + } + + set setVersion(String version) { + this._version = version; + } + + String get getStatus { + return _status ?? ""; + } + + set setStatus(String status) { + this._status = status; + } + + String get getConfig { + return _config ?? ""; + } + + set setConfig(String config) { + this._config = config; + } + + String get getLicens { + return _license ?? ""; + } + + set setLicense(String license) { + this._license = license; + } + + String get getTerminal { + return _terminal ?? ""; + } + + set setTerminal(String terminal) { + this._terminal = terminal; + } + + String get getMerchant { + return _merchant ?? ""; + } + + set setMerchant(String merchant) { + this._merchant = merchant; + } + + String get getId { + return _id ?? ""; + } + + set setId(String id) { + this._id = id; + } + + String get getType { + return _type ?? ""; + } + + set setType(String type) { + this._type = type; + } + + String get getProduct { + return _product ?? ""; + } + + set setProduct(String product) { + this._product = product; + } + + String get getResponse { + return _response ?? ""; + } + + set setResponse(String response) { + this._response = response; + } + + String get getAuthorization { + return _authorization ?? ""; + } + + set setAuthorization(String authorization) { + this._authorization = authorization; + } + + String get getAmount { + return _amount ?? ""; + } + + set setAmount(String amount) { + this._amount = amount; + } + + String get getInstallments { + return _installments ?? ""; + } + + set setInstallments(String installments) { + this._installments = installments; + } + + String get getInstmode { + return _instmode ?? ""; + } + + set setInstmode(String instmode) { + this._instmode = instmode; + } + + String get getStan { + return _stan ?? ""; + } + + set setStan(String stan) { + this._stan = stan; + } + + String get getRrn { + return _rrn ?? ""; + } + + set setRrn(String rrn) { + this._rrn = rrn; + } + + String get getTime { + return _time ?? ""; + } + + set setTime(String time) { + this._time = time; + } + + String get getPrint { + return _print ?? ""; + } + + set setPrint(String print) { + this._print = print; + } + + String get getTrack2 { + return _track2 ?? ""; + } + + set setTrack2(String track2) { + this._track2 = track2; + } + + String get getAid { + return _aid ?? ""; + } + + set setAid(String aid) { + this._aid = aid; + } + + String get getCardholder { + return _cardholder ?? ""; + } + + set setCardholder(String cardholder) { + this._cardholder = cardholder; + } + + String get getPrefname { + return _prefname ?? ""; + } + + set setPrefname(String prefname) { + this._prefname = prefname; + } + + String get getErrcode { + return _errcode ?? ""; + } + + set setErrcode(String errcode) { + this._errcode = errcode; + } + + String get getErrmsg { + return _errmsg ?? ""; + } + + set setErrmsg(String errmsg) { + this._errmsg = errmsg; + } + + String get getLabel { + return _label ?? ""; + } + + set setLabel(String label) { + this._label = label; + } +} + +/// Classe de retorno, utilizada para atribuir o resultado do M-Sitef para um Json. +class RetornoMsiTef { + String _cODRESP; + String _cOMPDADOSCONF; + String _cODTRANS; + String _vLTROCO; + String _rEDEAUT; + String _bANDEIRA; + String _nSUSITEF; + String _nSUHOST; + String _cODAUTORIZACAO; + String _tipoPARC; + String _numPARC; + String _viaESTABELECIMENTO; + String _viaCLIENTE; + RetornoMsiTef.fromJson(Map json) { + _cODRESP = json['CODRESP']; + _cOMPDADOSCONF = json['COMP_DADOS_CONF']; + _cODTRANS = json['CODTRANS']; + _vLTROCO = json['VLTROCO']; + _rEDEAUT = json['REDE_AUT']; + _bANDEIRA = json['BANDEIRA']; + _nSUSITEF = json['NSU_SITEF']; + _nSUHOST = json['NSU_HOST']; + _cODAUTORIZACAO = json['COD_AUTORIZACAO']; + _tipoPARC = json['TIPO_PARC']; + _numPARC = json['NUM_PARC']; + _viaCLIENTE = json['VIA_CLIENTE']; + _viaESTABELECIMENTO = json['VIA_ESTABELECIMENTO']; + } + + Map toJson() { + final Map data = new Map(); + data['CODRESP'] = this._cODRESP; + data['COMP_DADOS_CONF'] = this._cOMPDADOSCONF; + data['CODTRANS'] = this._cODTRANS; + data['VLTROCO'] = this._vLTROCO; + data['REDE_AUT'] = this._rEDEAUT; + data['BANDEIRA'] = this._bANDEIRA; + data['NSU_SITEF'] = this._nSUSITEF; + data['NSU_HOST'] = this._nSUHOST; + data['COD_AUTORIZACAO'] = this._cODAUTORIZACAO; + data['TIPO_PARC'] = this._tipoPARC; + data['NUM_PARC'] = this._numPARC; + data['VIA_ESTABELECIMENTO'] = this._viaESTABELECIMENTO; + data['VIA_CLIENTE'] = this._viaCLIENTE; + return data; + } + + get getNSUHOST => _nSUHOST; + String get getSitefTipoParcela => _tipoPARC; + get getNSUSitef => _nSUSITEF; + get getCodTrans => _cODTRANS; + get getNameTransCod { + String retorno = "Valor invalido"; + switch (int.parse(_tipoPARC)) { + case 0: + retorno = "A vista"; + break; + case 1: + retorno = "Pré-Datado"; + break; + case 2: + retorno = "Parcelado Loja"; + break; + case 3: + retorno = "Parcelado Adm"; + break; + } + return retorno; + } + + get getvlTroco => _vLTROCO; + get getParcelas { + if (_numPARC != null) { + return _numPARC; + } + return ""; + } + + get getCodAutorizacao => _cODAUTORIZACAO ?? ""; + String get textoImpressoEstabelecimento => _viaESTABELECIMENTO ?? ""; + String get textoImpressoCliente => _viaCLIENTE ?? ""; + get getCompDadosConf => _cOMPDADOSCONF ?? ""; + get getCodResp => _cODRESP ?? ""; + get getRedeAut => _rEDEAUT ?? ""; + get getBandeira => _bANDEIRA ?? ""; +} diff --git a/GPOS 700/lib/config_tef/venda.dart b/GPOS 700/lib/config_tef/venda.dart new file mode 100644 index 0000000..fc0c510 --- /dev/null +++ b/GPOS 700/lib/config_tef/venda.dart @@ -0,0 +1,88 @@ +/// Classe utilizada para enviar os dados da venda para o Tef Ger7. +class Venda { + String _type; + String _id; + String _amount; + String _installments; + String _instmode; + String _product; + String _receipt; + String _apiversion; + + Map toJson() { + Map map = new Map(); + map["amount"] = getAmount; + map["apiversion"] = getApiversion; + map["id"] = getId; + map["installments"] = getInstallments; + map["instmode"] = getInstmode; + map["product"] = getProduct; + map["receipt"] = getReceipt; + map["type"] = getType; + return map; + } + + String get getType { + return _type; + } + + set setType(String type) { + this._type = type; + } + + String get getId { + return _id; + } + + set setId(String id) { + this._id = id; + } + + String get getAmount { + return _amount; + } + + set setAmount(String amount) { + this._amount = amount; + } + + String get getInstallments { + return _installments; + } + + set setInstallments(String installments) { + this._installments = installments; + } + + String get getInstmode { + return _instmode; + } + + set setInstmode(String instmode) { + this._instmode = instmode; + } + + String get getProduct { + return _product; + } + + set setProduct(String product) { + this._product = product; + } + + String get getReceipt { + return _receipt; + } + + set setReceipt(String receipt) { + this._receipt = receipt; + } + + String get getApiversion { + return _apiversion; + } + + set setApiversion(String apiversion) { + this._apiversion = apiversion; + } +} diff --git a/GPOS 700/lib/main.dart b/GPOS 700/lib/main.dart index 850969a..9a406c8 100644 --- a/GPOS 700/lib/main.dart +++ b/GPOS 700/lib/main.dart @@ -1,10 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_gertec/CodigoDeBarraV1.dart'; -import 'package:flutter_gertec/imprimir.dart'; -import 'package:flutter_gertec/lerCartaoID.dart'; +import 'package:flutter_gertec/pages/CodigoDeBarraV1.dart'; +import 'package:flutter_gertec/pages/imprimir.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'lerCartaoGEDI.dart'; +import 'pages/lerCartaoGEDI.dart'; +import 'pages/lerCartaoID.dart'; +import 'pages/menus/sat.dart'; +import 'pages/menus/tefs.dart'; void main() => runApp(MyApp()); @@ -13,11 +15,11 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, - title: 'Flutter Demo', + title: 'GertecOne Flutter', theme: ThemeData( primarySwatch: Colors.blue, ), - home: MyHomePage(title: 'Flutter Demo Home Page'), + home: MyHomePage(title: 'GertecOne Flutter'), ); } } @@ -42,12 +44,14 @@ class _MyHomePageState extends State { } var newTaskCtrl = TextEditingController(); - var Lista_nome_funcoes = [ + var listaNomeFuncoes = [ {"name": "Código de Barras", "img": "assets/barcode.png"}, {"name": "Código de Barras V2", "img": "assets/qr_code.png"}, {"name": "Impressão", "img": "assets/print.png"}, {"name": "NFC GEDI", "img": "assets/nfc.png"}, {"name": "NFC Id", "img": "assets/nfc1.png"}, + {"name": "TEF", "img": "assets/pos-terminal.png"}, + {"name": "SAT", "img": "assets/iconSat.png"}, ]; void trocarTela(int id) { switch (id) { @@ -79,6 +83,18 @@ class _MyHomePageState extends State { MaterialPageRoute(builder: (context) => PageLeituraCartaoID()), ); break; + case 5: + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageTef()), + ); + break; + case 6: + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageSat()), + ); + break; } } @@ -102,11 +118,8 @@ class _MyHomePageState extends State { children: [ new Image.asset('assets/gertec.png'), Text( - "Flutter Project", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: ScreenUtil.instance.setSp(30.0), - color: Colors.black87), + "Flutter Project v1.0.0", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenUtil.instance.setSp(30.0), color: Colors.black87), ), ], ), @@ -114,7 +127,7 @@ class _MyHomePageState extends State { Expanded( child: new ListView.builder( shrinkWrap: true, - itemCount: Lista_nome_funcoes.length, + itemCount: listaNomeFuncoes.length, itemExtent: 80, scrollDirection: Axis.vertical, itemBuilder: (BuildContext context, int index) { @@ -125,18 +138,15 @@ class _MyHomePageState extends State { child: ListTile( dense: true, leading: Image( - image: AssetImage(Lista_nome_funcoes[index]["img"]), + image: AssetImage(listaNomeFuncoes[index]["img"]), ), onTap: () { trocarTela(index); }, title: Center( child: Text( - Lista_nome_funcoes[index]["name"], - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: ScreenUtil.instance.setSp(20.0), - color: Colors.black54), + listaNomeFuncoes[index]["name"], + style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenUtil.instance.setSp(20.0), color: Colors.black54), ), ), ), diff --git a/GPOS 700/lib/pages/CodigoDeBarraV1.dart b/GPOS 700/lib/pages/CodigoDeBarraV1.dart new file mode 100644 index 0000000..bf99a70 --- /dev/null +++ b/GPOS 700/lib/pages/CodigoDeBarraV1.dart @@ -0,0 +1,138 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class PageCodigoDeBarraV1 extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'GertecOne Flutter', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: CodigoDeBarrav1(title: 'Ler Código de Barras'), + ); + } +} + +class CodigoDeBarrav1 extends StatefulWidget { + CodigoDeBarrav1({Key key, this.title}) : super(key: key); + final String title; + _CodigoDeBarrav1 createState() => _CodigoDeBarrav1(); +} + +class _CodigoDeBarrav1 extends State { + static const platform = const MethodChannel('samples.flutter.dev/gedi'); + final myController = TextEditingController(); + List resultadosBardCod = new List(); + + Future _leitorCodigoDeBarra(String tipoLeitura) async { + try { + String teste = await platform.invokeMethod('leitorCodigov1', {"tipoLeitura": tipoLeitura}); + setState(() { + resultadosBardCod.add(teste); + }); + } on PlatformException catch (e) { + print(e.message); + } + } + + Widget build(BuildContext context) { + double defaultScreenWidth = 400.0; + double defaultScreenHeight = 810.0; + ScreenUtil.instance = ScreenUtil( + width: defaultScreenWidth, + height: defaultScreenHeight, + allowFontScaling: true, + )..init(context); + + return new Scaffold( + body: Container( + padding: EdgeInsets.only( + top: ScreenUtil.instance.setWidth(40.0), + ), + child: Column( + children: [ + Text( + "Ler Código de Barras", + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 30), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox( + width: ScreenUtil.instance.setWidth(100), + child: RaisedButton( + child: Text( + 'EAN 8', + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), + ), + onPressed: () { + _leitorCodigoDeBarra("EAN_8"); + }, + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(100), + child: RaisedButton( + child: Text( + 'EAN 13', + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), + ), + onPressed: () { + _leitorCodigoDeBarra("EAN_13"); + }, + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(100), // specific value + child: RaisedButton( + child: Text( + 'EAN 14', + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), + ), + onPressed: () { + _leitorCodigoDeBarra("EAN_14"); + }, + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(100), // specific value + child: RaisedButton( + child: Text( + 'QR CODE', + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), + ), + onPressed: () { + _leitorCodigoDeBarra("QR_CODE"); + }, + ), + ), + ], + ), + Expanded( + child: new ListView.builder( + shrinkWrap: true, + itemCount: resultadosBardCod.length, + itemExtent: 50, + scrollDirection: Axis.vertical, + itemBuilder: (BuildContext context, int index) { + return Container( + child: ListTile( + dense: true, + title: Text( + resultadosBardCod[index], + style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenUtil.instance.setSp(12.0), color: Colors.black54), + ), + ), + ); + }, + ), + ) + ], + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/imprimir.dart b/GPOS 700/lib/pages/imprimir.dart new file mode 100644 index 0000000..93bcabf --- /dev/null +++ b/GPOS 700/lib/pages/imprimir.dart @@ -0,0 +1,501 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class PageImprimir extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'GertecOne Flutter', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Imprimir(title: 'Impressão'), + ); + } +} + +class Imprimir extends StatefulWidget { + Imprimir({Key key, this.title}) : super(key: key); + final String title; + _Imprimir createState() => _Imprimir(); +} + +class _Imprimir extends State { + static const platform = const MethodChannel('samples.flutter.dev/gedi'); + final myController = TextEditingController(); + int dropdownValueSize = 20; + int dropdownBarHeight = 280; + int dropdownBarWidth = 280; + String dropdownFont = "DEFAULT"; + String dropdownBarType = "QR_CODE"; + String alinhar = "CENTER"; + String valorSelecionado = "CENTER"; + List listSelecionado = [false, false, false]; + void radioButtonChanges(String value) { + setState( + () { + valorSelecionado = value; + switch (value) { + case 'LEFT': + alinhar = value; + break; + case 'CENTER': + alinhar = value; + break; + case 'RIGHT': + alinhar = value; + break; + default: + alinhar = null; + } + print(alinhar); //Debug the choice in console + }, + ); + } + + void erroImpresao() { + showDialog( + context: context, + builder: (BuildContext c) { + return AlertDialog( + title: Text("Escreva uma mensagem para ser impressa !"), + ); + }, + ); + } + + // Função responsavel por finalizar impressao - ImpressoraOutput(); + void finalizarImpressao() async { + await platform.invokeMethod('fimimpressao'); + } + + void impressaoDeTexto({String texto, int fontSize, String alinhar, String fontFamily, List selectedOptions}) async { + texto = texto ?? ""; // Caso seja null + if (texto.isEmpty) { + erroImpresao(); + } else { + try { + await platform.invokeMethod( + 'imprimir', + { + "tipoImpressao": "Texto", + "mensagem": texto, + "alinhar": alinhar ?? "CENTER", + "size": fontSize ?? 10, + "font": fontFamily ?? "DEFAULT", + "options": selectedOptions ?? [false, false, false] + }, + ); + } on PlatformException catch (e) { + print(e.message); + } + } + } + + Future _impressaoTodasFuncoes() async { + try { + await platform.invokeMethod( + 'imprimir', + { + "tipoImpressao": "TodasFuncoes", + }, + ); + } on PlatformException catch (e) { + print(e.message); + } + } + + Future _impressaoDeImagem() async { + try { + await platform.invokeMethod('imprimir', { + "tipoImpressao": "Imagem", + }); + } on PlatformException catch (e) { + print(e.message); + } + } + + Future _impressaoDeCodigoDeBarra({String texto, int height, int width, String barCode}) async { + texto = texto ?? ""; // Caso seja null + if (texto.isNotEmpty) { + try { + await platform.invokeMethod('imprimir', { + "tipoImpressao": "CodigoDeBarra", + "height": height ?? 200, + "width": width ?? 200, + "barCode": barCode ?? "QR_CODE", + "mensagem": texto + }); + } on PlatformException catch (e) { + print(e.message); + } + } else { + erroImpresao(); + } + } + + Future checarImpressora() async { + try { + bool impressora = await platform.invokeMethod('checarImpressora'); + if (impressora == true) + return "Ok"; + else + return "Erro"; + } on PlatformException catch (e) { + print(e.message); + } + return "Erro"; + } + + Widget build(BuildContext context) { + double defaultScreenWidth = 400.0; + double defaultScreenHeight = 810.0; + ScreenUtil.instance = ScreenUtil( + width: defaultScreenWidth, + height: defaultScreenHeight, + allowFontScaling: true, + )..init(context); + + return new Scaffold( + body: Center( + child: Container( + padding: EdgeInsets.only( + top: 40, + ), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + child: Column( + children: [ + Center( + child: FittedBox( + fit: BoxFit.fitWidth, + child: Text( + "Funções Impressão G700/G800", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(25), fontWeight: FontWeight.bold), + ), + ), + ), + SizedBox( + width: 300, + child: RaisedButton( + child: Text("STATUS IMPRESSORA"), + onPressed: () { + checarImpressora().then((value) { + setState(() { + showDialog( + context: context, + builder: (BuildContext c) { + return AlertDialog( + title: Text("Status Impressora"), + content: Text("Impressora: " + value.toString()), + ); + }, + ); + }); + }); + }, + ), + ), + TextFormField( + autofocus: false, + decoration: const InputDecoration( + hintText: 'Escreva a sua mensagem', + ), + controller: myController, + ), + Center( + child: FittedBox( + fit: BoxFit.fitWidth, + child: Text( + "Configuração de Impressão", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(25), fontWeight: FontWeight.bold), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Radio(value: 'LEFT', groupValue: valorSelecionado, onChanged: radioButtonChanges), + AutoSizeText( + 'Esquerda', + style: TextStyle(fontSize: 15), + ), + Radio(value: 'CENTER', groupValue: valorSelecionado, onChanged: radioButtonChanges), + AutoSizeText( + 'Centralizado', + style: TextStyle(fontSize: 15), + ), + Radio(value: 'RIGHT', groupValue: valorSelecionado, onChanged: radioButtonChanges), + AutoSizeText( + 'Direita', + style: TextStyle(fontSize: 15), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox( + width: ScreenUtil.instance.setWidth(110), + child: RaisedButton( + color: listSelecionado[0] ? Colors.blue : Colors.grey, + onPressed: () { + setState(() { + listSelecionado[0] = !listSelecionado[0]; + }); + }, + child: Text( + "NEGRITO", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + ), + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(110), + child: RaisedButton( + color: listSelecionado[1] ? Colors.blue : Colors.grey, + onPressed: () { + setState(() { + listSelecionado[1] = !listSelecionado[1]; + }); + }, + disabledTextColor: Colors.black87, + child: Text( + "ITÁLICO", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + ), + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(110), + child: RaisedButton( + color: listSelecionado[2] ? Colors.blue : Colors.grey, + onPressed: () { + setState(() { + listSelecionado[2] = !listSelecionado[2]; + }); + }, + disabledTextColor: Colors.black87, + child: Text( + "SUBLINHADO", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + ), + ), + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Font: ", + style: TextStyle(fontSize: 20), + ), + DropdownButton( + value: dropdownFont, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (String newValue) { + setState(() { + dropdownFont = newValue; + }); + }, + items: [ + 'DEFAULT', + 'MONOSPACE', + 'SANS SERIF', + 'SERIF', + 'VECTRA.otf', + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + Text( + "Size: ", + style: TextStyle(color: Colors.black, fontSize: 20), + ), + DropdownButton( + value: dropdownValueSize, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (int newValue) { + setState(() { + dropdownValueSize = newValue; + }); + }, + items: [20, 30, 40, 50, 70, 80, 90, 100].map>((int value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox( + width: 150, + child: RaisedButton( + child: Text( + 'IMPRIMIR TEXTO', + style: TextStyle(fontSize: 12), + ), + onPressed: () { + // Não precisa passar todos os parâmetros - Sera dado o valor DEFAULT + impressaoDeTexto( + texto: myController.text, + fontSize: dropdownValueSize, + alinhar: alinhar, + fontFamily: dropdownFont, + selectedOptions: listSelecionado, + ); + finalizarImpressao(); // Limpa buffer de impressão + }, + ), + ), + SizedBox( + width: 150, + child: RaisedButton( + child: Text( + 'IMPRIMIR IMAGEM', + style: TextStyle(fontSize: 12), + ), + onPressed: () { + _impressaoDeImagem(); + finalizarImpressao(); // Limpa buffer de impressão + }, + ), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + Text("Bar Code Height"), + DropdownButton( + value: dropdownBarHeight, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (int newValue) { + setState(() { + dropdownBarHeight = newValue; + }); + }, + items: [10, 40, 80, 120, 160, 200, 280, 320].map>((int value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + Column( + children: [ + Text("Bar Code Width"), + DropdownButton( + value: dropdownBarWidth, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (int newValue) { + setState(() { + dropdownBarWidth = newValue; + }); + }, + items: [10, 40, 80, 120, 160, 200, 280, 320].map>((int value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + Column( + children: [ + Text("Bar Codes"), + DropdownButton( + value: dropdownBarType, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (String newValue) { + setState(() { + dropdownBarType = newValue; + }); + }, + items: [ + 'QR_CODE', + 'CODE_128', + 'EAN_8', + 'EAN_13', + 'PDF_417', + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + ], + ), + SizedBox( + width: 300, + child: RaisedButton( + child: Text( + 'IMPRIMIR BARCODE', + style: TextStyle(fontSize: 15), + ), + onPressed: () { + // Não precisa passar todos os parâmetros - Sera dado o valor DEFAULT + _impressaoDeCodigoDeBarra( + texto: myController.value.text.toString(), + height: dropdownBarHeight, + width: dropdownBarWidth, + barCode: dropdownBarType, + ); + finalizarImpressao(); // Limpa buffer de impressão + }, + ), + ), + SizedBox( + width: 300, + child: RaisedButton( + child: Text( + 'IMPRIMIR TODAS FUNÇÕES', + style: TextStyle(fontSize: 15), + ), + onPressed: () { + _impressaoTodasFuncoes(); + finalizarImpressao(); // Limpa buffer de impressão + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/lerCartaoGEDI.dart b/GPOS 700/lib/pages/lerCartaoGEDI.dart new file mode 100644 index 0000000..ae862a1 --- /dev/null +++ b/GPOS 700/lib/pages/lerCartaoGEDI.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class PageLeituraCartaoGEDI extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'GertecOne Flutter', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: LeituraCartaoGEDI(title: 'Impressão de Texto'), + ); + } +} + +class LeituraCartaoGEDI extends StatefulWidget { + @override + LeituraCartaoGEDI({Key key, this.title}) : super(key: key); + final String title; + _LeituraCartaoGEDI createState() => _LeituraCartaoGEDI(); +} + +class _LeituraCartaoGEDI extends State { + static const platform = const MethodChannel('samples.flutter.dev/gedi'); + final myController = TextEditingController(); + List resultadosNFCGEDI = new List(); + + Future _lerCartaoGEDI() async { + try { + String id = await platform.invokeMethod('lernfcgedi'); + setState(() { + resultadosNFCGEDI.add("Código do Cartão (GEDI): " + id); + }); + } on PlatformException catch (e) { + print(e.message); + } + } + + Widget build(BuildContext context) { + return new Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.only(top: 60), + child: RaisedButton( + child: Text("Ler Cartão Nfc (GEDI)"), + onPressed: () { + _lerCartaoGEDI(); + }, + )), + Container(padding: EdgeInsets.only(top: 20), child: Text("ID Cartões")), + Expanded( + child: new ListView.builder( + shrinkWrap: true, + itemCount: resultadosNFCGEDI.length, + itemExtent: 50, + scrollDirection: Axis.vertical, + itemBuilder: (BuildContext context, int index) { + return Container( + child: ListTile( + dense: true, + title: Text( + resultadosNFCGEDI[index], + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12.0, color: Colors.black54), + ), + ), + ); + }, + ), + ) + ], + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/lerCartaoID.dart b/GPOS 700/lib/pages/lerCartaoID.dart new file mode 100644 index 0000000..4ab94b3 --- /dev/null +++ b/GPOS 700/lib/pages/lerCartaoID.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class PageLeituraCartaoID extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'GertecOne Flutter', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: LeituraCartaoID(title: 'Impressão de Texto'), + ); + } +} + +class LeituraCartaoID extends StatefulWidget { + @override + LeituraCartaoID({Key key, this.title}) : super(key: key); + final String title; + _LeituraCartaoID createState() => _LeituraCartaoID(); +} + +class _LeituraCartaoID extends State { + static const platform = const MethodChannel('samples.flutter.dev/gedi'); + final myController = TextEditingController(); + List resultadosNFCID = new List(); + + Future _lerCartaoID() async { + try { + String id = await platform.invokeMethod('lernfcid'); + setState(() { + resultadosNFCID.add("Código do Cartão (ID): " + id); + }); + } on PlatformException catch (e) { + print(e.message); + } + } + + Widget build(BuildContext context) { + return new Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.only(top: 60), + child: RaisedButton( + child: Text("Ler Cartão Nfc (Nativo)"), + onPressed: () { + _lerCartaoID(); + }, + )), + Container(padding: EdgeInsets.only(top: 20), child: Text("ID Cartões")), + Expanded( + child: new ListView.builder( + shrinkWrap: true, + itemCount: resultadosNFCID.length, + itemExtent: 50, + scrollDirection: Axis.vertical, + itemBuilder: (BuildContext context, int index) { + return Container( + child: ListTile( + dense: true, + title: Text( + resultadosNFCID[index], + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12.0, color: Colors.black54), + ), + ), + ); + }, + ), + ) + ], + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/menus/sat.dart b/GPOS 700/lib/pages/menus/sat.dart new file mode 100644 index 0000000..1655fe9 --- /dev/null +++ b/GPOS 700/lib/pages/menus/sat.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; +import '../sat_pages/associarSat.dart'; +import '../sat_pages/ativarSat.dart'; +import '../sat_pages/configRede.dart'; +import '../sat_pages/ferramentasSat.dart'; +import '../sat_pages/testeSat.dart'; +import '../sat_pages/alterarCodigo.dart'; + +class PageSat extends StatefulWidget { + @override + _PageSatState createState() => _PageSatState(); +} + +// Tela de Menu Principal do Sat com suas Funções principais +class _PageSatState extends State { + //* Função responsavel por fazer a mudança de telas, recebe como parâmetro um Widget(Deve ser uma screen, caso não, resulta em erro) + void changeScreen(Widget screen) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => screen, + ), + ); + } + + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 30), + Text( + "GERSAT - Aplicativo de Ativação", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20), + ), + SizedBox(height: 30), + // Se deseja ir para tela de ativação + WidgetsGertec.buttonStandard( + "ATIVAÇÃO SAT", + callback: () => changeScreen(PageAtivarSat()), + ), + // Se deseja ir para tela de associar assinatura + WidgetsGertec.buttonStandard( + "ASSOCIAR ASSINATURA", + callback: () => changeScreen(PageAssociarSat()), + ), + // Se deseja ir para tela de teste + WidgetsGertec.buttonStandard( + "TESTE SAT", + callback: () => changeScreen(PageTesteSat()), + ), + // Se deseja ir para tela de configuração de rede + WidgetsGertec.buttonStandard( + "CONFIGURAÇÕES DE REDE", + callback: () => changeScreen(PageConfigSat()), + ), + // Se deseja ir para tela de alteração de código + WidgetsGertec.buttonStandard( + "ALTERAR CÓDIGO DE ATIVAÇÃO", + callback: () => changeScreen(PageCodigoSat()), + ), + // Se deseja ir para tela de ferramentas + WidgetsGertec.buttonStandard( + "OUTRAS FERRAMENTAS", + callback: () => changeScreen(PageFerramentaSat()), + ) + ], + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/menus/tefs.dart b/GPOS 700/lib/pages/menus/tefs.dart new file mode 100644 index 0000000..3c6a0d4 --- /dev/null +++ b/GPOS 700/lib/pages/menus/tefs.dart @@ -0,0 +1,760 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_gertec/config_tef/operacaoRetorno.dart'; +import 'package:flutter_gertec/services/serviceTet.dart'; +import 'package:flutter_masked_text/flutter_masked_text.dart'; + +class PageTef extends StatefulWidget { + @override + _PageTefState createState() => _PageTefState(); +} + +class _PageTefState extends State { + /* + * Pode inicializar a classe do service MsiTef com os valores da venda ao invés de settar. + TefService tefService = new TefService( + valor: "200", quantParcelas: 2, + habilitarImpressao: true, ip: "192.168.0.1", tipoPagamento: "Crédito"); + */ + TefService tefService = new TefService(); + + // Variavel que se comunica com o Canal Java Android + static const platform = const MethodChannel('samples.flutter.dev/gedi'); + + // Função responsavel por finalizar impressao - ImpressoraOutput(); + void finalizarImpressao() async { + await platform.invokeMethod('fimimpressao'); + } + + // Função responsavel por avancar linhas na impressao; + void avancaLinhas(int quantLinhas) async { + await platform.invokeMethod( + 'avancaLinha', + {"quantLinhas": quantLinhas}, + ); + } + + bool validaIp(String ipServer) { + RegExp regExp = new RegExp( + r"^(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))$", + caseSensitive: false, + multiLine: false, + ); + if (regExp.allMatches(ipServer).isEmpty) return false; + return true; + } + + // Caso ocorra um erro no momento de tentar executar ação + dialogo(String msg, String titulo) { + showDialog( + context: context, + child: AlertDialog( + title: Text(titulo), + content: Container( + height: 100, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(msg), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ); + } + + imprimirTexto(String texto, int size) async { + try { + await platform.invokeMethod( + 'imprimir', + { + "tipoImpressao": "Texto", + "mensagem": texto, + "alinhar": "LEFT", + "size": size, + "font": "MONOSPACE", + "options": [true, false, false] // Negrito, Sublinhado e Italico + }, + ); + } on PlatformException catch (e) { + print(e.message); + } + } + + imprimaGer7(String cupomTEF, int size) { + if (cupomTEF.isNotEmpty) { + int curPos = 0; + int lastPos = 0; + while (curPos >= 0) { + curPos = cupomTEF.indexOf("\n", curPos); + if (curPos > 0) { + try { + if (curPos != lastPos) { + imprimirTexto(cupomTEF.substring(lastPos, curPos), size); + } else { + imprimirTexto(" ", size); + } + curPos++; + lastPos = curPos; + } on Exception catch (e) { + print(e); + } + } + } + } + } + + // Função, para realizar impressão da nota, caso o usuario opte + void impressaoNota(String texto, int size) async { + String textoEstabelecimento = ""; + String textoCliente = ""; + // Ger 7 não difere a via do cliente e do escabelecimento, por isto neste momento é buscado o Pattern que difere uma nota da outra, ao encontrar a nota é partida por \n + if (tefSelecionado == "ger7") { + textoEstabelecimento = texto.substring(0, texto.indexOf("\f")); + textoCliente = texto.substring(texto.indexOf("\f"), texto.length); + imprimaGer7(textoEstabelecimento, size); + avancaLinhas(100); + imprimaGer7(textoCliente, size); + } else { + imprimirTexto(texto, size); + } + } // Mascara que pegar o valor do input e transforma em um tipo Money + + final precoVenda = MoneyMaskedTextController(decimalSeparator: ',', thousandSeparator: '.', initialValue: 10); + + final ipServidor = TextEditingController(); //Text edit ip do servidor + + final numParcelas = TextEditingController(text: "1"); //Text edit da quantidade de parcelas + + bool habilitarImpressao = true; //armazena se a impressao vai ser realizada + + String tipoPagamentoSelecionado = "Crédito"; //armazena o tipo de pagamento escolhido + + String tefSelecionado = "msitef"; //armazena a Tef escolhida + String tipoParcelamento = "Adm"; //armazena a Tef escolhida + + // Dialogo de verificação, para saber se o usuario deseja ou não imprimir a nota utilizando a GEDI + void dialogoImpressao(String textoNota, int size) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Realizar Impressão"), + content: Container( + height: 150, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Deseja realizar a impressão pela aplicação ?"), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Não"), + onPressed: () { + Navigator.pop(context); + }, + ), + FlatButton( + child: Text("Sim"), + onPressed: () { + impressaoNota(textoNota, size); + avancaLinhas(150); + finalizarImpressao(); + Navigator.pop(context); + }, + ), + ], + ), + ); + } + + // Altera o valor da opcao de habilitar impressao (true, false) + void alterarValorImpressao(bool newValue) => setState( + () { + habilitarImpressao = newValue; + }, + ); + + // Setta os valores e os envia para o TefService formatar e encaminhar para o Tef selecionado + // Recebe como parâmetros uma String que está relacionada a ação que deseja ser invocada e uma String relacionado a tef utilizada (ger7,msitef) + // As ações possiveis são: "venda, cancelamento, reimpressao, funcoes" (Os valores devem ser escritos exatamente como o demonstrado) + void realizarFuncao(String acao, String tef) { + // Settando os valores necessarios pra venda e chamando a funcao responsel pela venda. + // Retira mascara Money antes de enviar o valor para a função. + String valorFormatado = precoVenda.text; + valorFormatado = valorFormatado.replaceAll('.', ""); + valorFormatado = valorFormatado.replaceAll(',', ""); + tefService.setValorVenda = valorFormatado; + tefService.setTipoParcelamento = this.tipoParcelamento; + tefService.setIpConfig = ipServidor.text.toString(); // Somente é necessario settar o ip caso esteja utilizando o Tef M-sitef + + tefService.setHabilitarImpressao = + habilitarImpressao; //* Caso seja M-sitef, este parâmetro é passado, mas não surge efeito (linhas comentadas no ServiceTef), pois na versão v3.70 está opção foi removida do Sitef ** + + tefService.setQuantParcelas = int.parse(numParcelas.text); + tefService.setTipoPagamento = tipoPagamentoSelecionado; + if (precoVenda.numberValue <= 0) { + dialogo("O valor de venda digitado deve ser maior que 0", "Erro ao executar função"); + } else if (tef == "msitef" && validaIp(ipServidor.text) == false) { + dialogo("Verifique o IP digitado", "Erro ao executar função"); + } else { + tefService.enviarParametrosTef(tipoAcao: acao, tipoTef: tef).then( + (resultadoTef) { + //* Verificando qual o tipo de Tef foi utilizado. Cada Tef possui seu retorno que deve ser associado a uma classe diferente. + if (tef == "ger7") { + RetornoGer7 retornoGer7 = resultadoTef; + // print(retornoGer7.toJson()); - Caso deseje printar o Json de retorno + // Verifica se tem algo pra imprimir + if (retornoGer7.getErrmsg.isEmpty && retornoGer7.getPrint.isNotEmpty) { + dialogoImpressao(retornoGer7.getPrint, 17); + } + if (acao == "funcoes" && retornoGer7.getErrmsg.isNotEmpty) { + dialogoErroGer7(retornoGer7); + } + // Verifica se ocorreu um erro durante venda ou cancelamento + if (acao == "venda" || acao == "cancelamento") { + if (retornoGer7.getErrmsg.isNotEmpty) { + dialogoErroGer7(retornoGer7); + } else { + dialogoTransacaoAprovadaGer7(retornoGer7); + } + } + } else { + RetornoMsiTef retornoMsiTef = resultadoTef; + // print(retornoMsiTef.toJson()); - Caso deseje printar o Json de retorno + // Verifica se tem algo pra imprimir + if (retornoMsiTef.getCodResp == "0") { + String impressao = ""; + if (retornoMsiTef.textoImpressoCliente.isNotEmpty) { + impressao += retornoMsiTef.textoImpressoCliente; + } + if (retornoMsiTef.textoImpressoEstabelecimento.isNotEmpty) { + impressao += "\n\n----------------------------- \n"; + impressao += retornoMsiTef.textoImpressoEstabelecimento; + } + if (impressao != "") { + dialogoImpressao(impressao, 17); + } + } + // Verifica se ocorreu um erro durante venda ou cancelamento + if (acao == "venda" || acao == "cancelamento") { + if (retornoMsiTef.getCodTrans.toString() == "" || retornoMsiTef.getCodTrans == null) { + //Caso ocorra um erro durante as ações, um dialogo de erro é chamado + dialogoErroMsitef(retornoMsiTef); + } else { + dialogoTransacaoAprovadaMsitef(retornoMsiTef); + } + } + } + }, + ); + } + } + + // Dialogo que será exibido caso ocorra algum erro durante a chamada na Ger7 + void dialogoTransacaoAprovadaGer7(RetornoGer7 operacaoRetorno) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Ação executada com sucesso"), + content: Container( + height: MediaQuery.of(context).size.height - 20, + child: ListView( + scrollDirection: Axis.vertical, + children: [ + Text("version: " + operacaoRetorno.getVersion), + Text("status: " + operacaoRetorno.getStatus), + Text("config: " + operacaoRetorno.getConfig), + Text("license: " + operacaoRetorno.getLicens), + Text("terminal: " + operacaoRetorno.getTerminal), + Text("merchant: " + operacaoRetorno.getMerchant), + Text("id: " + operacaoRetorno.getId), + Text("type: " + operacaoRetorno.getType), + Text("product: " + operacaoRetorno.getProduct), + Text("response: " + operacaoRetorno.getResponse), + Text("authorization: " + operacaoRetorno.getAuthorization), + Text("amount: " + operacaoRetorno.getAmount), + Text("installments: " + operacaoRetorno.getInstallments), + Text("instmode: " + operacaoRetorno.getInstmode), + Text("stan: " + operacaoRetorno.getStan), + Text("rrn: " + operacaoRetorno.getRrn), + Text("time: " + operacaoRetorno.getTime), + Text("track2: " + operacaoRetorno.getTrack2), + Text("aid: " + operacaoRetorno.getAid), + Text("cardholder: " + operacaoRetorno.getCardholder), + Text("prefname: " + operacaoRetorno.getPrefname), + Text("errcode: " + operacaoRetorno.getErrcode), + Text("label: " + operacaoRetorno.getLabel), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + // Dialogo que será exibido caso a ação seja realizada com sucesso durante a chamada na Ger7 + void dialogoErroGer7(RetornoGer7 operacaoRetorno) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Ocorreu um erro durante a realização da ação"), + content: Container( + height: 150, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("version: " + operacaoRetorno.getVersion), + Text("errcode: " + operacaoRetorno.getErrcode), + Text("errmsg: " + operacaoRetorno.getErrmsg), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + // Dialogo que será exibido caso a ação seja realizada com sucesso durante a chamada na MsiTef + void dialogoTransacaoAprovadaMsitef(RetornoMsiTef operacaoRetorno) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Ação executada com sucesso"), + content: Container( + height: 250, + child: ListView( + scrollDirection: Axis.vertical, + children: [ + Text("CODRESP: " + operacaoRetorno.getCodResp), + Text("COMP_DADOS_CONF: " + operacaoRetorno.getCompDadosConf), + Text("CODTRANS: " + operacaoRetorno.getCodTrans), + Text("CODTRANS (Name): " + operacaoRetorno.getNameTransCod), + Text("VLTROCO: " + operacaoRetorno.getvlTroco), + Text("REDE_AUT: " + operacaoRetorno.getRedeAut), + Text("BANDEIRA: " + operacaoRetorno.getBandeira), + Text("NSU_SITEF: " + operacaoRetorno.getNSUSitef), + Text("NSU_HOST: " + operacaoRetorno.getNSUHOST), + Text("COD_AUTORIZACAO: " + operacaoRetorno.getCodAutorizacao), + Text("NUM_PARC: " + operacaoRetorno.getParcelas) + ], + )), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + // Dialogo que será exibido caso ocorra algum erro durante a chamada na MsiTef + void dialogoErroMsitef(RetornoMsiTef operacaoRetorno) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Ocorreu um erro durante a realização da ação"), + content: Container( + height: 100, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("CODRESP: " + operacaoRetorno.getCodResp), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + //Marca o valor do tipo de Tef escolhido + void radioButtonChangeTef(String value) { + setState( + () { + tefSelecionado = value; + }, + ); + } + + //Marca o valor do tipo de Parcelamento escolhido + void radioButtonChangeParcelamento(String value) { + setState( + () { + tipoParcelamento = value; + }, + ); + } + + //Marca o valor do tipo de pagamento escolhido + void radioButtonChangePagamento(String value) { + setState( + () { + tipoPagamentoSelecionado = value; + }, + ); + } + + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only(top: 35), + child: Center( + child: Text( + "Exemplo TEF API - Flutter", + style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold, color: Colors.grey[600]), + ), + ), + ), + SizedBox(height: 15), + Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + "Valor em R\$", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 15), + child: SizedBox( + height: 30, + width: 160, + child: TextFormField( + keyboardType: TextInputType.number, + controller: precoVenda, + style: TextStyle(fontSize: 20), + ), + ), + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + style: TextStyle(fontWeight: FontWeight.bold), + children: [ + TextSpan(text: 'IP', style: TextStyle(fontSize: 18, color: Colors.black)), + TextSpan(text: '(somente para o M-Sitef)', style: TextStyle(color: Colors.black)), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(left: 10), + child: SizedBox(height: 30, width: 160, child: textFormFieldIp), + ), + ], + ) + ], + ), + SizedBox(height: 10), + widgetRadios(), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + "Número de Parcelas", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + Center( + child: SizedBox( + height: 30, + width: MediaQuery.of(context).size.width - 40, + child: textFormFieldNumParcelas, + ), + ), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + "Escolha a API", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20), + child: Row( + children: [ + radioCheck("ger7", tefSelecionado, radioButtonChangeTef), + Text( + "Ger7", + style: TextStyle(fontSize: 18), + ), + SizedBox(width: 90), + radioCheck("msitef", tefSelecionado, radioButtonChangeTef), + Text( + "M-Sitef", + style: TextStyle(fontSize: 18), + ), + ], + ), + ), + checkBoxImpressao(), + button( + "ENVIAR TRANSAÇÃO", + () { + if (tipoPagamentoSelecionado == "Crédito" && (numParcelas.text.isEmpty || int.parse(numParcelas.text) <= 0)) { + dialogo("É necessário colocar o número de parcelas desejadas (obs.: Opção de compra por crédito marcada)", + "Ocorreu um erro durante a execução"); + } else { + realizarFuncao("venda", tefSelecionado); + } + }, + ), + button( + "CANCELAR TRANSAÇÃO", + () { + realizarFuncao("cancelamento", tefSelecionado); + }, + ), + button( + "FUNÇÕES", + () { + realizarFuncao("funcoes", tefSelecionado); + }, + ), + button( + "REIMPRESSÃO", + () { + realizarFuncao("reimpressao", tefSelecionado); + }, + ) + ], + ), + ), + ); + } + + Widget get textFormFieldIp { + if (tefSelecionado != "msitef") { + return TextFormField( + enabled: false, + decoration: InputDecoration(hintText: '192.168.0.1'), + keyboardType: TextInputType.number, + controller: ipServidor, + inputFormatters: [ + BlacklistingTextInputFormatter(RegExp("[-, ]")), + ], + style: TextStyle(fontSize: 17), + ); + } else { + return TextFormField( + decoration: InputDecoration(hintText: '192.168.0.1'), + keyboardType: TextInputType.number, + inputFormatters: [ + BlacklistingTextInputFormatter(RegExp("[-, ]")), + ], + controller: ipServidor, + style: TextStyle(fontSize: 17), + ); + } + } + + Widget get textFormFieldNumParcelas { + if (tipoPagamentoSelecionado == "Debito" || tipoPagamentoSelecionado == "Todos") { + this.numParcelas.text = "1"; + return TextFormField( + enabled: false, + inputFormatters: [ + WhitelistingTextInputFormatter.digitsOnly, + ], + keyboardType: TextInputType.numberWithOptions(signed: false), + controller: numParcelas, + style: TextStyle(fontSize: 20), + ); + } else { + return TextFormField( + inputFormatters: [ + WhitelistingTextInputFormatter.digitsOnly, + ], + keyboardType: TextInputType.numberWithOptions(signed: false), + controller: numParcelas, + style: TextStyle(fontSize: 20), + ); + } + } + + Widget checkBoxImpressao() { + if (tefSelecionado == "ger7") { + return Row( + children: [ + Checkbox(value: habilitarImpressao, onChanged: alterarValorImpressao), + Text( + "Habilitar impressão", + style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), + ) + ], + ); + } else { + habilitarImpressao = false; + return AbsorbPointer( + child: Row( + children: [ + Checkbox( + activeColor: Colors.grey, + value: habilitarImpressao, + onChanged: alterarValorImpressao, + ), + Text( + "Habilitar impressão", + style: TextStyle( + fontSize: 15, + color: Colors.grey, + ), + ) + ], + ), + ); + } + } + + Widget widgetRadios() { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + "Pagamento a ser utilizado", + style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), + ), + ), + Row( + children: [ + radioCheck("Crédito", tipoPagamentoSelecionado, radioButtonChangePagamento), + AutoSizeText( + 'Crédito', + style: TextStyle(fontSize: 15), + ), + ], + ), + Row( + children: [ + radioCheck("Debito", tipoPagamentoSelecionado, radioButtonChangePagamento), + AutoSizeText( + 'Débito', + style: TextStyle(fontSize: 15), + ), + ], + ), + Row( + children: [ + radioCheck("Todos", tipoPagamentoSelecionado, radioButtonChangePagamento), + AutoSizeText( + 'Todos (Msitef)\nVoucher (Ger7)', + style: TextStyle(fontSize: 15), + ), + ], + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + "Tipo de parcelamento", + style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + radioCheck("Loja", tipoParcelamento, radioButtonChangeParcelamento), + Text( + "Parcelado Loja", + style: TextStyle(fontSize: 15), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + radioCheck("Adm", tipoParcelamento, radioButtonChangeParcelamento), + Text( + "Parcelado Adm", + style: TextStyle(fontSize: 15), + ), + ], + ) + ], + ), + ], + ); + } + + Widget radioCheck(String text, String controll, Function onChange) { + return SizedBox( + height: 30, + child: Radio(value: text, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, groupValue: controll, onChanged: onChange), + ); + } + + Widget button(String text, VoidCallback callback) { + return Center( + child: SizedBox( + width: MediaQuery.of(context).size.width - 30, + child: RaisedButton( + onPressed: callback, + child: Text( + text, + style: TextStyle(fontSize: 15), + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/sat_pages/alterarCodigo.dart b/GPOS 700/lib/pages/sat_pages/alterarCodigo.dart new file mode 100644 index 0000000..61304af --- /dev/null +++ b/GPOS 700/lib/pages/sat_pages/alterarCodigo.dart @@ -0,0 +1,135 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/services/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; + +class PageCodigoSat extends StatefulWidget { + @override + _PageCodigoSatState createState() => _PageCodigoSatState(); +} + +class _PageCodigoSatState extends State { + final codigoAtivacaoNovo = TextEditingController(); // Codigo de ativação Novo + + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação Novo + final confirmacaoCodigo = TextEditingController(); // Confirmação do codigo + String tipoCodigo = "Código de ativação"; // Armazena o tipo de codigo + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void alterarCodigoSat() async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + // Verifica se as entradas são validas + if (commonGertec.isCodigoValido(codigoAtivacao.text) && commonGertec.isCodigoValido(codigoAtivacaoNovo.text)) { + if (codigoAtivacaoNovo.text == confirmacaoCodigo.text) { + // No Java o Sat reconhece 1 - Como sendo a opção de mudar codigo de ativação + // 2 como sendo a opção de alterar codigo de emergência + int op = 0; + if (tipoCodigo == "Código de ativação") + op = 1; + else + op = 2; + + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: { + 'funcao': "TrocarCodAtivacao", + 'random': Random().nextInt(999999), // Cada chamada no Java deve acompanhar diferente + 'codigoAtivar': codigoAtivacao.text.toString(), + 'codigoAtivacaoNovo': codigoAtivacaoNovo.text.toString(), + 'op': op + }, + ); + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } else { + WidgetsGertec.dialogoSat("O Código de Ativação Novo e a Confirmação do Código de Ativação não correspondem!", context: context); + } + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 30), + dropDownList(), + WidgetsGertec.formField(codigoAtivacao, "Atual: "), + SizedBox(height: 20), + WidgetsGertec.formField(codigoAtivacaoNovo, "Novo: "), + SizedBox(height: 20), + WidgetsGertec.formField(confirmacaoCodigo, "Confirmar: "), + SizedBox(height: 20), + SizedBox( + width: 240, + child: RaisedButton( + child: Text("ALTERAR"), + onPressed: () { + alterarCodigoSat(); + }, + ), + ), + ], + ), + ), + ), + ); + } + + Widget dropDownList() { + return Row( + children: [ + Text( + "Tipo de codigo: ", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + DropdownButton( + value: tipoCodigo, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontSize: 15), + onChanged: (String newValue) { + setState( + () { + tipoCodigo = newValue; + }, + ); + }, + items: [ + "Código de ativação", + "Código de Emergência", + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ); + } +} diff --git a/GPOS 700/lib/pages/sat_pages/associarSat.dart b/GPOS 700/lib/pages/sat_pages/associarSat.dart new file mode 100644 index 0000000..e4a3cb2 --- /dev/null +++ b/GPOS 700/lib/pages/sat_pages/associarSat.dart @@ -0,0 +1,102 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/services/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; +import 'package:flutter_masked_text/flutter_masked_text.dart'; + +class PageAssociarSat extends StatefulWidget { + @override + _PageAssociarSatState createState() => _PageAssociarSatState(); +} + +class _PageAssociarSatState extends State { + final cnpj = MaskedTextController(mask: "00.000.000/0000-00"); // CNPJ do contribuinte + final cnpjSoftHouse = MaskedTextController(mask: "00.000.000/0000-00"); // CNPJ do Software House + + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de Ativacao do Sat + final assinaturaAc = TextEditingController(); // Assinatura Ac + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void associarSat() async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (commonGertec.isCodigoValido(codigoAtivacao.text)) { + if (assinaturaAc.text.length != 0) { + if (commonGertec.removeMaskCnpj(cnpj.text).length != 14 || commonGertec.removeMaskCnpj(cnpjSoftHouse.text).length != 14) { + WidgetsGertec.dialogoSat("Verifique o CNPJ digitado!", context: context); + } else { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: { + 'funcao': "AssociarSAT", + 'random': Random().nextInt(999999), + 'codigoAtivar': codigoAtivacao.text.toString(), + 'cnpj': commonGertec.removeMaskCnpj(cnpj.text), + 'cnpjSoft': commonGertec.removeMaskCnpj(cnpjSoftHouse.text), + 'assinatura': assinaturaAc.text + }, + ); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } + } else { + WidgetsGertec.dialogoSat("Assinatura AC Inválida!", context: context); + } + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + WidgetsGertec.formField(cnpj, "CNPJ Contribuinte: ", textInputType: TextInputType.number), + SizedBox(height: 20), + WidgetsGertec.formField(cnpjSoftHouse, "CNPJ Software House: ", textInputType: TextInputType.number), + SizedBox(height: 20), + WidgetsGertec.formField(codigoAtivacao, "Código de Ativação: "), + SizedBox(height: 20), + WidgetsGertec.formField(assinaturaAc, "Assinatura AC: "), + SizedBox(height: 20), + SizedBox( + width: 240, + child: RaisedButton( + child: Text("Associar"), + onPressed: () { + associarSat(); + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/sat_pages/ativarSat.dart b/GPOS 700/lib/pages/sat_pages/ativarSat.dart new file mode 100644 index 0000000..0eff96c --- /dev/null +++ b/GPOS 700/lib/pages/sat_pages/ativarSat.dart @@ -0,0 +1,92 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/services/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; +import 'package:flutter_masked_text/flutter_masked_text.dart'; + +class PageAtivarSat extends StatefulWidget { + @override + _PageAtivarSatState createState() => _PageAtivarSatState(); +} + +class _PageAtivarSatState extends State { + final cnpj = MaskedTextController(mask: "00.000.000/0000-00"); // CNPJ do contribuinte + + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação que vai ser utilizado + + final confirmacaoCodigo = TextEditingController(); // Confirmação do codigo + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void ativarSat() async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (commonGertec.isCodigoValido(codigoAtivacao.text)) { + if (codigoAtivacao.text == confirmacaoCodigo.text) { + String cnpjNoMask = commonGertec.removeMaskCnpj(cnpj.text); // Remove a mascara do CNPJ para validar + if (cnpjNoMask.length != 14) { + WidgetsGertec.dialogoSat("Verifique o CNPJ digitado!", context: context); + } else { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: {'funcao': 'AtivarSAT', 'random': Random().nextInt(999999), 'codigoAtivar': codigoAtivacao.text.toString(), 'cnpj': cnpjNoMask}, + ); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } + } else { + WidgetsGertec.dialogoSat("O Código de Ativação e a Confirmação do Código de Ativação não correspondem!", context: context); + } + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 30), + WidgetsGertec.formField(cnpj, "CNPJ Contribuinte: ", textInputType: TextInputType.number), + SizedBox(height: 20), + WidgetsGertec.formField(codigoAtivacao, "Código de Ativação SAT: "), + SizedBox(height: 20), + WidgetsGertec.formField(confirmacaoCodigo, "Confirmação do Código: "), + SizedBox(height: 20), + SizedBox( + width: 240, + child: RaisedButton( + child: Text("ATIVAR"), + onPressed: () { + ativarSat(); + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/sat_pages/configRede.dart b/GPOS 700/lib/pages/sat_pages/configRede.dart new file mode 100644 index 0000000..7bec79b --- /dev/null +++ b/GPOS 700/lib/pages/sat_pages/configRede.dart @@ -0,0 +1,304 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/services/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; + +class PageConfigSat extends StatefulWidget { + @override + _PageConfigSatState createState() => _PageConfigSatState(); +} + +class _PageConfigSatState extends State { + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação + + final ipSat = TextEditingController(); // Ip do Sat para ser ativado + final mascara = TextEditingController(); // Mascara Rede + final gateway = TextEditingController(); // gateway Rede + final dns1 = TextEditingController(); // dns1 Rede + final dns2 = TextEditingController(); // dns2 Rede + final proxyIp = TextEditingController(); // proxy Rede + final porta = TextEditingController(); // porta Rede + final user = TextEditingController(); // user Rede + final password = TextEditingController(); // password Rede + String tipoRede = "Estático"; // Armazena o tipo de rede + String habilitarDNS = "Sim"; // Armazena opção Dns + String habilitarProxy = "Não usa proxy"; // Armazena o tipo proxy de rede + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void configRedeSat() async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (commonGertec.isCodigoValido(codigoAtivacao.text)) { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: { + 'funcao': "EnviarConfRede", + 'random': Random().nextInt(999999), + 'codigoAtivar': codigoAtivacao.text.toString(), + 'dadosXml': formatarEnvioConfigRede() + }, + ); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 30), + WidgetsGertec.formField(codigoAtivacao, "Codigo ativação: "), + SizedBox(height: 20), + Row( + children: [ + Text( + "Tipo de Rede: ", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + DropdownButton( + value: tipoRede, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontSize: 15), + onChanged: (String newValue) { + setState( + () { + print(newValue); + tipoRede = newValue; + }, + ); + }, + items: ["Estático", "DHCP"].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + verificartipoRede(), + SizedBox(height: 20), + Row( + children: [ + Text( + "DNS: ", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + DropdownButton( + value: habilitarDNS, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontSize: 15), + onChanged: (String newValue) { + setState( + () { + habilitarDNS = newValue; + }, + ); + }, + items: ["Sim", "Não"].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + verificartipoDns(), + SizedBox(height: 20), + Row( + children: [ + Text( + "Proxy: ", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + DropdownButton( + value: habilitarProxy, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontSize: 15), + onChanged: (String newValue) { + setState( + () { + habilitarProxy = newValue; + }, + ); + }, + items: ["Não usa proxy", "Proxy com configuração", "Proxy transparente"].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + verificartipoProxy(), + SizedBox(height: 20), + WidgetsGertec.buttonStandard("ENVIAR", callback: () => configRedeSat()) + ], + ), + ), + ), + ); + } + + Widget verificartipoRede() { + if (tipoRede == "Estático") + return Column( + children: [ + WidgetsGertec.formField(ipSat, "IP SAT: "), + WidgetsGertec.formField(mascara, "Máscara: "), + WidgetsGertec.formField(gateway, "Getway: "), + ], + ); + else { + return SizedBox(height: 0); + } + } + + Widget verificartipoDns() { + if (habilitarDNS == "Sim") + return Column( + children: [ + WidgetsGertec.formField(dns1, "DNS 1: "), + WidgetsGertec.formField(dns2, "DNS 2: "), + ], + ); + else { + return SizedBox(height: 0); + } + } + + Widget verificartipoProxy() { + if (habilitarProxy != "Não usa proxy") + return Column( + children: [ + WidgetsGertec.formField(proxyIp, "Proxy Ip: "), + WidgetsGertec.formField(porta, "Porta: "), + WidgetsGertec.formField(user, "User: "), + WidgetsGertec.formField(password, "Password: "), + ], + ); + else { + return SizedBox(height: 0); + } + } + + // Configuracao os dados a serem enviados para o Sat + List formatarEnvioConfigRede() { + List dadosXml = new List(11); + dadosXml[0] = ""; + dadosXml[1] = ""; + dadosXml[2] = ""; + dadosXml[3] = ""; + dadosXml[4] = ""; + dadosXml[5] = ""; + dadosXml[6] = ""; + dadosXml[7] = ""; + dadosXml[8] = ""; + dadosXml[9] = ""; + dadosXml[10] = ""; + + // Monta as tags do XML sobre a parte de REDE + if (tipoRede == "Estático") { + dadosXml[0] = "IPFIX"; + if (ipSat.text.isNotEmpty) { + dadosXml[1] = "" + ipSat.text + ""; + } + if (mascara.text.isNotEmpty) { + dadosXml[2] = "" + mascara.text + ""; + } + if (gateway.text.isNotEmpty) { + dadosXml[3] = "" + gateway.text + ""; + } + + // Monta as tags do XML sobre a parte de DNS + if (habilitarDNS == "Sim") { + if (dns1.text.isNotEmpty) { + dadosXml[4] = "" + dns1.text + ""; + } + if (dns2.text.isNotEmpty) { + dadosXml[5] = "" + dns2.text + ""; + } + } else { + dadosXml[4] = "8.8.8.8"; + dadosXml[5] = "4.4.4.4"; + } + } else { + dadosXml[0] = "DHCP"; + dadosXml[1] = ""; + dadosXml[2] = ""; + dadosXml[3] = ""; + dadosXml[4] = ""; + dadosXml[5] = ""; + } + + // Monta as tags do XML sobre a parte de PROXY + if (habilitarProxy == "Não usa proxy") { + dadosXml[6] = "0"; + dadosXml[7] = ""; + dadosXml[8] = ""; + dadosXml[9] = ""; + dadosXml[10] = ""; + } else if (habilitarProxy == "Proxy com configuração") { + dadosXml[6] = "1"; + if (proxyIp.text.isNotEmpty) { + dadosXml[7] = "" + proxyIp.text + ""; + } + if (porta.text.isNotEmpty) { + dadosXml[8] = "" + porta.text + ""; + } + if (user.text.isNotEmpty) { + dadosXml[9] = "" + user.text + ""; + } + if (password.text.isNotEmpty) { + dadosXml[10] = "" + password.text + ""; + } + } else { + dadosXml[6] = "2"; + if (proxyIp.text.isNotEmpty) { + dadosXml[7] = "" + proxyIp.text + ""; + } + if (porta.text.isNotEmpty) { + dadosXml[8] = "" + porta.text + ""; + } + if (user.text.isNotEmpty) { + dadosXml[9] = "" + user.text + ""; + } + if (password.text.isNotEmpty) { + dadosXml[10] = "" + password.text + ""; + } + } + return dadosXml; + } +} diff --git a/GPOS 700/lib/pages/sat_pages/ferramentasSat.dart b/GPOS 700/lib/pages/sat_pages/ferramentasSat.dart new file mode 100644 index 0000000..e90c510 --- /dev/null +++ b/GPOS 700/lib/pages/sat_pages/ferramentasSat.dart @@ -0,0 +1,100 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/services/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; + +class PageFerramentaSat extends StatefulWidget { + @override + _PageFerramentaSatState createState() => _PageFerramentaSatState(); +} + +class _PageFerramentaSatState extends State { + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação do Sat + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void ferramentasSat(String funcao) async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (funcao == "Versao" || commonGertec.isCodigoValido(codigoAtivacao.text)) { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: {'funcao': funcao, 'random': Random().nextInt(999999), 'codigoAtivar': codigoAtivacao.text.toString()}); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + // O retorno da operação Versão não é tratado, pois retorna somente uma string + if (funcao == "Versao") { + WidgetsGertec.dialogoSat(retornoSat.getResultadoCompleto, context: context); + } else { + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + Padding( + padding: const EdgeInsets.only(left: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Código de Ativação SAT: ", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 30, + width: 140, + child: TextFormField( + controller: codigoAtivacao, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ), + SizedBox(height: 20), + WidgetsGertec.buttonStandard("BLOQUEAR SAT", callback: () => ferramentasSat("BloquearSat")), + WidgetsGertec.buttonStandard("DESBLOQUEAR SAT", callback: () => ferramentasSat("DesbloquearSat")), + WidgetsGertec.buttonStandard("EXTRAIR LOG", callback: () => ferramentasSat("ExtrairLog")), + WidgetsGertec.buttonStandard("ATUALIZAR SOFTWARE", callback: () => ferramentasSat("AtualizarSoftware")), + WidgetsGertec.buttonStandard("VERIFICAR VERSÃO", callback: () => ferramentasSat("Versao")), + ], + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/sat_pages/testeSat.dart b/GPOS 700/lib/pages/sat_pages/testeSat.dart new file mode 100644 index 0000000..b05ae3f --- /dev/null +++ b/GPOS 700/lib/pages/sat_pages/testeSat.dart @@ -0,0 +1,206 @@ +import 'dart:convert'; +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_gertec/services/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; + +class PageTesteSat extends StatefulWidget { + @override + _PageTesteSatState createState() => _PageTesteSatState(); +} + +class _PageTesteSatState extends State { + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação do Sat + final chaveCancelamento = TextEditingController(text: GlobalValues.valorCfe); // Chave de cancelamento + final chaveSessao = TextEditingController(text: "123"); // Chave de sessao para consulta + String xmlVenda; // Xml de Venda a ser enviado, transformado em Base 64 + String xmlCancelamento; // Xml de Cancelamento a ser enviado, transformado em Base 64 + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + void initState() { + super.initState(); + // Transforma os Xml em base 64 e envia para o Java Android transmitir para a Sefaz + transformarbase64('assets/xmlSat/arq_cancelamento.xml').then((value) => xmlCancelamento = value); + transformarbase64('assets/xmlSat/arq_venda_008_Simples_Nacional.xml').then((value) => xmlVenda = value); + } + + //Reponsavel por fazer a conversão de um File Xml das pastas assets, para um codigo na base 64. + Future transformarbase64(String assetPath) async { + ByteData bytes = await rootBundle.load(assetPath); + var buffer = bytes.buffer; + var m = base64.encode(Uint8List.view(buffer)); + return m; + } + + // Dialogo para inserir dados + void dialogoInserirDados( + String texto, + TextEditingController textEditingController, + TextInputType textInputType, + Function function, + ) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Alerta"), + content: Container( + height: 120, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(texto), + SizedBox( + height: 50, + width: 140, + child: TextFormField( + keyboardType: textInputType, + controller: textEditingController, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + if (textEditingController.text.length > 0) { + Navigator.pop(context); + function(); + } else { + WidgetsGertec.dialogoSat("Verifique a entrada!"); + } + }, + ) + ], + ), + ); + } + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + Future testeSat(String funcao) async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (funcao == "ConsultarSat" || commonGertec.isCodigoValido(codigoAtivacao.text)) { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: { + //* os dados são enviados para o Java, mas nem todos são lidos, por isso não existe problema de alguns parametros estarem Nulos + 'funcao': funcao, + 'random': Random().nextInt(999999), + 'codigoAtivar': codigoAtivacao.text.toString(), + 'chaveCancelamento': chaveCancelamento.text ?? " ", + 'chaveSessao': int.parse(chaveSessao.text) ?? " ", + 'xmlVenda': xmlVenda, + 'xmlCancelamento': xmlCancelamento + }, + ); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + /* + * Está verificação(abaixo) tem como objetivo capturar a "Chave de Consulta" retornado na operação EnviarTesteVendas + * O valor é armazenado em uma variavel global e quando o usuario abre a tela para cancelar venda, o campo (Chave de Cancelamento) já fica preenchido + */ + if (funcao == 'EnviarTesteVendas') { + GlobalValues.valorCfe = retornoSat.getChaveConsulta; + setState(() { + chaveCancelamento.text = GlobalValues.valorCfe; + }); + } + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context, heightDialog: 300); + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + Padding( + padding: const EdgeInsets.only(left: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Código de Ativação SAT: ", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 18, + width: 140, + child: TextFormField( + controller: codigoAtivacao, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ), + SizedBox(height: 20), + WidgetsGertec.buttonStandard("CONSULTAR SAT", callback: () => testeSat("ConsultarSat")), + WidgetsGertec.buttonStandard("STATUS OPERACIONAL", callback: () => testeSat("ConsultarStatusOperacional")), + WidgetsGertec.buttonStandard("TESTE FIM A FIM", callback: () => testeSat("EnviarTesteFim")), + WidgetsGertec.buttonStandard("ENVIAR DADOS DE VENDA", callback: () => testeSat("EnviarTesteVendas")), + WidgetsGertec.buttonStandard( + "CANCELAR VENDA", + callback: () => + // Aqui vai ser aberto o dialogo para inserção de dados para cancelamento da Venda, ao preencher e clicar em Ok, vai ser cancelado a venda + dialogoInserirDados( + "Digite a chave de cancelamento", + chaveCancelamento, + TextInputType.name, + () => testeSat("CancelarUltimaVenda"), + ), + ), + WidgetsGertec.buttonStandard( + "CONSULTAR SESSÃO", + callback: () => + // Aqui vai ser aberto o dialogo para inserção de dados para consulta da sessão + dialogoInserirDados( + "Digite o número da sessão", + chaveSessao, + TextInputType.number, + () => testeSat("ConsultarNumeroSessao"), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/tefs.dart b/GPOS 700/lib/pages/tefs.dart new file mode 100644 index 0000000..2f7c72a --- /dev/null +++ b/GPOS 700/lib/pages/tefs.dart @@ -0,0 +1,496 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/config_tef/operacaoRetorno.dart'; +import 'package:flutter_gertec/serviceTet.dart'; +import 'package:flutter_masked_text/flutter_masked_text.dart'; + +class PageTef extends StatefulWidget { + @override + _PageTefState createState() => _PageTefState(); +} + +class _PageTefState extends State { + TefService tefService = new TefService(); + + /* + * Pode inicializar a classe do service MsiTef com os valores da venda ao invés de settar. + TefService tefService = new TefService( + valor: "200", quantParcelas: 2, + habilitarImpressao: true, ip: "192.168.0.1", tipoPagamento: "Crédito"); + + */ + + //Mascara que pegar o valor do input e transforma em um tipo Money + final precoVenda = MoneyMaskedTextController( + leftSymbol: "R\$ ", + decimalSeparator: '.', + thousandSeparator: ',', + initialValue: 20); + + final ipServidor = + TextEditingController(text: "192.168.15.8"); //Text edit ip do servidor + + final numParcelas = + TextEditingController(text: "1"); //Text edit da quantidade de parcelas + + bool habilitarImpressao = false; //armazena se a impressao vai ser realizada + + String tipoPagamentoSelecionado = + "Crédito"; //armazena o tipo de pagamento escolhido + + String tefSelecionado = "ger7"; //armazena a Tef escolhida + + // Altera o valor da opcao de habilitar impressao (true, false) + void alterarValorImpressao(bool newValue) => setState( + () { + habilitarImpressao = newValue; + }, + ); + + // Setta os valores e os envia para o TefService formatar e encaminhar para o Tef selecionado + // Recebe como parâmetros uma String que está relacionada a ação que deseja ser invocada e uma String relacionado a tef utilizada (ger7,msitef) + // As ações possiveis são: "venda, cancelamento, reimpressao, funcoes" (Os valores devem ser escritos exatamente como o demonstrado) + void realizarFuncao(String acao, String tef) { + // Settando os valores necessarios pra venda e chamando a funcao responsel pela venda. + // Retira mascara Money antes de enviar o valor para a função. + String valorFormatado = precoVenda.text.substring(3); + valorFormatado = valorFormatado.replaceAll('.', ""); + valorFormatado = valorFormatado.replaceAll(',', ""); + tefService.setValorVenda = valorFormatado; + tefService.setIpConfig = ipServidor + .text; // Somente é necessario settar o ip caso esteja utilizando o Tef Msitef + tefService.setHabilitarImpressao = habilitarImpressao; + tefService.setQuantParcelas = int.parse(numParcelas.text); + tefService.setTipoPagamento = tipoPagamentoSelecionado; + tefService.enviarParametrosTef(tipoAcao: acao, tipoTef: tef).then( + (resultadoTef) { + //* Verificando qual o tipo de Tef foi utilizado. Cada Tef possui seu retorno que deve ser associado a uma classe diferente. + if (tef == "ger7") { + RetornoGer7 retornoGer7 = resultadoTef; + // print(retornoGer7.toJson()); - Caso deseje printar o Json de retorno + if (retornoGer7.getErrcode != "0") { + dialogoErroGer7(retornoGer7); + } else { + dialogoTransacaoAprovadaGer7(retornoGer7); + } + } else { + RetornoMsiTef retornoMsiTef = resultadoTef; + // print(retornoMsiTef.toJson()); - Caso deseje printar o Json de retorno + // Verifica se ocorreu algum problema durante a realização da venda ou demais funções. + if (retornoMsiTef.getCodTrans.toString().isEmpty || + retornoMsiTef.getCodTrans == null || + retornoMsiTef.textoImpressoEstabelecimento == null) { + //Caso ocorra um erro durante as ações, um dialogo de erro é chamado + dialogoErroMsitef(retornoMsiTef); + } else { + dialogoTransacaoAprovadaMsitef(retornoMsiTef); + } + } + }, + ); + } + + // Dialogo que será exibido caso ocorra algum erro durante a chamada na Ger7 + void dialogoTransacaoAprovadaGer7(RetornoGer7 operacaoRetorno) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Transação Aprovada"), + content: Container( + height: MediaQuery.of(context).size.height - 20, + child: ListView( + scrollDirection: Axis.vertical, + children: [ + Text("version: " + operacaoRetorno.getVersion), + Text("status: " + operacaoRetorno.getStatus), + Text("config: " + operacaoRetorno.getConfig), + Text("license: " + operacaoRetorno.getLicens), + Text("terminal: " + operacaoRetorno.getTerminal), + Text("merchant: " + operacaoRetorno.getMerchant), + Text("id: " + operacaoRetorno.getId), + Text("type: " + operacaoRetorno.getType), + Text("product: " + operacaoRetorno.getProduct), + Text("response: " + operacaoRetorno.getResponse), + Text("authorization: " + operacaoRetorno.getAuthorization), + Text("amount: " + operacaoRetorno.getAmount), + Text("installments: " + operacaoRetorno.getInstallments), + Text("instmode: " + operacaoRetorno.getInstmode), + Text("stan: " + operacaoRetorno.getStan), + Text("rrn: " + operacaoRetorno.getRrn), + Text("time: " + operacaoRetorno.getTime), + Text("track2: " + operacaoRetorno.getTrack2), + Text("aid: " + operacaoRetorno.getAid), + Text("cardholder: " + operacaoRetorno.getCardholder), + Text("prefname: " + operacaoRetorno.getPrefname), + Text("errcode: " + operacaoRetorno.getErrcode), + Text("label: " + operacaoRetorno.getLabel), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + // Dialogo que será exibido caso a ação seja realizada com sucesso durante a chamada na Ger7 + void dialogoErroGer7(RetornoGer7 operacaoRetorno) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Transação Negada"), + content: Container( + height: 150, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("version: " + operacaoRetorno.getVersion), + Text("errcode: " + operacaoRetorno.getErrcode), + Text("errmsg: " + operacaoRetorno.getErrmsg), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + // Dialogo que será exibido caso a ação seja realizada com sucesso durante a chamada na MsiTef + void dialogoTransacaoAprovadaMsitef(RetornoMsiTef operacaoRetorno) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Transação Aprovada"), + content: Container( + height: 250, + child: ListView( + scrollDirection: Axis.vertical, + children: [ + Text("CODRESP: " + operacaoRetorno.getCodResp), + Text("COMP_DADOS_CONF: " + operacaoRetorno.getCompDadosConf), + Text("CODTRANS: " + operacaoRetorno.getCodTrans), + Text("CODTRANS (Name): " + operacaoRetorno.getNameTransCod), + Text("VLTROCO: " + operacaoRetorno.getvlTroco), + Text("REDE_AUT: " + operacaoRetorno.getRedeAut), + Text("BANDEIRA: " + operacaoRetorno.getBandeira), + Text("NSU_SITEF: " + operacaoRetorno.getNSUSitef), + Text("NSU_HOST: " + operacaoRetorno.getNSUHOST), + Text("COD_AUTORIZACAO: " + operacaoRetorno.getCodAutorizacao), + Text("NUM_PARC: " + operacaoRetorno.getParcelas) + ], + )), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + // Dialogo que será exibido caso ocorra algum erro durante a chamada na MsiTef + void dialogoErroMsitef(RetornoMsiTef operacaoRetorno) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Transação Negada"), + content: Container( + height: 50, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("CODRESP: " + operacaoRetorno.getCodResp), + Text("Verique se o ip está correto !") + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + //Marca o valor do tipo de Tef escolhido + void radioButtonChangeTef(String value) { + setState( + () { + tefSelecionado = value; + }, + ); + } + + //Marca o valor do tipo de pagamento escolhido + void radioButtonChangePagamento(String value) { + setState( + () { + tipoPagamentoSelecionado = value; + }, + ); + } + + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Center( + child: Text( + "Exemplo TEF API - Flutter", + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: Colors.grey[600]), + ), + ), + SizedBox(height: 15), + Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + "Valor em R\$", + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 15), + child: SizedBox( + height: 30, + width: 160, + child: TextFormField( + keyboardType: TextInputType.number, + controller: precoVenda, + style: TextStyle(fontSize: 20), + ), + ), + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + style: TextStyle(fontWeight: FontWeight.bold), + children: [ + TextSpan( + text: 'IP', + style: TextStyle( + fontSize: 18, color: Colors.black)), + TextSpan( + text: '(somente para o M-Siterf)', + style: TextStyle(color: Colors.black)), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(left: 10), + child: SizedBox( + height: 30, + width: 160, + child: TextFormField( + keyboardType: TextInputType.number, + controller: ipServidor, + style: TextStyle(fontSize: 20), + ), + ), + ), + ], + ) + ], + ), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + "Pagamento a ser utilizado", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 15), + child: widgetRadios(), + ), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + "Número de Parcelas", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + Center( + child: SizedBox( + height: 30, + width: MediaQuery.of(context).size.width - 40, + child: TextFormField( + keyboardType: TextInputType.number, + controller: numParcelas, + style: TextStyle(fontSize: 20), + ), + ), + ), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + "Escolha a API", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20), + child: Row( + children: [ + radioCheck("ger7", tefSelecionado, radioButtonChangeTef), + Text( + "Ger7", + style: TextStyle(fontSize: 18), + ), + SizedBox(width: 90), + radioCheck("msitef", tefSelecionado, radioButtonChangeTef), + Text( + "M-Sitef", + style: TextStyle(fontSize: 18), + ), + ], + ), + ), + Row( + children: [ + Checkbox( + value: habilitarImpressao, + onChanged: alterarValorImpressao), + Text( + "Habilitar impressão", + style: TextStyle(fontSize: 15), + ) + ], + ), + button( + "ENVIAR TRANSAÇÃO", + () { + realizarFuncao("venda", tefSelecionado); + }, + ), + button( + "CANCELAR TRANSAÇÃO", + () { + realizarFuncao("cancelamento", tefSelecionado); + }, + ), + button( + "FUNÇÕES", + () { + realizarFuncao("funcoes", tefSelecionado); + }, + ), + button( + "REIMPRESSÃO", + () { + realizarFuncao("reimpressao", tefSelecionado); + }, + ) + ], + ), + ), + ), + ); + } + + Widget widgetRadios() { + return Column( + children: [ + Row( + children: [ + radioCheck("Crédito", tipoPagamentoSelecionado, + radioButtonChangePagamento), + AutoSizeText( + 'Crédito', + style: TextStyle(fontSize: 18), + ), + ], + ), + Row( + children: [ + radioCheck( + "Debito", tipoPagamentoSelecionado, radioButtonChangePagamento), + AutoSizeText( + 'Debito', + style: TextStyle(fontSize: 18), + ), + ], + ), + Row( + children: [ + radioCheck( + "Todos", tipoPagamentoSelecionado, radioButtonChangePagamento), + AutoSizeText( + 'Todos (Msitef) / Voucher (Ger7)', + style: TextStyle(fontSize: 18), + ), + ], + ), + ], + ); + } + + Widget radioCheck(String text, String controll, Function onChange) { + return SizedBox( + height: 30, + child: Radio( + value: text, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + groupValue: controll, + onChanged: onChange), + ); + } + + Widget button(String text, VoidCallback callback) { + return Center( + child: SizedBox( + width: MediaQuery.of(context).size.width - 30, + child: RaisedButton( + onPressed: callback, + child: Text( + text, + style: TextStyle(fontSize: 15), + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/serviceTet.dart b/GPOS 700/lib/serviceTet.dart new file mode 100644 index 0000000..3d20ef3 --- /dev/null +++ b/GPOS 700/lib/serviceTet.dart @@ -0,0 +1,340 @@ +import 'dart:convert'; +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; + +import 'config_tef/operacaoRetorno.dart'; +import 'config_tef/venda.dart'; + +//Recebe um Json obtido através da chamada feito para Tef e a formata para devolver ao Flutter. +Map _formatarInfoRecebida(myjson) { + Map mapResultado; + myjson = myjson.toString().replaceAll('\\n', ""); + myjson = myjson.toString().replaceAll('\\r', ""); + myjson = myjson.toString().replaceAll('\\', ""); + myjson = myjson.toString().replaceAll('"{', "{ "); + myjson = myjson.toString().replaceAll('}"', " }"); + var parsedJson = json.decode(myjson); + mapResultado = Map.from(parsedJson); + return mapResultado; +} + +class TefService { + TefService( + {String valor, + String tipoPagamento, + int quantParcelas, + bool habilitarImpressao, + String ip}) { + this._ipConfig = ip; + this._valorVenda = valor; + this._tipoPagamento = tipoPagamento; + this._quantParcelas = quantParcelas; + this._habilitarImpressao = habilitarImpressao; + } + + final _platform = const MethodChannel('samples.flutter.dev/gedi'); + String _valorVenda; + String _tipoPagamento; + int _quantParcelas; + bool _habilitarImpressao; + String _ipConfig; + + final String _ger7ApiVersion = "1.04"; + final String _ger7SemParcelamento = "0"; + final String _ger7ParcelaDoLoja = "1"; + final String _ger7ParcelaDoAdm = "2"; + final String _ger7DesabilitaImpressao = "0"; + final String _ger7HabilitaImpressao = "1"; + +//Metodos Get + String get getIpConfig => _ipConfig; + String get getValorVenda => _valorVenda; + + //Retorna uma lista onde o Index 0 == TipoPagamento Ger 7 e o 1 == TipoPagamento M-Sitef (Caso exista esse tipo de pagamento no Tef) + List get getTipoPagamento { + if (_tipoPagamento == "Crédito") { + return ["1", "3"]; + } else if (_tipoPagamento == "Debito") { + return ["2", "2"]; + } else if (_tipoPagamento == "Voucher") { + return ["4", "4"]; + } else { + return ["0", "0"]; + } + } + + int get getQuantParcelas => _quantParcelas; + bool get getImpressaoHabilitada => _habilitarImpressao; +//Metodos Set + set setValorVenda(String valor) => _valorVenda = valor; + set setTipoPagamento(String tipo) => this._tipoPagamento = tipo; + set setQuantParcelas(int quantParcelas) => _quantParcelas = quantParcelas; + set setHabilitarImpressao(bool value) => _habilitarImpressao = value; + set setIpConfig(String ip) => _ipConfig = ip; + + /// Realiza a formatação para reimpressão da nota emitida. + /// ''' + /// Retorna um json, que vai ser enviado para a Tef Ger 7. + String get _formatarPametrosReimpressaoGer7 { + Venda venda = new Venda(); + venda.setType = "18"; + venda.setId = new Random().nextInt(9999999).toString(); + venda.setReceipt = this._ger7HabilitaImpressao; + venda.setApiversion = this._ger7ApiVersion; + String json = jsonEncode(venda.toJson()); + return json; + } + + /// Realiza a formatação para abertura de funções da Tef. + /// ''' + /// Retorna um json, que vai ser enviado para a Tef Ger 7. + String get _formatarPametrosFuncaoGer7 { + Venda venda = new Venda(); + venda.setType = "3"; + venda.setId = new Random().nextInt(9999999).toString(); + venda.setReceipt = this._ger7HabilitaImpressao; + venda.setApiversion = this._ger7ApiVersion; + String json = jsonEncode(venda.toJson()); + return json; + } + + // Realiza a formatação para realização de venda Ger7. + // ''' + // Retorna um json, que vai ser enviado para a Tef Ger 7. + String get _formatarPametrosVendaGer7 { + Venda venda = new Venda(); + venda.setType = "1"; + venda.setId = new Random().nextInt(9999999).toString(); + venda.setAmount = this.getValorVenda.toString(); + venda.setInstallments = this.getQuantParcelas.toString(); + if (venda.getInstallments == "0" || venda.getInstallments == "1") { + venda.setInstmode = this._ger7SemParcelamento; + } else if (true) { + venda.setInstmode = this._ger7ParcelaDoLoja; + } else { + venda.setInstmode = this._ger7ParcelaDoAdm; + } + + venda.setProduct = this.getTipoPagamento[0]; + + if (this.getImpressaoHabilitada) { + venda.setReceipt = this._ger7HabilitaImpressao; + } else { + venda.setReceipt = this._ger7DesabilitaImpressao; + } + venda.setApiversion = this._ger7ApiVersion; + String json = jsonEncode(venda.toJson()); + return json; + } + + /// Realiza a formatação para cancelamento da nota emitida. + /// ''' + /// Retorna um json, que vai ser enviado para a Tef Ger 7. + String get _formatarPametrosCancelamentoGer7 { + Venda venda = new Venda(); + venda.setType = "2"; + venda.setId = new Random().nextInt(9999999).toString(); + venda.setApiversion = this._ger7ApiVersion; + String json = jsonEncode(venda.toJson()); + return json; + } + + /// Realiza a formatação para realização de venda MsiTef. + /// ''' + /// Retorna um json, que vai ser enviado para a Tef MsiTef. + Map get _formatarPametrosVendaMsiTef { + Map mapMsiTef = Map(); + String now = new DateTime.now().toString(); + now = now.toString().replaceAll("-", ""); + now = now.toString().replaceAll(":", ""); + now = now.toString().replaceAll(".", ""); + String data = now.substring(0, 8); + String hora = now.substring(8, 15); + mapMsiTef["empresaSitef"] = "00000000"; + mapMsiTef["enderecoSitef"] = this.getIpConfig; + mapMsiTef["operador"] = "0001"; + mapMsiTef["data"] = data; + mapMsiTef["hora"] = hora; + mapMsiTef["numeroCupom"] = new Random().nextInt(9999999).toString(); + mapMsiTef["valor"] = this.getValorVenda; + mapMsiTef["CNPJ_CPF"] = "03654119000176"; + mapMsiTef["comExterna"] = "0"; + mapMsiTef["modalidade"] = this.getTipoPagamento[1]; + if (this.getTipoPagamento[1] == "3") { + if (this.getQuantParcelas == 1 || this.getQuantParcelas == 0) { + mapMsiTef["transacoesHabilitadas"] = "26"; + } + if (true) { + mapMsiTef["transacoesHabilitadas"] = "27"; + } else { + mapMsiTef["transacoesHabilitadas"] = "27"; + } + mapMsiTef["numParcelas"] = this.getQuantParcelas.toString(); + } + if (this.getTipoPagamento[1] == "2") { + mapMsiTef["transacoesHabilitadas"] = "16"; + } + if (this.getTipoPagamento[1] == "0") { + mapMsiTef["restricoes"] = "transacoesHabilitadas=16"; + } + mapMsiTef["isDoubleValidation"] = "0"; + mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; + if (this.getImpressaoHabilitada) { + mapMsiTef["comprovante"] = "1"; + } else { + mapMsiTef["comprovante"] = "0"; + } + return mapMsiTef; + } + + ///Realiza a formatação para realização de cancelamento MsiTef. + /// ''' + /// Retorna um map , que vai ser enviado para a MsiTef. + Map get _formatarPametrosCancelamentoMsiTef { + Map mapMsiTef = Map(); + String now = new DateTime.now().toString(); + now = now.toString().replaceAll("-", ""); + now = now.toString().replaceAll(":", ""); + now = now.toString().replaceAll(".", ""); + String data = now.substring(0, 8); + String hora = now.substring(8, 15); + mapMsiTef["empresaSitef"] = "00000000"; + mapMsiTef["enderecoSitef"] = this.getIpConfig; + mapMsiTef["operador"] = "0001"; + mapMsiTef["data"] = data; + mapMsiTef["hora"] = hora; + mapMsiTef["numeroCupom"] = new Random().nextInt(9999999).toString(); + mapMsiTef["valor"] = this.getValorVenda; + mapMsiTef["CNPJ_CPF"] = "03654119000176"; + mapMsiTef["comExterna"] = "0"; + mapMsiTef["modalidade"] = "200"; + mapMsiTef["isDoubleValidation"] = "0"; + mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; + if (this.getImpressaoHabilitada) { + mapMsiTef["comprovante"] = "1"; + } else { + mapMsiTef["comprovante"] = "0"; + } + return mapMsiTef; + } + + /// Realiza a formatação para realização de configuração de funções MsiTef. + /// ''' + /// Retorna um map , que vai ser enviado para a Tef Ger 7. + Map get _formatarPametrosFuncoesMsiTef { + Map mapMsiTef = Map(); + String now = new DateTime.now().toString(); + now = now.toString().replaceAll("-", ""); + now = now.toString().replaceAll(":", ""); + now = now.toString().replaceAll(".", ""); + String data = now.substring(0, 8); + String hora = now.substring(8, 15); + mapMsiTef["empresaSitef"] = "00000000"; + mapMsiTef["enderecoSitef"] = this.getIpConfig; + mapMsiTef["operador"] = "0001"; + mapMsiTef["data"] = data; + mapMsiTef["hora"] = hora; + mapMsiTef["numeroCupom"] = new Random().nextInt(9999999).toString(); + mapMsiTef["valor"] = this.getValorVenda; + mapMsiTef["CNPJ_CPF"] = "03654119000176"; + mapMsiTef["comExterna"] = "0"; + mapMsiTef["modalidade"] = "110"; + mapMsiTef["isDoubleValidation"] = "0"; + mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; + mapMsiTef["restricoes"] = "transacoesHabilitadas=16;26;27"; + if (this.getImpressaoHabilitada) { + mapMsiTef["comprovante"] = "1"; + } else { + mapMsiTef["comprovante"] = "0"; + } + return mapMsiTef; + } + + /// Realiza a formatação para realização de reimpressão MsiTef. + /// ''' + /// Retorna um map , que vai ser enviado para a Tef Ger + Map get _formatarPametrosReimpressaoMsiTef { + Map mapMsiTef = Map(); + String now = new DateTime.now().toString(); + now = now.toString().replaceAll("-", ""); + now = now.toString().replaceAll(":", ""); + now = now.toString().replaceAll(".", ""); + String data = now.substring(0, 8); + String hora = now.substring(8, 15); + mapMsiTef["empresaSitef"] = "00000000"; + mapMsiTef["enderecoSitef"] = this.getIpConfig; + mapMsiTef["operador"] = "0001"; + mapMsiTef["data"] = data; + mapMsiTef["hora"] = hora; + mapMsiTef["numeroCupom"] = new Random().nextInt(9999999).toString(); + mapMsiTef["valor"] = this.getValorVenda; + mapMsiTef["CNPJ_CPF"] = "03654119000176"; + mapMsiTef["comExterna"] = "0"; + mapMsiTef["modalidade"] = "114"; + mapMsiTef["isDoubleValidation"] = "0"; + mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; + if (this.getImpressaoHabilitada) { + mapMsiTef["comprovante"] = "1"; + } else { + mapMsiTef["comprovante"] = "0"; + } + return mapMsiTef; + } + + // Realiza as funções da Tef, tem como retorno um objeto dynamic que pode ser atributi a [RetornoMsiTef] ou [RetornoGer7] + // Recebe como parâmetros uma String que está relacionada a ação que deseja ser invocada e uma String relacionado a tef utilizada (ger7,msitef) + // As ações possiveis são: venda, cancelamento, reimpressao, funcoes (Os valores devem ser escritos exatamente como o demonstrado) + Future enviarParametrosTef( + {@required String tipoAcao, @required String tipoTef}) async { + var retornoTef; + var myjson; + var parametroFormatado; + // Verificando qual foi a tef selecionada, dependendo da Tef os seus parâmetros são formatados; + if (tipoTef == "ger7") { + switch (tipoAcao) { + case "venda": + print("venda"); + parametroFormatado = _formatarPametrosVendaGer7; + break; + case "cancelamento": + parametroFormatado = _formatarPametrosCancelamentoGer7; + break; + case "funcoes": + parametroFormatado = _formatarPametrosFuncaoGer7; + break; + case "reimpressao": + parametroFormatado = _formatarPametrosReimpressaoGer7; + break; + } + myjson = await _platform.invokeMethod( + 'realizarAcaoGer7', + {"json": parametroFormatado}, + ); + retornoTef = RetornoGer7.fromJson(_formatarInfoRecebida(myjson)); + } else { + // Caso não for Ger7, então M-Sitef + switch (tipoAcao) { + case "venda": + parametroFormatado = _formatarPametrosVendaMsiTef; + break; + case "cancelamento": + parametroFormatado = _formatarPametrosCancelamentoMsiTef; + break; + case "funcoes": + parametroFormatado = _formatarPametrosFuncoesMsiTef; + break; + case "reimpressao": + parametroFormatado = _formatarPametrosReimpressaoMsiTef; + break; + } + myjson = await _platform.invokeMethod( + 'realizarAcaoMsitef', + {"mapMsiTef": parametroFormatado}, + ); + retornoTef = RetornoMsiTef.fromJson(_formatarInfoRecebida(myjson)); + } + return retornoTef; + } +} diff --git a/GPOS 700/lib/services/globalValues.dart b/GPOS 700/lib/services/globalValues.dart new file mode 100644 index 0000000..6bb6ff4 --- /dev/null +++ b/GPOS 700/lib/services/globalValues.dart @@ -0,0 +1,5 @@ +class GlobalValues { + GlobalValues._(); + static String codAtivarSat = ""; + static String valorCfe = "CFe29200603654119000176599000073560000266137373"; +} diff --git a/GPOS 700/lib/services/operacaoSat.dart b/GPOS 700/lib/services/operacaoSat.dart new file mode 100644 index 0000000..7cf6d55 --- /dev/null +++ b/GPOS 700/lib/services/operacaoSat.dart @@ -0,0 +1,170 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; + +import 'retornoSat.dart'; + +const platform = const MethodChannel('samples.flutter.dev/gedi'); + +class OperacaoSat { + // Funcão que invoca uma operação no Sat. Recebe como parâmetro um Map com os valores que vão ser enviados para o Sat + static Future invocarOperacaoSat({Map args}) async { + try { + // O resultado da invocação de uma operação é uma String grande contendos todas as informações divida por Pipes "|" + String retornoPipeCompleto = await platform.invokeMethod(args['funcao'], args); + + // Após a String ser recebida do canal, ela é enviada como parâmetro para a classe [RetornoSat] + // onde a String é divida e pode ser pego seus valores através de metodos Get e Set. + RetornoSat retornoSat = new RetornoSat(args['funcao'], retornoPipeCompleto); + // Esta função já retorna um objeto do tipo [RetornoSat], onde as informações do retorno já podem ser acessadas + return retornoSat; + } on Exception catch (_) { + return null; + } + } + + // Função que retorna uma String formatada para ser posta no dialogo Sat, com todas as informações do retorno da operação realizada + // Em caso de erro retorna o erro + // *Existem operações que vão ter como resultado informações semelhantes + static String formataRetornoSat({@required RetornoSat retornoSat}) { + String retornoFormatado = ''; + // Verifica se existe um erro no retorno + if (retornoSat.getErroSat != "") { + // Retorna o erro caso exista + return "Mensagem: " + retornoSat.getErroSat; + } else { + //* Estas informações são padrões a todos os retornos(sempre vão aparecer no Dialogo Sat) + //* Para mais informações consulte o arquivo retornosSat.txt. É possivel visualizar nele a posição e informação de cada Retorno do Sat. + if (retornoSat.getNumeroCCCC != "") { + // Se tiver Código CCCC adiciona ele a string formatada + retornoFormatado = retornoSat.getNumeroEEEE + "|" + retornoSat.getNumeroCCCC + "-"; + } else { + // Caso não tenha o código CCCC adicionada somente o EEEE + retornoFormatado = retornoSat.getNumeroEEEE + "-"; + } + + retornoFormatado += retornoSat.getMensagem; + + retornoFormatado += "\n"; // Pula linha + + // Verifica se adiciona o Código e Mensagem Sefaz na mensagem, caso não estejam vazios + if (retornoSat.getNumeroCod != "" && retornoSat.getMensagemSefaz != "") { + retornoFormatado += "Cod/Mens Sefaz: \n" + retornoSat.getNumeroCod + "-" + retornoSat.getMensagemSefaz; + } else if (retornoSat.getNumeroCod != "") { + retornoFormatado += "Cod/Mens Sefaz: \n" + retornoSat.getNumeroCod + "-"; + } else if (retornoSat.getMensagemSefaz != "") { + retornoFormatado += "Cod/Mens Sefaz: \n" + "-" + retornoSat.getMensagemSefaz; + } + + retornoFormatado += "\n"; // Pula linha + + //* Agora só são inseridas as informações que não são padrões a todos retornos + //* São atribuidas as informações especificas do retorno da operação + if (retornoSat.getOperacao == "AtivarSAT") { + if (retornoSat.getCodigoCSR != "") { + retornoFormatado += "CSR: " + retornoSat.getCodigoCSR; + } + } else if (retornoSat.getOperacao == "ExtrairLog") { + //! Cuidado com está parte, ela pode exigir muito processamento se estiver em modo Debug + //! Recomenda-se que utilize somente em modo release e não colocar em um Dialogo, pois o arquivo retornado é grande + // retornoFormatado += "Arquivo de log em base64: " + retornoSat.getLogBase64; + print(retornoSat.getLogBase64); + } else if (retornoSat.getOperacao == "ConsultarStatusOperacional") { + retornoFormatado += "------- Conteúdo Retorno -------" + + "\n" + + "Número de Série do SAT: " + + retornoSat.getNumeroSerieSat + + "Tipo de Lan: " + + retornoSat.getTipoLan + + "\n" + + "IP SAT: " + + retornoSat.getIpSat + + "\n" + + "MAC SAT: " + + retornoSat.getMacSat + + "\n" + + "Máscara: " + + retornoSat.getMascara + + "\n" + + "Gateway: " + + retornoSat.getGateway + + "\n" + + "DNS 1: " + + retornoSat.getDns1 + + "\n" + + "DNS 2: " + + retornoSat.getDns2 + + "\n" + + "Status da Rede: " + + retornoSat.getStatusRede + + "\n" + + "Nível da Bateria: " + + retornoSat.getNivelBateria + + "\n" + + "Memória de Trabalho Total: " + + retornoSat.getMemoriaDeTrabalhoTotal + + "\n" + + "Memória de Trabalho Usada: " + + retornoSat.getMemoriaDeTrabalhoUsada + + "\n" + + "Data/Hora: " + + retornoSat.getDataHora + + "\n" + + "Versão: " + + retornoSat.getVersao + + "\n" + + "Versão de Leiaute: " + + retornoSat.getVersaoLeiaute + + "\n" + + "Último CFe-Sat Emitido: " + + retornoSat.getUltimoCfeEmitido + + "\n" + + "Primeiro CFe-Sat Em Memória: " + + retornoSat.getPrimeiroCfeMemoria + + "\n" + + "Último CFe-Sat Em Memória: " + + retornoSat.getUltimoCfeMemoria + + "\n" + + "Última Transmissão de CFe-SAT para SEFAZ: " + + retornoSat.getUltimaTransmissaoSefazDataHora + + "\n" + + "Última Comunicacao com a SEFAZ:" + + retornoSat.getUltimaComunicacaoSefazData + + "\n" + + "Estado de Operação do SAT: " + + retornoSat.getEstadoDeOperacao; + } else if (retornoSat.getOperacao == "AssociarSAT") { + //* Associar SAT somente tem como dado especifico o campo CCCC(fica ao seu criterio adicionar-lo ou não) + } else if (retornoSat.getOperacao == "EnviarTesteFim") { + retornoFormatado += "TimeStamp: " + + retornoSat.getTimeStamp + + "\nNum Doc Fiscal: " + + retornoSat.getNumDocFiscal + + "\nChave de Consulta: " + + retornoSat.getChaveConsulta + + "\nArquivo CFE Base 64: " + + converterBase64EmXml(retornoSat.getArquivoCFeBase64); + } else if (retornoSat.getOperacao == "EnviarTesteVendas" || retornoSat.getOperacao == "CancelarUltimaVenda") { + retornoFormatado += "TimeStamp: " + + retornoSat.getTimeStamp + + "\nChave de Consulta: " + + retornoSat.getChaveConsulta + + "\nValor CFE: " + + retornoSat.getValorTotalCFe + + "\nValor CPF CNPJ: " + + retornoSat.getCPFCNPJValue + + "\nArquivo CFE Base 64: " + + converterBase64EmXml(retornoSat.getArquivoCFeBase64) + + "\nAssinatura QRCODE: " + + retornoSat.getAssinaturaQRCODE; + } + } + return retornoFormatado; + } + + // Função que converte o arquivo Base 64 em String + static String converterBase64EmXml(String base64Sat) { + return utf8.decode(base64.decode(base64Sat)); // Converte o arquivo Base 64 em String(vai ser usado para visualizar o Xml de resposta) + } +} diff --git a/GPOS 700/lib/services/retornoSat.dart b/GPOS 700/lib/services/retornoSat.dart new file mode 100644 index 0000000..df2266b --- /dev/null +++ b/GPOS 700/lib/services/retornoSat.dart @@ -0,0 +1,284 @@ +class RetornoSat { + List _retornoPipe; // Armazena o retorno em forma de lista String + String _operacao; // Armazena a operacao solicitada + bool retornoDiferente; + String _retornoPipeCompleto; + RetornoSat(String operacao, String retornopipe) { + this._retornoPipeCompleto = retornopipe; + this._retornoPipe = retornopipe.split("|"); + this._operacao = operacao; + /** + O resultado das operações solicitadas é uma String divida por Pipes, exemplo: “numeroSessao|EEEEE|mensagem|cod|mensagemSEFAZ” + Mas nem todos os retornos são padrões, existem alguns com posições diferentes de um mesmo valor. + Para solucionar este obstaculo foi elabarado uma condição que verifica se a operação solicitada é uma das três(que possuem maior discrepância de posições) + Caso sim, é retornado uma posição diferente do mesmo valor, caso contrario é retornado a posição padrão + **/ + retornoDiferente = _operacao == 'AssociarSAT' || _operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda'; + } + // Retorna a String divida por pipe sem formatações + get getResultadoCompleto => _retornoPipeCompleto; + + // Retorna a Operacao que foi solicitada + get getOperacao => _operacao; + + // Verifica se tem algum problema no retorno da operacao solicitada + get getErroSat { + //* Se o tamanho da lista de informações obtidas do retorno [_retornoPipe] for igual <= 1, provavelmente ocorreu um erro. + if (_retornoPipe.length <= 1) { + // Verifica se houve um erro ao se conectar com o Sat + if (_retornoPipe[0] == 'Failed to find SAT device.') { + return 'Dispositivo SAT não localizado'; + } else { + // Caso não seja um erro de comunicação com o SAT retorna o erro que ocorreu + return _retornoPipe[0]; + } + } + //* Verifica se o código de ativação é invalido + if (getMensagem == "Codigo de ativação inválido" || getMensagem == "Codigo ativação inválido") { + return getMensagem; + } + // Caso não exista nenhum erro + return ""; + } + + get getNumeroSessao { + try { + return _retornoPipe[0]; + } catch (e) { + return ""; + } + } + + get getNumeroEEEE { + try { + return _retornoPipe[1]; + } catch (e) { + return ""; + } + } + + get getMensagem { + try { + if (retornoDiferente) return _retornoPipe[3]; + return _retornoPipe[2]; + } catch (e) { + return ""; + } + } + + // Dado somente presente na três funções(AssociarSAT, Enviar Teste Venda e Cancelar Ultima Venda) + get getNumeroCCCC { + try { + if (retornoDiferente) return _retornoPipe[2]; + return ""; + } catch (e) { + return ""; + } + } + + get getNumeroCod { + try { + if (retornoDiferente) return _retornoPipe[4]; + return _retornoPipe[3]; + } catch (e) { + return ""; + } + } + + get getMensagemSefaz { + try { + if (retornoDiferente) return _retornoPipe[5]; + return _retornoPipe[4]; + } catch (e) { + return ""; + } + } + + // Dado exclusivo do retorno da operação Ativar Sat + get getCodigoCSR { + try { + if (_operacao == 'AtivarSAT') return _retornoPipe[5]; + return ""; + } catch (e) { + return ""; + } + } + + // Dado exclusivo do retorno da operação Extrair Log + get getLogBase64 { + try { + if (_operacao == 'ExtrairLog') return _retornoPipe[5]; + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente na três funções(EnviarTesteFim, Enviar Teste Venda e Cancelar Ultima Venda) + get getArquivoCFeBase64 { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') { + return _retornoPipe[6]; + } else if (_operacao == 'EnviarTesteFim') { + return _retornoPipe[5]; + } else { + return ""; + } + } catch (e) { + return ""; + } + } + + // Dado somente presente na três funções(EnviarTesteFim, Enviar Teste Venda e Cancelar Ultima Venda) + get getTimeStamp { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') { + return _retornoPipe[7]; + } else if (_operacao == 'EnviarTesteFim') { + return _retornoPipe[6]; + } else { + return ""; + } + } catch (e) { + return ""; + } + } + + // Dado exclusivo do retorno da operação TEnviarTesteFim + get getNumDocFiscal { + try { + if (_operacao == "EnviarTesteFim") return _retornoPipe[7]; + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente na três funções(EnviarTesteFim, Enviar Teste Venda e Cancelar Ultima Venda) + get getChaveConsulta { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda' || _operacao == 'EnviarTesteFim') return _retornoPipe[8]; + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente nas funções(Enviar Teste Venda e Cancelar Ultima Venda) + get getValorTotalCFe { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') + return _retornoPipe[9]; + else + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente nas funções(Enviar Teste Venda e Cancelar Ultima Venda) + get getCPFCNPJValue { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') + return _retornoPipe[10]; + else + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente nas funções(Enviar Teste Venda e Cancelar Ultima Venda) + get getAssinaturaQRCODE { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') + return _retornoPipe[11]; + else + return ""; + } catch (e) { + return ""; + } + } + + get getEstadoDeOperacao { + try { + if (_retornoPipe[27] == "0") + return "DESBLOQUEADO"; + else if (_retornoPipe[27] == "1") + return "BLOQUEADO SEFAZ"; + else if (_retornoPipe[27] == "2") + return "BLOQUEIO CONTRIBUINTE"; + else if (_retornoPipe[27] == "3") + return "BLOQUEIO AUTÔNOMO"; + else if (_retornoPipe[27] == "4") return "BLOQUEIO PARA DESATIVAÇÃO"; + } catch (e) { + return ""; + } + } + + get getNumeroSerieSat { + try { + return _retornoPipe[5] + "\n"; + } catch (e) { + return ""; + } + } + + get getTipoLan => _retornoPipe[6] + "\n"; + get getIpSat => _retornoPipe[7] + "\n"; + get getMacSat => _retornoPipe[8] + "\n"; + get getMascara => _retornoPipe[9] + "\n"; + get getGateway => _retornoPipe[10] + "\n"; + get getDns1 => _retornoPipe[11] + "\n"; + get getDns2 => _retornoPipe[12] + "\n"; + get getStatusRede => _retornoPipe[13] + "\n"; + get getNivelBateria => _retornoPipe[14] + "\n"; + get getMemoriaDeTrabalhoTotal => _retornoPipe[15] + "\n"; + get getMemoriaDeTrabalhoUsada => _retornoPipe[16] + "\n"; + get getDataHora => + _retornoPipe[17].substring(6, 8) + + "/" + + _retornoPipe[17].substring(4, 6) + + "/" + + _retornoPipe[17].substring(0, 4) + + " " + + _retornoPipe[17].substring(8, 10) + + ":" + + _retornoPipe[17].substring(10, 12) + + ":" + + _retornoPipe[17].substring(12, 14) + + "\n"; + + get getVersao => _retornoPipe[18] + "\n"; + get getVersaoLeiaute => _retornoPipe[19] + "\n"; + get getUltimoCfeEmitido => _retornoPipe[20] + "\n"; + get getPrimeiroCfeMemoria => _retornoPipe[21] + "\n"; + get getUltimoCfeMemoria => _retornoPipe[22] + "\n"; + get getUltimaTransmissaoSefazDataHora => + _retornoPipe[23].substring(6, 8) + + "/" + + _retornoPipe[23].substring(4, 6) + + "/" + + _retornoPipe[23].substring(0, 4) + + " " + + _retornoPipe[23].substring(8, 10) + + ":" + + _retornoPipe[23].substring(10, 12) + + ":" + + _retornoPipe[23].substring(12, 14) + + "\n"; + + get getUltimaComunicacaoSefazData => + _retornoPipe[24].substring(6, 8) + + "/" + + _retornoPipe[24].substring(4, 6) + + "/" + + _retornoPipe[24].substring(0, 4) + + " " + + _retornoPipe[24].substring(8, 10) + + ":" + + _retornoPipe[24].substring(10, 12) + + ":" + + _retornoPipe[24].substring(12, 14) + + "\n"; +} diff --git a/GPOS 700/lib/services/serviceTet.dart b/GPOS 700/lib/services/serviceTet.dart new file mode 100644 index 0000000..10a0371 --- /dev/null +++ b/GPOS 700/lib/services/serviceTet.dart @@ -0,0 +1,344 @@ +import 'dart:convert'; +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_gertec/config_tef/operacaoRetorno.dart'; +import 'package:flutter_gertec/config_tef/venda.dart'; + +//Recebe um Json obtido através da chamada feito para Tef e a formata para devolver ao Flutter. +Map _formatarInfoRecebida(myjson) { + Map mapResultado; + // myjson = myjson.toString().replaceAll('\\n', ""); + myjson = myjson.toString().replaceAll('\\r', ""); + // myjson = myjson.toString().replaceAll('\\', ""); + myjson = myjson.toString().replaceAll('"{', "{ "); + myjson = myjson.toString().replaceAll('}"', " }"); + var parsedJson = json.decode(myjson); + mapResultado = Map.from(parsedJson); + return mapResultado; +} + +class TefService { + TefService({String valor, String tipoPagamento, int quantParcelas, bool habilitarImpressao, String ip}) { + this._ipConfig = ip; + this._valorVenda = valor; + this._tipoPagamento = tipoPagamento; + this._quantParcelas = quantParcelas; + this._habilitarImpressao = habilitarImpressao; + } + + final _platform = const MethodChannel('samples.flutter.dev/gedi'); + String _valorVenda; + String _tipoPagamento; + int _quantParcelas; + bool _habilitarImpressao; + String _ipConfig; + String _tipoParcelamento; + + final String _ger7ApiVersion = "1.04"; + final String _ger7SemParcelamento = "0"; + final String _ger7ParcelaDoLoja = "1"; + final String _ger7ParcelaDoAdm = "2"; + final String _ger7DesabilitaImpressao = "0"; + final String _ger7HabilitaImpressao = "1"; + +//Metodos Get + String get getIpConfig => _ipConfig; + String get getValorVenda => _valorVenda; + + //Retorna uma lista onde o Index 0 == TipoPagamento Ger 7 e o 1 == TipoPagamento M-Sitef (Caso exista esse tipo de pagamento no Tef) + List get getTipoPagamento { + if (_tipoPagamento == "Crédito") { + return ["1", "3"]; + } else if (_tipoPagamento == "Debito") { + return ["2", "2"]; + } else if (_tipoPagamento == "Todos") { + return ["4", "0"]; + } else { + return ["0", "0"]; + } + } + + int get getQuantParcelas => _quantParcelas; + bool get getImpressaoHabilitada => _habilitarImpressao; + get getTipoParcelamento => this._tipoParcelamento; + +//Metodos Set + set setTipoParcelamento(String tipo) => _tipoParcelamento = tipo; + set setValorVenda(String valor) => _valorVenda = valor; + set setTipoPagamento(String tipo) => this._tipoPagamento = tipo; + set setQuantParcelas(int quantParcelas) => _quantParcelas = quantParcelas; + set setHabilitarImpressao(bool value) => _habilitarImpressao = value; + set setIpConfig(String ip) => _ipConfig = ip; + + /// Realiza a formatação para reimpressão da nota emitida. + /// + /// Retorna um json, que vai ser enviado para a Tef Ger 7. + String get _formatarPametrosReimpressaoGer7 { + Venda venda = new Venda(); + venda.setType = "18"; + venda.setId = new Random().nextInt(9999999).toString(); + if (this.getImpressaoHabilitada) { + venda.setReceipt = this._ger7HabilitaImpressao; + } else { + venda.setReceipt = this._ger7DesabilitaImpressao; + } + venda.setApiversion = this._ger7ApiVersion; + String json = jsonEncode(venda.toJson()); + return json; + } + + /// Realiza a formatação para abertura de funções da Tef. + /// + /// Retorna um json, que vai ser enviado para a Tef Ger 7. + String get _formatarPametrosFuncaoGer7 { + Venda venda = new Venda(); + venda.setType = "3"; + venda.setId = new Random().nextInt(9999999).toString(); + if (this.getImpressaoHabilitada) { + venda.setReceipt = this._ger7HabilitaImpressao; + } else { + venda.setReceipt = this._ger7DesabilitaImpressao; + } + venda.setApiversion = this._ger7ApiVersion; + String json = jsonEncode(venda.toJson()); + return json; + } + + // Realiza a formatação para realização de venda Ger7. + // + // Retorna um json, que vai ser enviado para a Tef Ger 7. + String get _formatarPametrosVendaGer7 { + Venda venda = new Venda(); + venda.setType = "1"; + venda.setId = new Random().nextInt(9999999).toString(); + venda.setAmount = this.getValorVenda.toString(); + if (this._tipoPagamento == "Debito") { + venda.setInstmode = this._ger7SemParcelamento; + } else { + venda.setInstallments = this.getQuantParcelas.toString(); + if (venda.getInstallments == "0" || venda.getInstallments == "1") { + venda.setInstmode = this._ger7SemParcelamento; + } else if (this.getTipoParcelamento == "Loja") { + venda.setInstmode = this._ger7ParcelaDoLoja; + } else if (this.getTipoParcelamento == "Adm") { + venda.setInstmode = this._ger7ParcelaDoAdm; + } + } + + venda.setProduct = this.getTipoPagamento[0]; + + if (this.getImpressaoHabilitada) { + venda.setReceipt = this._ger7HabilitaImpressao; + } else { + venda.setReceipt = this._ger7DesabilitaImpressao; + } + venda.setApiversion = this._ger7ApiVersion; + String json = jsonEncode(venda.toJson()); + return json; + } + + /// Realiza a formatação para cancelamento da nota emitida. + /// + /// Retorna um json, que vai ser enviado para a Tef Ger 7. + String get _formatarPametrosCancelamentoGer7 { + Venda venda = new Venda(); + venda.setType = "2"; + venda.setId = new Random().nextInt(9999999).toString(); + venda.setApiversion = this._ger7ApiVersion; + if (this.getImpressaoHabilitada) { + venda.setReceipt = this._ger7HabilitaImpressao; + } else { + venda.setReceipt = this._ger7DesabilitaImpressao; + } + String json = jsonEncode(venda.toJson()); + return json; + } + + /// Realiza a formatação para realização de venda MsiTef. + /// + /// Retorna um json, que vai ser enviado para a Tef MsiTef. + Map get _formatarPametrosVendaMsiTef { + Map mapMsiTef = Map(); + mapMsiTef["empresaSitef"] = "00000000"; + mapMsiTef["enderecoSitef"] = this.getIpConfig; + mapMsiTef["operador"] = "0001"; + mapMsiTef["data"] = "20200324"; + mapMsiTef["hora"] = "130358"; + mapMsiTef["numeroCupom"] = new Random().nextInt(9999999).toString(); + mapMsiTef["valor"] = this.getValorVenda; + mapMsiTef["CNPJ_CPF"] = "03654119000176"; + mapMsiTef["comExterna"] = "0"; + mapMsiTef["modalidade"] = this.getTipoPagamento[1]; + if (this.getTipoPagamento[1] == "3") { + if (this.getQuantParcelas == 1 || this.getQuantParcelas == 0) { + mapMsiTef["transacoesHabilitadas"] = "26"; + mapMsiTef["numParcelas"] = null; + } else if (this.getTipoParcelamento == "Loja") { + mapMsiTef["transacoesHabilitadas"] = "27"; + } else if (this.getTipoParcelamento == "Adm") { + mapMsiTef["transacoesHabilitadas"] = "28"; + } + mapMsiTef["numParcelas"] = this.getQuantParcelas.toString(); + } + if (this.getTipoPagamento[1] == "2") { + mapMsiTef["transacoesHabilitadas"] = "16"; + mapMsiTef["numParcelas"] = null; + } + if (this.getTipoPagamento[1] == "0") { + mapMsiTef["restricoes"] = "transacoesHabilitadas=16"; + mapMsiTef["transacoesHabilitadas"] = null; + mapMsiTef["numParcelas"] = null; + } + mapMsiTef["isDoubleValidation"] = "0"; + mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; + // ** Removida esta opção v3.70 Sitef ** + + // if (this.getImpressaoHabilitada) { + // mapMsiTef["comprovante"] = "1"; + // } else { + // mapMsiTef["comprovante"] = "0"; + // } + return mapMsiTef; + } + + ///Realiza a formatação para realização de cancelamento MsiTef. + /// + /// Retorna um map , que vai ser enviado para a MsiTef. + Map get _formatarPametrosCancelamentoMsiTef { + Map mapMsiTef = Map(); + mapMsiTef["empresaSitef"] = "00000000"; + mapMsiTef["enderecoSitef"] = this.getIpConfig; + mapMsiTef["operador"] = "0001"; + mapMsiTef["data"] = "20200324"; + mapMsiTef["hora"] = "130358"; + mapMsiTef["numeroCupom"] = new Random().nextInt(9999999).toString(); + mapMsiTef["valor"] = this.getValorVenda; + mapMsiTef["CNPJ_CPF"] = "03654119000176"; + mapMsiTef["comExterna"] = "0"; + mapMsiTef["modalidade"] = "200"; + mapMsiTef["isDoubleValidation"] = "0"; + mapMsiTef["restricoes"] = null; + mapMsiTef["transacoesHabilitadas"] = null; + mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; + // ** Removida esta opção v3.70 Sitef ** + + // if (this.getImpressaoHabilitada) { + // mapMsiTef["comprovante"] = "1"; + // } else { + // mapMsiTef["comprovante"] = "0"; + // } + return mapMsiTef; + } + + /// Realiza a formatação para realização de configuração de funções MsiTef. + /// + /// Retorna um map , que vai ser enviado para a Tef Ger 7. + Map get _formatarPametrosFuncoesMsiTef { + Map mapMsiTef = Map(); + mapMsiTef["empresaSitef"] = "00000000"; + mapMsiTef["enderecoSitef"] = this.getIpConfig; + mapMsiTef["operador"] = "0001"; + mapMsiTef["data"] = "20200324"; + mapMsiTef["hora"] = "130358"; + mapMsiTef["numeroCupom"] = new Random().nextInt(9999999).toString(); + mapMsiTef["valor"] = this.getValorVenda; + mapMsiTef["CNPJ_CPF"] = "03654119000176"; + mapMsiTef["comExterna"] = "0"; + mapMsiTef["modalidade"] = "110"; + mapMsiTef["isDoubleValidation"] = "0"; + mapMsiTef["restricoes"] = null; + mapMsiTef["transacoesHabilitadas"] = null; + mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; + mapMsiTef["restricoes"] = "transacoesHabilitadas=16;26;27"; + // ** Removida esta opção v3.70 Sitef ** + + // if (this.getImpressaoHabilitada) { + // mapMsiTef["comprovante"] = "1"; + // } else { + // mapMsiTef["comprovante"] = "0"; + // } + return mapMsiTef; + } + + /// Realiza a formatação para realização de reimpressão MsiTef. + /// + /// Retorna um map , que vai ser enviado para a Tef Ger + Map get _formatarPametrosReimpressaoMsiTef { + Map mapMsiTef = Map(); + mapMsiTef["empresaSitef"] = "00000000"; + mapMsiTef["enderecoSitef"] = this.getIpConfig; + mapMsiTef["operador"] = "0001"; + mapMsiTef["data"] = "20200324"; + mapMsiTef["hora"] = "130358"; + mapMsiTef["numeroCupom"] = new Random().nextInt(9999999).toString(); + mapMsiTef["valor"] = this.getValorVenda; + mapMsiTef["CNPJ_CPF"] = "03654119000176"; + mapMsiTef["comExterna"] = "0"; + mapMsiTef["modalidade"] = "114"; + mapMsiTef["isDoubleValidation"] = "0"; + mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; + // ** Removida esta opção v3.70 ** + + // if (this.getImpressaoHabilitada) { + // mapMsiTef["comprovante"] = "1"; + // } else { + // mapMsiTef["comprovante"] = "0"; + // } + return mapMsiTef; + } + + // Realiza as funções da Tef, tem como retorno um objeto dynamic que pode ser atributi a [RetornoMsiTef] ou [RetornoGer7] + // Recebe como parâmetros uma String que está relacionada a ação que deseja ser invocada e uma String relacionado a tef utilizada (ger7,msitef) + // As ações possiveis são: venda, cancelamento, reimpressao, funcoes (Os valores devem ser escritos exatamente como o demonstrado) + Future enviarParametrosTef({@required String tipoAcao, @required String tipoTef}) async { + var retornoTef; + var myjson; + var parametroFormatado; + // Verificando qual foi a tef selecionada, dependendo da Tef os seus parâmetros são formatados; + if (tipoTef == "ger7") { + switch (tipoAcao) { + case "venda": + parametroFormatado = _formatarPametrosVendaGer7; + break; + case "cancelamento": + parametroFormatado = _formatarPametrosCancelamentoGer7; + break; + case "funcoes": + parametroFormatado = _formatarPametrosFuncaoGer7; + break; + case "reimpressao": + parametroFormatado = _formatarPametrosReimpressaoGer7; + break; + } + myjson = await _platform.invokeMethod( + 'realizarAcaoGer7', + {"json": parametroFormatado}, + ); + retornoTef = RetornoGer7.fromJson(_formatarInfoRecebida(myjson)); + } else { + // Caso não for Ger7, então M-Sitef + switch (tipoAcao) { + case "venda": + parametroFormatado = _formatarPametrosVendaMsiTef; + break; + case "cancelamento": + parametroFormatado = _formatarPametrosCancelamentoMsiTef; + break; + case "funcoes": + parametroFormatado = _formatarPametrosFuncoesMsiTef; + break; + case "reimpressao": + parametroFormatado = _formatarPametrosReimpressaoMsiTef; + break; + } + myjson = await _platform.invokeMethod( + 'realizarAcaoMsitef', + {"mapMsiTef": parametroFormatado}, + ); + retornoTef = RetornoMsiTef.fromJson(_formatarInfoRecebida(myjson)); + } + return retornoTef; + } +} diff --git a/GPOS 700/lib/util/common_code.dart b/GPOS 700/lib/util/common_code.dart new file mode 100644 index 0000000..be07eb8 --- /dev/null +++ b/GPOS 700/lib/util/common_code.dart @@ -0,0 +1,20 @@ +//* Classe que possui partes de código comuns em diversas telas +class CommonGertec { + CommonGertec(); + final int maxLength = 32; // Armazena o tamanho maximo do códig de validação + final int minLength = 8; // Armazena o tamanho minimo do códig de validação + + // Verifica se o código de validação do Sat inserido pelo usuario é valido + // ? Está função foi desenvolvida para minimizar a repetição de código + bool isCodigoValido(String codigo) { + if (codigo.length >= this.minLength && codigo.length <= this.maxLength) { + return true; + } + return false; + } + + // Remove a mascara do CNPJ + String removeMaskCnpj(String cnpjInput) { + return cnpjInput.toString().replaceAll(".", "").replaceAll("/", "").replaceAll("-", ""); + } +} diff --git a/GPOS 700/lib/widgets/widgetsgertec.dart b/GPOS 700/lib/widgets/widgetsgertec.dart new file mode 100644 index 0000000..024659e --- /dev/null +++ b/GPOS 700/lib/widgets/widgetsgertec.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +class WidgetsGertec extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container(); + } + + // Botão padrão, recebe como parâmetro uma string('texto') e a função que vai ser chamada ao pressionar o botão('voidCallback') + static Widget buttonStandard(String text, {VoidCallback callback}) { + return SizedBox( + width: 240, + child: RaisedButton( + child: Text(text), + onPressed: callback, + ), + ); + } + + // Dialogo que ira aparecer após a função Sat ser iniciada e ocorrer algum erro ou tudo ocorrer certo + static void dialogoSat(String messageText, {@required BuildContext context, double heightDialog = 100}) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Retorno"), + content: Container( + height: heightDialog, + child: ListView( + children: [ + Text(messageText), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + static Widget formField(TextEditingController textFormField, String textAntesForm, {TextInputType textInputType}) { + return Padding( + padding: const EdgeInsets.only(left: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + textAntesForm, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 30, + width: 140, + child: TextFormField( + keyboardType: textInputType, + controller: textFormField, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ); + } +} diff --git a/GPOS 700/pubspec.lock b/GPOS 700/pubspec.lock index b1aabc3..ec8bc96 100644 --- a/GPOS 700/pubspec.lock +++ b/GPOS 700/pubspec.lock @@ -1,27 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "2.4.2" auto_size_text: dependency: "direct main" description: @@ -35,35 +21,35 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" - charcode: + version: "2.0.0" + characters: dependency: transitive description: - name: charcode + name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" - collection: + version: "1.0.0" + charcode: dependency: transitive description: - name: collection + name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" - convert: + version: "1.1.3" + clock: dependency: transitive description: - name: convert + name: clock url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" - crypto: + version: "1.0.1" + collection: dependency: transitive description: - name: crypto + name: collection url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "1.14.13" cupertino_icons: dependency: "direct main" description: @@ -71,11 +57,25 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_masked_text: + dependency: "direct main" + description: + name: flutter_masked_text + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.0" flutter_screenutil: dependency: "direct main" description: @@ -88,20 +88,13 @@ packages: description: flutter source: sdk version: "0.0.0" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.8" meta: dependency: transitive description: @@ -115,28 +108,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" + version: "1.7.0" sky_engine: dependency: transitive description: flutter @@ -148,14 +120,14 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.7.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.9.5" stream_channel: dependency: transitive description: @@ -183,14 +155,14 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.11" + version: "0.2.17" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.2.0" vector_math: dependency: transitive description: @@ -198,12 +170,5 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.0" sdks: - dart: ">=2.4.0 <3.0.0" + dart: ">=2.9.0-14.0.dev <3.0.0" diff --git a/GPOS 700/pubspec.yaml b/GPOS 700/pubspec.yaml index ad5f0a3..12fd301 100644 --- a/GPOS 700/pubspec.yaml +++ b/GPOS 700/pubspec.yaml @@ -1,16 +1,6 @@ name: flutter_gertec description: A new Flutter project. -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html version: 1.0.0+1 environment: @@ -21,61 +11,17 @@ dependencies: sdk: flutter flutter_screenutil: ^0.5.2 auto_size_text: ^2.1.0 - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. + flutter_masked_text: ^0.8.0 cupertino_icons: ^0.1.2 dev_dependencies: flutter_test: sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: assets: - - assets/barcode.png - - assets/nfc.png - - assets/gertec.png - - assets/nfc1.png - - assets/print.png - - assets/qr_code.png - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages + - assets/ + - assets/xmlSat/arq_cancelamento.xml + - assets/xmlSat/arq_venda_008_Simples_Nacional.xml - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages + uses-material-design: true \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c8b0af5 --- /dev/null +++ b/README.md @@ -0,0 +1,90 @@ +[![](https://pbs.twimg.com/media/EKzBdw7WwAQrq8J.png)](https://www.gertec.com.br/) + +# Prezados e parceiros e escovadores de Bits!! + +Obrigado por acessarem nosso github!! + +Nestes code samples, você encontra exemplos de integração com os terminais Gertec GPOS700 e TSG800 em diversas linguagens tais como Java, Delphi, Flutter, React-Native, Ionic, Xamarin-Android e Xamarin-Forms! + +Seja capaz de executar em curto período de tempo as diversas funcionalidades para seu aplicativo: + + - Impressão + - Código de Barras + - Leitura de Cartão NFC + - Integração com TEF Sw Express e Ger7 + +# Gertec Developer +Quero fazer parte da Comunidade e receber informações. +Está bem fácil. + +[Cadastre-se aqui]( https://www.gertec.com.br/login/software-house/cadastro/) + +# GPOS700, TSG800, MP5 +GPOS700 é o POS com PCI e que permite você desenvolver um aplicativo Android nele e colocar a solução de cartão de credito também dentro dele. + +O TSG800 é um terminal sem pagamento, um Smart Printer, mas você pode usar uma “moderninha” e parear a “moderninha” com ele por Bluetooth e fazer o pagamento. + +MP5 em breve teremos novidades sobre este Pinpad Bluetooth para você desenvolver pareando com o celular ou com o TSG800 + +Em nosso site você pode ter acesso a mais informações, seguem links: + +**G700** https://www.gertec.com.br/produtos/gpos700/ + +**G800** https://www.gertec.com.br/produtos/tsg800/ + +**MP5** https://www.gertec.com.br/produtos/mp5/ + +# PILOTO MP5 +Desejo participar o Piloto com o Pinpad Bluetooth MP5, como fazer? Super simples, me envie um e-mail com seu nome e telefone para **claudenir.andrade@gertec.com.br** com o título **“Piloto MP5”**. + +Assim que tivemos disponível peças para desenvolvedor a preço reduzido e funcionando com a SwExpress e Multi-Chave, vamos te enviar a informação. + +# Desejo adquirir o equipamento para meu desenvolvimento +A MP5 (Pinpad Bluetooth) ainda não está disponível pra desenvolvedor, em breve estará, sem dúvida e 100% integrado com a SwExpress. + +O GPOS700 para Desenvolvedor o valor e de R$1.099,00 em até 5x no cartão ou 28Dias no boleto. + +Como adquirir? + 1. Preencha esta planilha em anexo com os dados de sua empresa + 2. pode me enviar Claudenir.andrade@gertec.com.br + +O TSG800 você pode adquirir direto de nosso e-commerce com uma promoção para Desenvolvedor + +[Click aqui adquirir um TSG 800]( +https://loja.gertec.com.br/produto/terminal-smart-g800-para-desenvolvimento/) + +Código de Promoção : **TSG800DEV** + +Aplicando o código acima o preço fica em 999,00 Até 12X no Cartão + +# GITHUB e VIDEOS +Nosso GitHub: [Gertec Developer](https://github.com/gertecdeveloper) + +Nosso Canal de vídeos: [Gertec Developer YouTube](https://www.youtube.com/gertecdeveloper) + - [Video **“Out-Of-box”** do TSG800 e GPOS700]( https://www.youtube.com/watch?v=bW101g2mSgI&t=0s) + - [Playlist completa](https://www.youtube.com/c/GertecDeveloper/videos) + +# TEF no GPOS (MSITEF ou GER7 com GPOS700). +Para saber o preço e a modalidade comercial pra uso do TEF SwExpress ou Ger7 com o GPOS700, favor tratar com + + - **Wilmar Poli** wilmar.poli@gertec.com.br Celular 011 98833 6696 + + +## Software Express +Para ter acesso a documentação, Simuladores e Roteiros de homologação, favor entrar em contato com: + +#### **Fernanda Ramos** +fernanda.ramos@softwareexpress.com.br + +#### **Ger7** + +Para ter acesso a documentação, Simuladores e Roteiros de homologação, favor se cadastrarem no seguinte link: + +https://integracao.ger7.com.br/ + +Fiquem com meu contato, estou a inteira disposição + +#### **Claudenir Andrade** +011 9 8137 0262 + +claudenir.andrade@gertec.com.br. \ No newline at end of file diff --git a/TSG 800/README.md b/TSG 800/README.md index 03c6a7a..c8b0af5 100644 --- a/TSG 800/README.md +++ b/TSG 800/README.md @@ -1,2 +1,90 @@ -Projeto -Flutter para GPOS Smart 800 +[![](https://pbs.twimg.com/media/EKzBdw7WwAQrq8J.png)](https://www.gertec.com.br/) + +# Prezados e parceiros e escovadores de Bits!! + +Obrigado por acessarem nosso github!! + +Nestes code samples, você encontra exemplos de integração com os terminais Gertec GPOS700 e TSG800 em diversas linguagens tais como Java, Delphi, Flutter, React-Native, Ionic, Xamarin-Android e Xamarin-Forms! + +Seja capaz de executar em curto período de tempo as diversas funcionalidades para seu aplicativo: + + - Impressão + - Código de Barras + - Leitura de Cartão NFC + - Integração com TEF Sw Express e Ger7 + +# Gertec Developer +Quero fazer parte da Comunidade e receber informações. +Está bem fácil. + +[Cadastre-se aqui]( https://www.gertec.com.br/login/software-house/cadastro/) + +# GPOS700, TSG800, MP5 +GPOS700 é o POS com PCI e que permite você desenvolver um aplicativo Android nele e colocar a solução de cartão de credito também dentro dele. + +O TSG800 é um terminal sem pagamento, um Smart Printer, mas você pode usar uma “moderninha” e parear a “moderninha” com ele por Bluetooth e fazer o pagamento. + +MP5 em breve teremos novidades sobre este Pinpad Bluetooth para você desenvolver pareando com o celular ou com o TSG800 + +Em nosso site você pode ter acesso a mais informações, seguem links: + +**G700** https://www.gertec.com.br/produtos/gpos700/ + +**G800** https://www.gertec.com.br/produtos/tsg800/ + +**MP5** https://www.gertec.com.br/produtos/mp5/ + +# PILOTO MP5 +Desejo participar o Piloto com o Pinpad Bluetooth MP5, como fazer? Super simples, me envie um e-mail com seu nome e telefone para **claudenir.andrade@gertec.com.br** com o título **“Piloto MP5”**. + +Assim que tivemos disponível peças para desenvolvedor a preço reduzido e funcionando com a SwExpress e Multi-Chave, vamos te enviar a informação. + +# Desejo adquirir o equipamento para meu desenvolvimento +A MP5 (Pinpad Bluetooth) ainda não está disponível pra desenvolvedor, em breve estará, sem dúvida e 100% integrado com a SwExpress. + +O GPOS700 para Desenvolvedor o valor e de R$1.099,00 em até 5x no cartão ou 28Dias no boleto. + +Como adquirir? + 1. Preencha esta planilha em anexo com os dados de sua empresa + 2. pode me enviar Claudenir.andrade@gertec.com.br + +O TSG800 você pode adquirir direto de nosso e-commerce com uma promoção para Desenvolvedor + +[Click aqui adquirir um TSG 800]( +https://loja.gertec.com.br/produto/terminal-smart-g800-para-desenvolvimento/) + +Código de Promoção : **TSG800DEV** + +Aplicando o código acima o preço fica em 999,00 Até 12X no Cartão + +# GITHUB e VIDEOS +Nosso GitHub: [Gertec Developer](https://github.com/gertecdeveloper) + +Nosso Canal de vídeos: [Gertec Developer YouTube](https://www.youtube.com/gertecdeveloper) + - [Video **“Out-Of-box”** do TSG800 e GPOS700]( https://www.youtube.com/watch?v=bW101g2mSgI&t=0s) + - [Playlist completa](https://www.youtube.com/c/GertecDeveloper/videos) + +# TEF no GPOS (MSITEF ou GER7 com GPOS700). +Para saber o preço e a modalidade comercial pra uso do TEF SwExpress ou Ger7 com o GPOS700, favor tratar com + + - **Wilmar Poli** wilmar.poli@gertec.com.br Celular 011 98833 6696 + + +## Software Express +Para ter acesso a documentação, Simuladores e Roteiros de homologação, favor entrar em contato com: + +#### **Fernanda Ramos** +fernanda.ramos@softwareexpress.com.br + +#### **Ger7** + +Para ter acesso a documentação, Simuladores e Roteiros de homologação, favor se cadastrarem no seguinte link: + +https://integracao.ger7.com.br/ + +Fiquem com meu contato, estou a inteira disposição + +#### **Claudenir Andrade** +011 9 8137 0262 + +claudenir.andrade@gertec.com.br. \ No newline at end of file diff --git a/TSG 800/android/.settings/org.eclipse.buildship.core.prefs b/TSG 800/android/.settings/org.eclipse.buildship.core.prefs index e889521..27b37ed 100644 --- a/TSG 800/android/.settings/org.eclipse.buildship.core.prefs +++ b/TSG 800/android/.settings/org.eclipse.buildship.core.prefs @@ -1,2 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= eclipse.preferences.version=1 +gradle.user.home= +java.home=C\:/Program Files/Java/jdk-11.0.8 +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/TSG 800/android/app/.classpath b/TSG 800/android/app/.classpath index eb19361..4a04201 100644 --- a/TSG 800/android/app/.classpath +++ b/TSG 800/android/app/.classpath @@ -1,6 +1,6 @@ - + diff --git a/TSG 800/android/app/.settings/org.eclipse.buildship.core.prefs b/TSG 800/android/app/.settings/org.eclipse.buildship.core.prefs index b1886ad..c304bf6 100644 --- a/TSG 800/android/app/.settings/org.eclipse.buildship.core.prefs +++ b/TSG 800/android/app/.settings/org.eclipse.buildship.core.prefs @@ -1,2 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.3)) connection.project.dir=.. eclipse.preferences.version=1 +gradle.user.home= +java.home=C\:/Program Files/Java/jdk1.8.0_241 +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/TSG 800/android/app/build.gradle b/TSG 800/android/app/build.gradle index 10de0ef..9bafc1b 100644 --- a/TSG 800/android/app/build.gradle +++ b/TSG 800/android/app/build.gradle @@ -32,9 +32,8 @@ android { } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.flutter_gertec" - minSdkVersion 20 + minSdkVersion 22 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -49,21 +48,12 @@ android { keyPassword 'Development@GertecDeveloper2018' } } - defaultConfig { - applicationId "com.example.flutter_gertec" - minSdkVersion 20 - targetSdkVersion 28 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - buildTypes { release { - shrinkResources true - minifyEnabled true - multiDexEnabled true + minifyEnabled false + useProguard false + shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.gertec } @@ -71,7 +61,6 @@ android { signingConfig signingConfigs.gertec } } - } flutter { @@ -81,7 +70,7 @@ flutter { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation(name:'libgedi-0.190121.gpos800', ext:'aar') -// implementation(name: 'payment-1.14.10.181016', ext: 'aar') + implementation(name: 'SatGerLib', ext: 'aar') implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' diff --git a/TSG 800/android/app/libs/SatGerLib.aar b/TSG 800/android/app/libs/SatGerLib.aar new file mode 100644 index 0000000..75f1fbc Binary files /dev/null and b/TSG 800/android/app/libs/SatGerLib.aar differ diff --git a/TSG 800/android/app/src/main/AndroidManifest.xml b/TSG 800/android/app/src/main/AndroidManifest.xml index 36e1b1f..d990dbc 100644 --- a/TSG 800/android/app/src/main/AndroidManifest.xml +++ b/TSG 800/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,13 @@ + + + + + @@ -9,11 +15,11 @@ - + android:icon="@mipmap/gertec_one" + android:label="GertecOne Flutter"> @@ -32,9 +38,10 @@ android:windowSoftInputMode="adjustResize"> - + + @@ -46,10 +53,10 @@ - - - - + + + + 0){ + if (linhas > 0) { this.iPrint.DrawBlankLine(linhas); } } catch (GediException e) { @@ -504,10 +506,10 @@ public void avancaLinha(int linhas) throws GediException { * * @return true = quando estiver tudo ok. * - * */ - public boolean isImpressoraOK(){ + */ + public boolean isImpressoraOK() { - if( status.getValue() == 0 ){ + if (status.getValue() == 0) { return true; } return false; @@ -518,10 +520,10 @@ public boolean isImpressoraOK(){ * * @throws GediException = retorno o código do erro. * - * */ + */ public void ImpressoraInit() throws GediException { try { - if( this.iPrint != null && !isPrintInit ){ + if (this.iPrint != null && !isPrintInit) { this.iPrint.Init(); isPrintInit = true; } @@ -530,15 +532,16 @@ public void ImpressoraInit() throws GediException { throw new GediException(e.getErrorCode()); } } + /** * Método que faz a finalizacao do objeto iPrint * * @throws GediException = retorno o código do erro. * - * */ + */ public void ImpressoraOutput() throws GediException { try { - if( this.iPrint != null ){ + if (this.iPrint != null) { this.iPrint.Output(); isPrintInit = false; } @@ -555,7 +558,7 @@ public void ImpressoraOutput() throws GediException { * * @return String = Retorno o atual status da impressora * - * */ + */ private String traduzStatusImpressora(GEDI_PRNTR_e_Status status) { String retorno; switch (status) { diff --git a/TSG 800/android/app/src/main/java/com/example/flutter_gertec/MainActivity.java b/TSG 800/android/app/src/main/java/com/example/flutter_gertec/MainActivity.java index edb7c82..0334ec7 100644 --- a/TSG 800/android/app/src/main/java/com/example/flutter_gertec/MainActivity.java +++ b/TSG 800/android/app/src/main/java/com/example/flutter_gertec/MainActivity.java @@ -1,10 +1,10 @@ package com.example.flutter_gertec; import android.content.Intent; -import android.nfc.Tag; -import android.os.Build; import android.os.Bundle; import android.os.PersistableBundle; + +import java.io.IOException; import java.util.List; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -21,27 +21,33 @@ public class MainActivity extends FlutterActivity { private GertecPrinter gertecPrinter; - public static final String G700 = "GPOS700"; - public static final String G800 = "Smart G800"; - private static final String version = "RC03"; - private MethodChannel.Result _result; // private NfcAdapter nfcAdapter; - public static String Model = Build.MODEL; - private String resultado_Leitor; + private MethodChannel.Result _result; // Instanciando uma variavel do tipo Result, para enviar o resultado para o + // flutter + private String resultado_Leitor; // Instanciando uma variavel que vai armazenar o resultado ao ler o codigo de + // Barras no V1 private IntentIntegrator qrScan; - private String tipo; + private String tipo; // Armazerna o tipo de codigo de barra que deseja ser lido private ArrayList arrayListTipo; - private static final String[] CHANNEL = { "samples.flutter.dev/gedi" }; + private static final String[] CHANNEL = { "samples.flutter.dev/gedi" }; // Canal de comunicação do flutter com o + // Java private ConfigPrint configPrint = new ConfigPrint(); + private SatLib satLib; + public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); gertecPrinter.setConfigImpressao(configPrint); } + @Override + protected void onResume() { + super.onResume(); + gertecPrinter = new GertecPrinter(this.getActivity()); + satLib = new SatLib(this); + } + public MainActivity() { super(); this.arrayListTipo = new ArrayList(); - System.out.println("GPOS800"); - gertecPrinter = new GertecPrinter(this.getActivity()); } public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { @@ -49,28 +55,32 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL[0]) .setMethodCallHandler((call, result) -> { _result = result; - Intent intent = null; + Intent intent; switch (call.method) { + // Inicia o intent que vai fazer a leitura do Nfc case "lerNfc": try { intent = new Intent(this, NfcLeitura.class); - startActivity(intent); + startActivityForResult(intent, 111); } catch (Exception e) { e.printStackTrace(); result.notImplemented(); } break; + // Inicia o intent que vai fazer a gravação no Cartão + // A mensagem que vai ser gravada é enviada do flutter case "gravarNfc": String mensagemGravar = call.argument("mensagemGravar"); try { intent = new Intent(this, NfcGravacao.class); - intent.putExtra("mensagemGravar",mensagemGravar); + intent.putExtra("mensagemGravar", mensagemGravar); startActivity(intent); } catch (Exception e) { e.printStackTrace(); result.notImplemented(); } break; + // Inicia o intent que vai fazer a formatação do cartão Nfc case "formatarNfc": try { intent = new Intent(this, NfcFormatar.class); @@ -80,6 +90,7 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { result.notImplemented(); } break; + // Inicia o intent que vai fazer o teste de leitura e gravação no cartão Nfc case "testeNfc": try { intent = new Intent(this, NfcLerGravar.class); @@ -97,6 +108,8 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { e.printStackTrace(); } break; + // Inicia a função que vai abrir o leitor de codigo de barra + // Do flutter ele vai pegar o "tipo" de codigo que deseja ser lido case "leitorCodigov1": try { tipo = call.argument("tipoLeitura"); @@ -105,10 +118,90 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { e.printStackTrace(); } break; + // Verifica qual ação do Sat foi solicitada e retorna o codigo de resposta da + // Sefaz + // "satLib" possui todas funções do Sat + + case "AtivarSAT": + _result.success(satLib.ativarSat(call.argument("codigoAtivar"), call.argument("cnpj"), + call.argument("random"))); + break; + case "AssociarSAT": + _result.success(satLib.associarSat(call.argument("cnpj"), call.argument("cnpjSoft"), + call.argument("codigoAtivar"), call.argument("assinatura"), + call.argument("random"))); + break; + case "ConsultarSat": + _result.success(satLib.consultarSat(call.argument("random"))); + break; + case "ConsultarStatusOperacional": + String a = call.argument("codigoAtivar"); + int b = call.argument("random"); + _result.success(satLib.consultarStatusOperacional(call.argument("random"), + call.argument("codigoAtivar"))); + break; + case "EnviarTesteFim": + _result.success(satLib.enviarTesteFim(call.argument("codigoAtivar"), + call.argument("xmlVenda"), call.argument("random"))); + break; + case "EnviarTesteVendas": + _result.success(satLib.enviarTesteVendas(call.argument("codigoAtivar"), + call.argument("xmlVenda"), call.argument("random"))); + break; + case "CancelarUltimaVenda": + _result.success(satLib.cancelarUltimaVenda(call.argument("codigoAtivar"), + call.argument("xmlCancelamento"), call.argument("chaveCancelamento"), + call.argument("random"))); + break; + case "ConsultarNumeroSessao": + _result.success(satLib.consultarNumeroSessao(call.argument("codigoAtivar"), + call.argument("chaveSessao"), call.argument("random"))); + break; + case "EnviarConfRede": + try { + _result.success(satLib.enviarConfRede(call.argument("random"), + call.argument("dadosXml"), call.argument("codigoAtivar"))); + } catch (IOException e) { + e.printStackTrace(); + } + break; + case "TrocarCodAtivacao": + _result.success(satLib.trocarCodAtivacao(call.argument("codigoAtivar"), call.argument("op"), + call.argument("codigoAtivacaoNovo"), call.argument("random"))); + break; + case "BloquearSat": + _result.success(satLib.bloquearSat(call.argument("codigoAtivar"), call.argument("random"))); + break; + case "DesbloquearSat": + _result.success( + satLib.desbloquearSat(call.argument("codigoAtivar"), call.argument("random"))); + break; + case "ExtrairLog": + _result.success(satLib.extrairLog(call.argument("codigoAtivar"), call.argument("random"))); + break; + case "AtualizarSoftware": + _result.success( + satLib.atualizarSoftware(call.argument("codigoAtivar"), call.argument("random"))); + break; + case "Versao": + _result.success(satLib.versao()); + break; + // Inicia o intent que vai fazer a leitura do codigo de barras v2 + // Ler qualquer tipo de codigo de barra case "leitorCodigoV2": intent = new Intent(this, CodigoBarrasV2.class); startActivity(intent); break; + // Esta função vai chamar as classes para realizar as impressões de acordo com + // as configurações recebidas do flutter + case "fimimpressao": + try { + gertecPrinter.ImpressoraOutput(); + result.success("Finalizou impressao"); + } catch (GediException e) { + e.printStackTrace(); + } + break; case "imprimir": configPrint = new ConfigPrint(); try { @@ -141,16 +234,15 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { String barCode = call.argument("barCode"); configPrint.setAlinhamento("CENTER"); gertecPrinter.setConfigImpressao(configPrint); - gertecPrinter.imprimeBarCodeIMG(mensagem,height,width,barCode); + gertecPrinter.imprimeBarCodeIMG(mensagem, height, width, barCode); break; case "TodasFuncoes": ImprimeTodasAsFucoes(); break; } - gertecPrinter.avancaLinha(200); - gertecPrinter.ImpressoraOutput(); + gertecPrinter.avancaLinha(40); } - }catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); } break; @@ -158,10 +250,10 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { }); } - private void startCamera(){ + private void startCamera() { this.arrayListTipo.add(tipo); qrScan = new IntentIntegrator(this); - qrScan.setPrompt("Digitalizar o código " + tipo ); + qrScan.setPrompt("Digitalizar o código " + tipo); qrScan.setBeepEnabled(true); qrScan.setBarcodeImageEnabled(true); qrScan.setTimeout(30000); // 30 * 1000 => 3 minuto @@ -307,7 +399,7 @@ private void ImprimeTodasAsFucoes(){ gertecPrinter.imprimeTexto("===[Codigo QrCode Gertec IMG]=="); gertecPrinter.imprimeBarCodeIMG("Gertec Developer Partner IMG", 240,240,"QR_CODE"); - gertecPrinter.avancaLinha(100); + gertecPrinter.avancaLinha(40); } catch (Exception e) { e.printStackTrace(); @@ -320,38 +412,32 @@ private void ImprimeTodasAsFucoes(){ } } - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - if (requestCode == 109) { - if (resultCode == RESULT_OK && data != null) { - _result.success(data.getStringExtra("codigoNFCID")); - } else { - _result.notImplemented(); - } - } else if (requestCode == 108) { + public void onActivityResult(int requestCode, int resultCode, Intent data) { + // Pega os resultados obtidos dos intent e envia para o flutter + // ("_result.success") + if (requestCode == 111) { if (resultCode == RESULT_OK && data != null) { - _result.success(data.getStringExtra("codigoNFCGEDI")); + _result.success(data.getStringExtra("mensagemLeitura")); } else { _result.notImplemented(); } } else { IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if (intentResult != null) { - //if qrcode has nothing in it + // if qrcode has nothing in it if (intentResult.getContents() == null) { - // Toast.makeText(this, "Result Not Found", Toast.LENGTH_LONG).show(); - resultado_Leitor = (this.tipo +": Não foi possível ler o código.\n"); + resultado_Leitor = (this.tipo + ": Não foi possível ler o código.\n"); } else { - //if qr contains data + // if qr contains data try { - resultado_Leitor = this.tipo + ": " + intentResult.getContents() + "\n"; + resultado_Leitor = this.tipo + ": " + intentResult.getContents() + "\n"; } catch (Exception e) { e.printStackTrace(); - resultado_Leitor = this.tipo +": Erro " + e.getMessage() + "\n"; + resultado_Leitor = this.tipo + ": Erro " + e.getMessage() + "\n"; } } } else { - super.onActivityResult(requestCode, resultCode, data); - resultado_Leitor = this.tipo +": Não foi possível fazer a leitura.\n"; + resultado_Leitor = this.tipo + ": Não foi possível fazer a leitura.\n"; } _result.success(resultado_Leitor); this.arrayListTipo.clear(); diff --git a/TSG 800/android/app/src/main/java/com/example/flutter_gertec/NfcFormatar.java b/TSG 800/android/app/src/main/java/com/example/flutter_gertec/NfcFormatar.java index 900363f..943eb9b 100644 --- a/TSG 800/android/app/src/main/java/com/example/flutter_gertec/NfcFormatar.java +++ b/TSG 800/android/app/src/main/java/com/example/flutter_gertec/NfcFormatar.java @@ -1,4 +1,5 @@ package com.example.flutter_gertec; + import android.app.PendingIntent; import android.content.Intent; import android.content.IntentFilter; @@ -33,12 +34,11 @@ protected void onCreate(Bundle savedInstanceState) { initNFC(); } - private void initNFC(){ + private void initNFC() { mNfcAdapter = NfcAdapter.getDefaultAdapter(this); // nfcManager = new NfcManager(this); } - @Override protected void onResume() { super.onResume(); @@ -46,18 +46,18 @@ protected void onResume() { IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); IntentFilter techDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); IntentFilter idDetected = new IntentFilter((NfcAdapter.EXTRA_ID)); - IntentFilter[] nfcIntentFilter = new IntentFilter[]{techDetected,tagDetected,ndefDetected, idDetected}; + IntentFilter[] nfcIntentFilter = new IntentFilter[] { techDetected, tagDetected, ndefDetected, idDetected }; - PendingIntent pendingIntent = PendingIntent.getActivity( - this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); - if(mNfcAdapter!= null) + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, + new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); + if (mNfcAdapter != null) mNfcAdapter.enableForegroundDispatch(this, pendingIntent, nfcIntentFilter, null); } @Override protected void onPause() { super.onPause(); - if(mNfcAdapter!= null) + if (mNfcAdapter != null) mNfcAdapter.disableForegroundDispatch(this); } @@ -72,14 +72,15 @@ protected void onNewIntent(Intent intent) { Ndef ndef = Ndef.get(tag); - if(ndef == null){ + if (ndef == null) { Toast.makeText(getApplicationContext(), "Tipo de cartão não suportado.", Toast.LENGTH_SHORT).show(); - }else { + } else { nfcLeituraGravacao = new NfcLeituraGravacao(ndef.getTag()); formatFromNFC(ndef); } } } + private void formatFromNFC(Ndef ndef) { boolean retorno; @@ -88,9 +89,9 @@ private void formatFromNFC(Ndef ndef) { retorno = nfcLeituraGravacao.formataCartao(ndef); - if (retorno){ + if (retorno) { texMensagem.setText("Cartão formatado"); - }else{ + } else { texMensagem.setText("Não é necessário formatar este cartão."); } diff --git a/TSG 800/android/app/src/main/java/com/example/flutter_gertec/NfcLeitura.java b/TSG 800/android/app/src/main/java/com/example/flutter_gertec/NfcLeitura.java index 0ac231b..fb6262d 100644 --- a/TSG 800/android/app/src/main/java/com/example/flutter_gertec/NfcLeitura.java +++ b/TSG 800/android/app/src/main/java/com/example/flutter_gertec/NfcLeitura.java @@ -37,6 +37,7 @@ private void initNFC(){ // nfcManager = new NfcManager(this); } + @Override protected void onResume() { super.onResume(); @@ -59,6 +60,14 @@ protected void onPause() { mNfcAdapter.disableForegroundDispatch(this); } + @Override + protected void onDestroy() { + super.onDestroy(); + Intent intent = new Intent(); + intent.putExtra("mensagemLeitura", mTvMessage.toString()); + setResult(RESULT_OK, intent); + } + @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); @@ -108,4 +117,4 @@ private void readFromNFC(Ndef ndef) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG ).show(); } } -} +} \ No newline at end of file diff --git a/TSG 800/android/app/src/main/java/com/example/flutter_gertec/SatLib.java b/TSG 800/android/app/src/main/java/com/example/flutter_gertec/SatLib.java new file mode 100644 index 0000000..1fbc30d --- /dev/null +++ b/TSG 800/android/app/src/main/java/com/example/flutter_gertec/SatLib.java @@ -0,0 +1,337 @@ +package com.example.flutter_gertec; + +import android.content.Context; +import android.util.Base64; + +import com.phi.gertec.sat.satger.SatGerLib; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +public class SatLib { + public static SatGerLib serialComms; + + private String funcao; + Context context; + private File arquivoXml = new File("mnt/sdcard/Gertec/teste_fim_a_fim.xml"); + private File arquivoXmlVendas = new File("mnt/sdcard/Gertec/EnviarDadosVenda.xml"); + private File arquivoXmlCancelamento = new File("mnt/sdcard/Gertec/CancelarVenda.xml"); + + public SatLib(Context context) { + this.context = context; + serialComms = new SatGerLib(context, dataReceivedListener); // Inicializando + } + + public String enviarConfRede(int random, List dadosXml, String codigoAtivacao) throws IOException { + String packageName = "com.example.flutter_gertec"; + String caminhoXML = "data/data/" + packageName + "/configRede.xml"; + File file = new File(caminhoXML); + // Se o arquivo não existe, então cria + if (!file.exists()) { + file.createNewFile(); + } + // Começa a escrever no arquivo + FileWriter fw = new FileWriter(file.getAbsoluteFile()); + BufferedWriter bw = new BufferedWriter(fw); + bw.write(""); + bw.newLine(); + bw.write(""); + bw.newLine(); + bw.write("ETHE"); + bw.newLine(); + bw.write(dadosXml.get(0)); + bw.newLine(); + + if (!dadosXml.get(1).equals("")) { + bw.write(dadosXml.get(1)); + bw.newLine(); + } + if (!dadosXml.get(2).equals("")) { + bw.write(dadosXml.get(2)); + bw.newLine(); + } + if (!dadosXml.get(3).equals("")) { + bw.write(dadosXml.get(3)); + bw.newLine(); + } + if (!dadosXml.get(4).equals("")) { + bw.write(dadosXml.get(4)); + bw.newLine(); + } + if (!dadosXml.get(5).equals("")) { + bw.write(dadosXml.get(5)); + bw.newLine(); + } + + bw.write(dadosXml.get(6)); + bw.newLine(); + + if (!dadosXml.get(7).equals("")) { + bw.write(dadosXml.get(7)); + bw.newLine(); + } + if (!dadosXml.get(8).equals("")) { + bw.write(dadosXml.get(8)); + bw.newLine(); + } + if (!dadosXml.get(9).equals("")) { + bw.write(dadosXml.get(9)); + bw.newLine(); + } + if (!dadosXml.get(10).equals("")) { + bw.write(dadosXml.get(10)); + bw.newLine(); + } + + bw.write(""); + bw.flush(); + bw.close(); + // Chama o método para enviar a configuração de rede + try { + funcao = "EnviarConfRede"; + String configData; + // Abre o arquivo XML + BufferedReader br = new BufferedReader(new FileReader(caminhoXML)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + // Lê linha por linha + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + configData = sb.toString(); + return retornoDaFuncaoSat(serialComms.ConfigurarInterfaceDeRede(random, codigoAtivacao, configData)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String versao() { + try { + funcao = "Versao"; + return retornoDaFuncaoSat(serialComms.VersaoDllGerSAT()); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String atualizarSoftware(String codAtivacao, int random) { + try { + funcao = "AtualizarSoftware"; + return retornoDaFuncaoSat(serialComms.AtualizarSAT(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String extrairLog(String codAtivacao, int random) { + try { + funcao = "ExtrairLog"; + return retornoDaFuncaoSat(serialComms.ExtrairLogs(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String desbloquearSat(String codAtivacao, int random) { + try { + funcao = "DesbloquearSat"; + return retornoDaFuncaoSat(serialComms.DesbloquearSAT(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String bloquearSat(String codAtivacao, int random) { + try { + funcao = "BloquearSat"; + return retornoDaFuncaoSat(serialComms.BloquearSAT(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String trocarCodAtivacao(String codAtual, int opt, String codNovo, int random) { + try { + // Sempre o codigo de confirmação vai ser igual ao novo, pois já foi validado no + // flutter + funcao = "TrocarCodAtivacao"; + return retornoDaFuncaoSat(serialComms.TrocarCodigoDeAtivacao(random, codAtual, opt, codNovo, codNovo)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String consultarNumeroSessao(String codAtivacao, int cNumeroDeSessao, int random) { + try { + funcao = "ConsultarNumeroSessao"; + return retornoDaFuncaoSat(serialComms.ConsultarNumeroSessao(random, codAtivacao, cNumeroDeSessao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String cancelarUltimaVenda(String codAtivacao, String xmlBase64, String chave, int random) { + try { + funcao = "CancelarUltimaVenda"; + String vendaData; + + // Cria um arquivo XML + File file = new File(this.context.getFilesDir().getPath() + "/xmlCancelamento.xml"); + + // Escreve no XML os dados que foram enviados do XML decodificado (Flutter) + FileOutputStream fos = new FileOutputStream(file); + fos.write(Base64.decode(xmlBase64, Base64.NO_WRAP)); + fos.close(); + + BufferedReader br = new BufferedReader(new FileReader(file)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + vendaData = sb.toString(); + vendaData = vendaData.replaceAll("trocarCfe", chave); + System.out.println(vendaData); + return retornoDaFuncaoSat(serialComms.CancelarUltimaVenda(random, codAtivacao, chave, vendaData)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String enviarTesteVendas(String codAtivacao, String xmlBase64, int random) { + try { + funcao = "EnviarTesteVendas"; + String vendaData; + + // Cria um arquivo XML + File file = new File(this.context.getFilesDir().getPath() + "/xmlVenda.xml"); + + // Escreve no XML os dados que foram enviados do XML decodificado (Flutter) + FileOutputStream fos = new FileOutputStream(file); + fos.write(Base64.decode(xmlBase64, Base64.NO_WRAP)); + fos.close(); + + // Carrega o XML + BufferedReader br = new BufferedReader(new FileReader(file)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + vendaData = sb.toString(); + return retornoDaFuncaoSat(serialComms.EnviarDadosVenda(random, codAtivacao, vendaData)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String enviarTesteFim(String codAtivacao, String xmlBase64, int random) { + try { + funcao = "EnviarTesteFim"; + String vendaData; + + // Cria um arquivo XML + File file = new File(this.context.getFilesDir().getPath() + "/xmlVenda.xml"); + + // Escreve no XML os dados que foram enviados do XML decodificado (Flutter) + FileOutputStream fos = new FileOutputStream(file); + fos.write(Base64.decode(xmlBase64, Base64.NO_WRAP)); + fos.close(); + + // Carrega o XML + BufferedReader br = new BufferedReader(new FileReader(file)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + vendaData = sb.toString(); + return retornoDaFuncaoSat(serialComms.TesteFimAFim(random, codAtivacao, vendaData)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String consultarStatusOperacional(int random, String codAtivacao) { + try { + funcao = "ConsultarStatusOperacional"; + return retornoDaFuncaoSat(serialComms.ConsultarStatusOperacional(random, codAtivacao)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String consultarSat(int random) { + try { + funcao = "ConsultarSat"; + return retornoDaFuncaoSat(serialComms.ConsultarSAT(random)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String associarSat(String cnpj, String cnpjSW, String codAtivacao, String assinatura, int random) { + try { + funcao = "AssociarSAT"; + return retornoDaFuncaoSat( + serialComms.AssociarAssinatura(random, codAtivacao, cnpjSW + "" + cnpj, assinatura)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String ativarSat(String codAtivacao, String cnpj, int random) { + try { + funcao = "AtivarSAT"; + return retornoDaFuncaoSat(serialComms.AtivarSAT(random, 1, codAtivacao, cnpj, 35)); + } catch (Exception e) { + return e.getMessage(); + } + } + + public String retornoDaFuncaoSat(String s) { + // TODO Fazer algo com a String que foi retornada do sat. + try { + return s; // Retorna a mensagem com os pipes, para ser tratado no Flutter + } catch (Exception e) { + return e.getMessage(); + } + } + + SatGerLib.OnDataReceived dataReceivedListener = new SatGerLib.OnDataReceived() { + public void onError(Exception e) { + System.out.println(e.getMessage()); + } + + @Override + public void onReceivedDataUpdate(String s) { + // TODO Fazer algo com a String que foi retornada do sat. + try { + // Trata o retorno da função + String[] respostaSplited; + respostaSplited = s.split("\\|"); + byte ptext[] = respostaSplited[2].getBytes(); + String value = new String(ptext, "UTF-8"); + } catch (Exception e) { + } + } + }; +} \ No newline at end of file diff --git a/TSG 800/android/app/src/main/res/mipmap-xhdpi/gertec_one.png b/TSG 800/android/app/src/main/res/mipmap-xhdpi/gertec_one.png new file mode 100644 index 0000000..db8a639 Binary files /dev/null and b/TSG 800/android/app/src/main/res/mipmap-xhdpi/gertec_one.png differ diff --git a/TSG 800/assets/iconSat.png b/TSG 800/assets/iconSat.png new file mode 100644 index 0000000..2e9dee0 Binary files /dev/null and b/TSG 800/assets/iconSat.png differ diff --git a/TSG 800/assets/xmlSat/arq_cancelamento.xml b/TSG 800/assets/xmlSat/arq_cancelamento.xml new file mode 100644 index 0000000..ddd4dac --- /dev/null +++ b/TSG 800/assets/xmlSat/arq_cancelamento.xml @@ -0,0 +1,13 @@ + + + + + 16716114000172 + SGR-SAT SISTEMA DE GESTAO E RETAGUARDA DO SAT + 001 + + + + + + \ No newline at end of file diff --git a/TSG 800/assets/xmlSat/arq_venda_008_Simples_Nacional.xml b/TSG 800/assets/xmlSat/arq_venda_008_Simples_Nacional.xml new file mode 100644 index 0000000..3ba070e --- /dev/null +++ b/TSG 800/assets/xmlSat/arq_venda_008_Simples_Nacional.xml @@ -0,0 +1,64 @@ + + + + 16716114000172 + SGR-SAT SISTEMA DE GESTAO E RETAGUARDA DO SAT + 123 + + + 03654119000176 + 000052619494 + 123123 + N + + + + + 0020 + Trib ICMS Isento - PIS e COFINS ST aliquota 0.0250 + 60052300 + 5020 + kg + 1.0000 + 30.00 + A + + + + + 2 + 400 + + + + + 02 + 30.00 + 0.0250 + + + + 30.00 + 0.0250 + + + + 02 + 30.00 + 0.0250 + + + + 30.00 + 0.0250 + + + + + + 01 + 30.00 + + + + diff --git a/TSG 800/lib/main.dart b/TSG 800/lib/main.dart index 089e225..e6f8183 100644 --- a/TSG 800/lib/main.dart +++ b/TSG 800/lib/main.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_gertec/CodigoDeBarraV1.dart'; -import 'package:flutter_gertec/imprimir.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'lerCartaoNfc.dart'; + +import 'menus/sat.dart'; +import 'pages/CodigoDeBarraV1.dart'; +import 'pages/imprimir.dart'; +import 'pages/lerCartaoNfc.dart'; void main() => runApp(MyApp()); @@ -41,11 +43,12 @@ class _MyHomePageState extends State { } var newTaskCtrl = TextEditingController(); - var Lista_nome_funcoes = [ + var listaNomeFuncoes = [ {"name": "Código de Barras", "img": "assets/barcode.png"}, {"name": "Código de Barras V2", "img": "assets/qr_code.png"}, {"name": "Impressão", "img": "assets/print.png"}, {"name": "NFC Leitura/Gravação", "img": "assets/nfc2.png"}, + {"name": "SAT", "img": "assets/iconSat.png"}, ]; void trocarTela(int id) { switch (id) { @@ -71,6 +74,12 @@ class _MyHomePageState extends State { MaterialPageRoute(builder: (context) => PageLeituraCartao()), ); break; + case 4: + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageSat()), + ); + break; } } @@ -94,11 +103,8 @@ class _MyHomePageState extends State { children: [ new Image.asset('assets/gertec.png'), Text( - "Flutter Project", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: ScreenUtil.instance.setSp(30.0), - color: Colors.black87), + "Flutter Project v1.0.0", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenUtil.instance.setSp(30.0), color: Colors.black87), ), ], ), @@ -106,7 +112,7 @@ class _MyHomePageState extends State { Expanded( child: new ListView.builder( shrinkWrap: true, - itemCount: Lista_nome_funcoes.length, + itemCount: listaNomeFuncoes.length, itemExtent: 80, scrollDirection: Axis.vertical, itemBuilder: (BuildContext context, int index) { @@ -117,18 +123,15 @@ class _MyHomePageState extends State { child: ListTile( dense: true, leading: Image( - image: AssetImage(Lista_nome_funcoes[index]["img"]), + image: AssetImage(listaNomeFuncoes[index]["img"]), ), onTap: () { trocarTela(index); }, title: Center( child: Text( - Lista_nome_funcoes[index]["name"], - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: ScreenUtil.instance.setSp(20.0), - color: Colors.black54), + listaNomeFuncoes[index]["name"], + style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenUtil.instance.setSp(20.0), color: Colors.black54), ), ), ), diff --git a/TSG 800/lib/menus/sat.dart b/TSG 800/lib/menus/sat.dart new file mode 100644 index 0000000..75ee3bc --- /dev/null +++ b/TSG 800/lib/menus/sat.dart @@ -0,0 +1,111 @@ +import 'package:flutter/material.dart'; + +import '../pages/sat_pages/associarSat.dart'; +import '../pages/sat_pages/ativarSat.dart'; +import '../pages/sat_pages/configRede.dart'; +import '../pages/sat_pages/ferramentasSat.dart'; +import '../pages/sat_pages/testeSat.dart'; +import '../pages/sat_pages/alterarCodigo.dart'; + +class PageSat extends StatefulWidget { + @override + _PageSatState createState() => _PageSatState(); +} + +// Tela de Menu Principal do Sat com suas Funções principais +class _PageSatState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + Text( + "GERSAT - Aplicativo de Ativação", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20), + ), + SizedBox( + height: 30, + ), + button( + "ATIVAÇÃO SAT", + () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageAtivarSat()), + ); + }, + ), + button( + "ASSOCIAR ASSINATURA", + () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageAssociarSat()), + ); + }, + ), + button( + "TESTE SAT", + () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageTesteSat()), + ); + }, + ), + button( + "CONFIGURAÇÕES DE REDE", + () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageConfigSat()), + ); + }, + ), + button( + "ALTERAR CÓDIGO DE ATIVAÇÃO", + () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageCodigoSat()), + ); + }, + ), + button( + "OUTRAS FERRAMENTAS", + () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageFerramentaSat()), + ); + }, + ) + ], + ), + ), + ), + ); + } + + // Botão padrão, recebe como parâmetro uma string do tipo texto e a função que vai ser chamada ao pressionar o botão + Widget button(String text, VoidCallback voidCallback) { + return SizedBox( + width: 240, + child: RaisedButton( + child: Text(text), + onPressed: voidCallback, + ), + ); + } +} diff --git a/TSG 800/lib/pages/CodigoDeBarraV1.dart b/TSG 800/lib/pages/CodigoDeBarraV1.dart new file mode 100644 index 0000000..84839e6 --- /dev/null +++ b/TSG 800/lib/pages/CodigoDeBarraV1.dart @@ -0,0 +1,139 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class PageCodigoDeBarraV1 extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: CodigoDeBarrav1(title: 'Ler Código de Barras'), + ); + } +} + +class CodigoDeBarrav1 extends StatefulWidget { + CodigoDeBarrav1({Key key, this.title}) : super(key: key); + final String title; + _CodigoDeBarrav1 createState() => _CodigoDeBarrav1(); +} + +class _CodigoDeBarrav1 extends State { + static const platform = const MethodChannel('samples.flutter.dev/gedi'); + final myController = TextEditingController(); + List resultadosBardCod = new List(); + + Future _leitorCodigoDeBarra(String tipoLeitura) async { + print("_leitorCodigoDeBarra"); + try { + String teste = await platform.invokeMethod('leitorCodigov1', {"tipoLeitura": tipoLeitura}); + setState(() { + resultadosBardCod.add(teste); + }); + } on PlatformException catch (e) { + print(e.message); + } + } + + Widget build(BuildContext context) { + double defaultScreenWidth = 400.0; + double defaultScreenHeight = 810.0; + ScreenUtil.instance = ScreenUtil( + width: defaultScreenWidth, + height: defaultScreenHeight, + allowFontScaling: true, + )..init(context); + + return new Scaffold( + body: Container( + padding: EdgeInsets.only( + top: ScreenUtil.instance.setWidth(40.0), + ), + child: Column( + children: [ + Text( + "Ler Código de Barras", + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 30), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox( + width: ScreenUtil.instance.setWidth(100), + child: RaisedButton( + child: Text( + 'EAN 8', + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), + ), + onPressed: () { + _leitorCodigoDeBarra("EAN_8"); + }, + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(100), + child: RaisedButton( + child: Text( + 'EAN 13', + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), + ), + onPressed: () { + _leitorCodigoDeBarra("EAN_13"); + }, + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(100), // specific value + child: RaisedButton( + child: Text( + 'EAN 14', + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), + ), + onPressed: () { + _leitorCodigoDeBarra("EAN_14"); + }, + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(100), // specific value + child: RaisedButton( + child: Text( + 'QR CODE', + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), + ), + onPressed: () { + _leitorCodigoDeBarra("QR_CODE"); + }, + ), + ), + ], + ), + Expanded( + child: new ListView.builder( + shrinkWrap: true, + itemCount: resultadosBardCod.length, + itemExtent: 50, + scrollDirection: Axis.vertical, + itemBuilder: (BuildContext context, int index) { + return Container( + child: ListTile( + dense: true, + title: Text( + resultadosBardCod[index], + style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenUtil.instance.setSp(12.0), color: Colors.black54), + ), + ), + ); + }, + ), + ) + ], + ), + ), + ); + } +} diff --git a/TSG 800/lib/pages/imprimir.dart b/TSG 800/lib/pages/imprimir.dart new file mode 100644 index 0000000..098a12b --- /dev/null +++ b/TSG 800/lib/pages/imprimir.dart @@ -0,0 +1,495 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class PageImprimir extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Imprimir(title: 'Impressão'), + ); + } +} + +class Imprimir extends StatefulWidget { + Imprimir({Key key, this.title}) : super(key: key); + final String title; + _Imprimir createState() => _Imprimir(); +} + +class _Imprimir extends State { + static const platform = const MethodChannel('samples.flutter.dev/gedi'); + final myController = TextEditingController(); + int dropdownValueSize = 20; + int dropdownBarHeight = 280; + int dropdownBarWidth = 280; + String dropdownFont = "DEFAULT"; + String dropdownBarType = "QR_CODE"; + String alinhar = "CENTER"; + String valorSelecionado = "CENTER"; + List listSelecionado = [false, false, false]; + void radioButtonChanges(String value) { + setState(() { + valorSelecionado = value; + switch (value) { + case 'LEFT': + alinhar = value; + break; + case 'CENTER': + alinhar = value; + break; + case 'RIGHT': + alinhar = value; + break; + default: + alinhar = null; + } + print(alinhar); //Debug the choice in console + }); + } + + void erroImpresao() { + showDialog( + context: context, + builder: (BuildContext c) { + return AlertDialog( + title: Text("Escreva uma mensagem para ser impressa !"), + ); + }, + ); + } + + // Função responsavel por finalizar impressao - ImpressoraOutput(); + void finalizarImpressao() async { + await platform.invokeMethod('fimimpressao'); + } + + void impressaoDeTexto({String texto, int fontSize, String alinhar, String fontFamily, List selectedOptions}) async { + texto = texto ?? ""; // Caso seja null + if (texto.isEmpty) { + erroImpresao(); + } else { + try { + await platform.invokeMethod( + 'imprimir', + { + "tipoImpressao": "Texto", + "mensagem": texto, + "alinhar": alinhar ?? "CENTER", + "size": fontSize ?? 10, + "font": fontFamily ?? "DEFAULT", + "options": selectedOptions ?? [false, false, false] + }, + ); + } on PlatformException catch (e) { + print(e.message); + } + } + } + + Future _impressaoTodasFuncoes() async { + try { + await platform.invokeMethod('imprimir', { + "tipoImpressao": "TodasFuncoes", + }); + } on PlatformException catch (e) { + print(e.message); + } + } + + Future _impressaoDeImagem() async { + try { + await platform.invokeMethod('imprimir', { + "tipoImpressao": "Imagem", + }); + } on PlatformException catch (e) { + print(e.message); + } + } + + Future _impressaoDeCodigoDeBarra({String texto, int height, int width, String barCode}) async { + texto = texto ?? ""; // Caso seja null + if (texto.isNotEmpty) { + try { + await platform.invokeMethod('imprimir', { + "tipoImpressao": "CodigoDeBarra", + "height": height ?? 200, + "width": width ?? 200, + "barCode": barCode ?? "QR_CODE", + "mensagem": texto + }); + } on PlatformException catch (e) { + print(e.message); + } + } else { + erroImpresao(); + } + } + + Future checarImpressora() async { + try { + bool impressora = await platform.invokeMethod('checarImpressora'); + if (impressora == true) + return "Ok"; + else + return "Erro"; + } on PlatformException catch (e) { + print(e.message); + } + return "Erro"; + } + + Widget build(BuildContext context) { + double defaultScreenWidth = 400.0; + double defaultScreenHeight = 810.0; + ScreenUtil.instance = ScreenUtil( + width: defaultScreenWidth, + height: defaultScreenHeight, + allowFontScaling: true, + )..init(context); + return new Scaffold( + body: Center( + child: Container( + padding: EdgeInsets.only( + top: 40, + ), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + child: Column( + children: [ + Center( + child: FittedBox( + fit: BoxFit.fitWidth, + child: Text( + "Funções Impressão G700/G800", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(25), fontWeight: FontWeight.bold), + ), + ), + ), + SizedBox( + width: 300, + child: RaisedButton( + child: Text("STATUS IMPRESSORA"), + onPressed: () { + checarImpressora().then((value) { + setState(() { + showDialog( + context: context, + builder: (BuildContext c) { + return AlertDialog( + title: Text("Status Impressora"), + content: Text("Impressora: " + value.toString()), + ); + }, + ); + }); + }); + }, + ), + ), + TextFormField( + autofocus: false, + decoration: const InputDecoration( + hintText: 'Escreva a sua mensagem', + ), + controller: myController, + ), + Center( + child: FittedBox( + fit: BoxFit.fitWidth, + child: Text( + "Configuração de Impressão", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(25), fontWeight: FontWeight.bold), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Radio(value: 'LEFT', groupValue: valorSelecionado, onChanged: radioButtonChanges), + AutoSizeText( + 'Esquerda', + style: TextStyle(fontSize: 15), + ), + Radio(value: 'CENTER', groupValue: valorSelecionado, onChanged: radioButtonChanges), + AutoSizeText( + 'Centralizado', + style: TextStyle(fontSize: 15), + ), + Radio(value: 'RIGHT', groupValue: valorSelecionado, onChanged: radioButtonChanges), + AutoSizeText( + 'Direita', + style: TextStyle(fontSize: 15), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox( + width: ScreenUtil.instance.setWidth(110), + child: RaisedButton( + color: listSelecionado[0] ? Colors.blue : Colors.grey, + onPressed: () { + setState(() { + listSelecionado[0] = !listSelecionado[0]; + }); + }, + child: Text( + "NEGRITO", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + ), + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(110), + child: RaisedButton( + color: listSelecionado[1] ? Colors.blue : Colors.grey, + onPressed: () { + setState(() { + listSelecionado[1] = !listSelecionado[1]; + }); + }, + disabledTextColor: Colors.black87, + child: Text( + "ITÁLICO", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + ), + ), + ), + SizedBox( + width: ScreenUtil.instance.setWidth(110), + child: RaisedButton( + color: listSelecionado[2] ? Colors.blue : Colors.grey, + onPressed: () { + setState(() { + listSelecionado[2] = !listSelecionado[2]; + }); + }, + disabledTextColor: Colors.black87, + child: Text( + "SUBLINHADO", + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + ), + ), + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Font: ", + style: TextStyle(fontSize: 20), + ), + DropdownButton( + value: dropdownFont, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (String newValue) { + setState(() { + dropdownFont = newValue; + }); + }, + items: [ + 'DEFAULT', + 'MONOSPACE', + 'SANS SERIF', + 'SERIF', + 'VECTRA.otf', + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + Text( + "Size: ", + style: TextStyle(color: Colors.black, fontSize: 20), + ), + DropdownButton( + value: dropdownValueSize, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (int newValue) { + setState(() { + dropdownValueSize = newValue; + }); + }, + items: [20, 30, 40, 50, 70, 80, 90, 100].map>((int value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox( + width: 150, + child: RaisedButton( + child: Text( + 'IMPRIMIR TEXTO', + style: TextStyle(fontSize: 12), + ), + onPressed: () { + // Não precisa passar todos os parâmetros - Sera dado o valor DEFAULT + impressaoDeTexto( + texto: myController.text, + fontSize: dropdownValueSize, + alinhar: alinhar, + fontFamily: dropdownFont, + selectedOptions: listSelecionado, + ); + finalizarImpressao(); // Limpa buffer de impressão + }, + ), + ), + SizedBox( + width: 150, + child: RaisedButton( + child: Text( + 'IMPRIMIR IMAGEM', + style: TextStyle(fontSize: 12), + ), + onPressed: () { + _impressaoDeImagem(); + finalizarImpressao(); // Limpa buffer de impressão + }, + ), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + Text("Bar Code Height"), + DropdownButton( + value: dropdownBarHeight, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (int newValue) { + setState(() { + dropdownBarHeight = newValue; + }); + }, + items: [10, 40, 80, 120, 160, 200, 280, 320].map>((int value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + Column( + children: [ + Text("Bar Code Width"), + DropdownButton( + value: dropdownBarWidth, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (int newValue) { + setState(() { + dropdownBarWidth = newValue; + }); + }, + items: [10, 40, 80, 120, 160, 200, 280, 320].map>((int value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + Column( + children: [ + Text("Bar Codes"), + DropdownButton( + value: dropdownBarType, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + onChanged: (String newValue) { + setState(() { + dropdownBarType = newValue; + }); + }, + items: [ + 'QR_CODE', + 'CODE_128', + 'EAN_8', + 'EAN_13', + 'PDF_417', + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + ], + ), + SizedBox( + width: 300, + child: RaisedButton( + child: Text( + 'IMPRIMIR BARCODE', + style: TextStyle(fontSize: 15), + ), + onPressed: () { + // Não precisa passar todos os parâmetros - Sera dado o valor DEFAULT + _impressaoDeCodigoDeBarra( + texto: myController.value.text.toString(), + height: dropdownBarHeight, + width: dropdownBarWidth, + barCode: dropdownBarType, + ); + finalizarImpressao(); // Limpa buffer de impressão + }, + ), + ), + SizedBox( + width: 300, + child: RaisedButton( + child: Text( + 'IMPRIMIR TODAS FUNÇÕES', + style: TextStyle(fontSize: 15), + ), + onPressed: () { + _impressaoTodasFuncoes(); + finalizarImpressao(); // Limpa buffer de impressão + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/TSG 800/lib/pages/lerCartaoNfc.dart b/TSG 800/lib/pages/lerCartaoNfc.dart new file mode 100644 index 0000000..9119d46 --- /dev/null +++ b/TSG 800/lib/pages/lerCartaoNfc.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class PageLeituraCartao extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: LeituraCartao(title: 'Impressão de Texto'), + ); + } +} + +class LeituraCartao extends StatefulWidget { + @override + LeituraCartao({Key key, this.title}) : super(key: key); + final String title; + _LeituraCartao createState() => _LeituraCartao(); +} + +class _LeituraCartao extends State { + static const platform = const MethodChannel('samples.flutter.dev/gedi'); + final myController = TextEditingController(); + + void erroImpresao() { + showDialog( + context: context, + builder: (BuildContext c) { + return AlertDialog( + title: Text("Escreva uma mensagem para ser gravada !"), + ); + }, + ); + } + + Future _lerCartao() async { + try { + await platform.invokeMethod('lerNfc'); + } on PlatformException catch (e) { + print(e.message); + } + } + + Future _gravarCartao(String message) async { + if (message.isEmpty) { + erroImpresao(); + } else { + try { + await platform.invokeMethod('gravarNfc', {"mensagemGravar": message}); + } on PlatformException catch (e) { + print(e.message); + } + } + } + + Future _formatarCartao() async { + try { + await platform.invokeMethod('formatarNfc'); + } on PlatformException catch (e) { + print(e.message); + } + } + + Future _testeCartao() async { + try { + await platform.invokeMethod('testeNfc'); + } on PlatformException catch (e) { + print(e.message); + } + } + + Widget build(BuildContext context) { + return new Scaffold( + body: Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + padding: EdgeInsets.only(top: 40), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TextFormField( + autofocus: false, + decoration: const InputDecoration( + counterStyle: TextStyle(color: Colors.lightBlue), + hintText: 'Mensagem para gravar no cartão', + ), + controller: myController, + ), + SizedBox(height: 20), + SizedBox( + width: MediaQuery.of(context).size.width - 30, + child: RaisedButton( + onPressed: () => _gravarCartao(myController.text), + child: Text( + "GRAVAR NO CARTÃO", + style: TextStyle(color: Colors.white), + ), + color: Colors.blue, + ), + ), + SizedBox(height: 20), + SizedBox( + width: MediaQuery.of(context).size.width - 30, + child: RaisedButton( + onPressed: () => _lerCartao(), + child: Text( + "LER CARTÃO", + style: TextStyle(color: Colors.white), + ), + color: Colors.blue, + ), + ), + SizedBox(height: 20), + SizedBox( + width: MediaQuery.of(context).size.width - 30, + child: RaisedButton( + onPressed: () => _formatarCartao(), + child: Text( + "FORMATAR CARTÃO", + style: TextStyle(color: Colors.white), + ), + color: Colors.blue, + ), + ), + SizedBox(height: 20), + SizedBox( + width: MediaQuery.of(context).size.width - 30, + child: RaisedButton( + onPressed: () => _testeCartao(), + child: Text( + "TESTE LEITURA/GRAVAÇÃO", + style: TextStyle(color: Colors.white), + ), + color: Colors.blue, + ), + ), + ], + ), + ), + ); + } +} diff --git a/TSG 800/lib/pages/sat_pages/alterarCodigo.dart b/TSG 800/lib/pages/sat_pages/alterarCodigo.dart new file mode 100644 index 0000000..5b8cdbd --- /dev/null +++ b/TSG 800/lib/pages/sat_pages/alterarCodigo.dart @@ -0,0 +1,135 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/util/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; + +class PageCodigoSat extends StatefulWidget { + @override + _PageCodigoSatState createState() => _PageCodigoSatState(); +} + +class _PageCodigoSatState extends State { + final codigoAtivacaoNovo = TextEditingController(); // Codigo de ativação Novo + + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação Novo + final confirmacaoCodigo = TextEditingController(); // Confirmação do codigo + String tipoCodigo = "Código de ativação"; // Armazena o tipo de codigo + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void alterarCodigoSat() async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + // Verifica se as entradas são validas + if (commonGertec.isCodigoValido(codigoAtivacao.text) && commonGertec.isCodigoValido(codigoAtivacaoNovo.text)) { + if (codigoAtivacaoNovo.text == confirmacaoCodigo.text) { + // No Java o Sat reconhece 1 - Como sendo a opção de mudar codigo de ativação + // 2 como sendo a opção de alterar codigo de emergência + int op = 0; + if (tipoCodigo == "Código de ativação") + op = 1; + else + op = 2; + + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: { + 'funcao': "TrocarCodAtivacao", + 'random': Random().nextInt(999999), // Cada chamada no Java deve acompanhar diferente + 'codigoAtivar': codigoAtivacao.text.toString(), + 'codigoAtivacaoNovo': codigoAtivacaoNovo.text.toString(), + 'op': op + }, + ); + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } else { + WidgetsGertec.dialogoSat("O Código de Ativação Novo e a Confirmação do Código de Ativação não correspondem!", context: context); + } + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 30), + dropDownList(), + WidgetsGertec.formField(codigoAtivacao, "Atual: "), + SizedBox(height: 20), + WidgetsGertec.formField(codigoAtivacaoNovo, "Novo: "), + SizedBox(height: 20), + WidgetsGertec.formField(confirmacaoCodigo, "Confirmar: "), + SizedBox(height: 20), + SizedBox( + width: 240, + child: RaisedButton( + child: Text("ALTERAR"), + onPressed: () { + alterarCodigoSat(); + }, + ), + ), + ], + ), + ), + ), + ); + } + + Widget dropDownList() { + return Row( + children: [ + Text( + "Tipo de codigo: ", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + DropdownButton( + value: tipoCodigo, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontSize: 15), + onChanged: (String newValue) { + setState( + () { + tipoCodigo = newValue; + }, + ); + }, + items: [ + "Código de ativação", + "Código de Emergência", + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ); + } +} diff --git a/TSG 800/lib/pages/sat_pages/associarSat.dart b/TSG 800/lib/pages/sat_pages/associarSat.dart new file mode 100644 index 0000000..ef7f9fd --- /dev/null +++ b/TSG 800/lib/pages/sat_pages/associarSat.dart @@ -0,0 +1,102 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/util/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; +import 'package:flutter_masked_text/flutter_masked_text.dart'; + +class PageAssociarSat extends StatefulWidget { + @override + _PageAssociarSatState createState() => _PageAssociarSatState(); +} + +class _PageAssociarSatState extends State { + final cnpj = MaskedTextController(mask: "00.000.000/0000-00"); // CNPJ do contribuinte + final cnpjSoftHouse = MaskedTextController(mask: "00.000.000/0000-00"); // CNPJ do Software House + + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de Ativacao do Sat + final assinaturaAc = TextEditingController(); // Assinatura Ac + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void associarSat() async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (commonGertec.isCodigoValido(codigoAtivacao.text)) { + if (assinaturaAc.text.length != 0) { + if (commonGertec.removeMaskCnpj(cnpj.text).length != 14 || commonGertec.removeMaskCnpj(cnpjSoftHouse.text).length != 14) { + WidgetsGertec.dialogoSat("Verifique o CNPJ digitado!", context: context); + } else { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: { + 'funcao': "AssociarSAT", + 'random': Random().nextInt(999999), + 'codigoAtivar': codigoAtivacao.text.toString(), + 'cnpj': commonGertec.removeMaskCnpj(cnpj.text), + 'cnpjSoft': commonGertec.removeMaskCnpj(cnpjSoftHouse.text), + 'assinatura': assinaturaAc.text + }, + ); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } + } else { + WidgetsGertec.dialogoSat("Assinatura AC Inválida!", context: context); + } + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + WidgetsGertec.formField(cnpj, "CNPJ Contribuinte: ", textInputType: TextInputType.number), + SizedBox(height: 20), + WidgetsGertec.formField(cnpjSoftHouse, "CNPJ Software House: ", textInputType: TextInputType.number), + SizedBox(height: 20), + WidgetsGertec.formField(codigoAtivacao, "Código de Ativação: "), + SizedBox(height: 20), + WidgetsGertec.formField(assinaturaAc, "Assinatura AC: "), + SizedBox(height: 20), + SizedBox( + width: 240, + child: RaisedButton( + child: Text("Associar"), + onPressed: () { + associarSat(); + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/TSG 800/lib/pages/sat_pages/ativarSat.dart b/TSG 800/lib/pages/sat_pages/ativarSat.dart new file mode 100644 index 0000000..0c7422e --- /dev/null +++ b/TSG 800/lib/pages/sat_pages/ativarSat.dart @@ -0,0 +1,92 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/util/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; +import 'package:flutter_masked_text/flutter_masked_text.dart'; + +class PageAtivarSat extends StatefulWidget { + @override + _PageAtivarSatState createState() => _PageAtivarSatState(); +} + +class _PageAtivarSatState extends State { + final cnpj = MaskedTextController(mask: "00.000.000/0000-00"); // CNPJ do contribuinte + + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação que vai ser utilizado + + final confirmacaoCodigo = TextEditingController(); // Confirmação do codigo + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void ativarSat() async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (commonGertec.isCodigoValido(codigoAtivacao.text)) { + if (codigoAtivacao.text == confirmacaoCodigo.text) { + String cnpjNoMask = commonGertec.removeMaskCnpj(cnpj.text); // Remove a mascara do CNPJ para validar + if (cnpjNoMask.length != 14) { + WidgetsGertec.dialogoSat("Verifique o CNPJ digitado!", context: context); + } else { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: {'funcao': 'AtivarSAT', 'random': Random().nextInt(999999), 'codigoAtivar': codigoAtivacao.text.toString(), 'cnpj': cnpjNoMask}, + ); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } + } else { + WidgetsGertec.dialogoSat("O Código de Ativação e a Confirmação do Código de Ativação não correspondem!", context: context); + } + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 30), + WidgetsGertec.formField(cnpj, "CNPJ Contribuinte: ", textInputType: TextInputType.number), + SizedBox(height: 20), + WidgetsGertec.formField(codigoAtivacao, "Código de Ativação SAT: "), + SizedBox(height: 20), + WidgetsGertec.formField(confirmacaoCodigo, "Confirmação do Código: "), + SizedBox(height: 20), + SizedBox( + width: 240, + child: RaisedButton( + child: Text("ATIVAR"), + onPressed: () { + ativarSat(); + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/TSG 800/lib/pages/sat_pages/configRede.dart b/TSG 800/lib/pages/sat_pages/configRede.dart new file mode 100644 index 0000000..95b8d85 --- /dev/null +++ b/TSG 800/lib/pages/sat_pages/configRede.dart @@ -0,0 +1,304 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/util/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; + +class PageConfigSat extends StatefulWidget { + @override + _PageConfigSatState createState() => _PageConfigSatState(); +} + +class _PageConfigSatState extends State { + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação + + final ipSat = TextEditingController(); // Ip do Sat para ser ativado + final mascara = TextEditingController(); // Mascara Rede + final gateway = TextEditingController(); // gateway Rede + final dns1 = TextEditingController(); // dns1 Rede + final dns2 = TextEditingController(); // dns2 Rede + final proxyIp = TextEditingController(); // proxy Rede + final porta = TextEditingController(); // porta Rede + final user = TextEditingController(); // user Rede + final password = TextEditingController(); // password Rede + String tipoRede = "Estático"; // Armazena o tipo de rede + String habilitarDNS = "Sim"; // Armazena opção Dns + String habilitarProxy = "Não usa proxy"; // Armazena o tipo proxy de rede + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void configRedeSat() async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (commonGertec.isCodigoValido(codigoAtivacao.text)) { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: { + 'funcao': "EnviarConfRede", + 'random': Random().nextInt(999999), + 'codigoAtivar': codigoAtivacao.text.toString(), + 'dadosXml': formatarEnvioConfigRede() + }, + ); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 30), + WidgetsGertec.formField(codigoAtivacao, "Codigo ativação: "), + SizedBox(height: 20), + Row( + children: [ + Text( + "Tipo de Rede: ", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + DropdownButton( + value: tipoRede, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontSize: 15), + onChanged: (String newValue) { + setState( + () { + print(newValue); + tipoRede = newValue; + }, + ); + }, + items: ["Estático", "DHCP"].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + verificartipoRede(), + SizedBox(height: 20), + Row( + children: [ + Text( + "DNS: ", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + DropdownButton( + value: habilitarDNS, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontSize: 15), + onChanged: (String newValue) { + setState( + () { + habilitarDNS = newValue; + }, + ); + }, + items: ["Sim", "Não"].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + verificartipoDns(), + SizedBox(height: 20), + Row( + children: [ + Text( + "Proxy: ", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + DropdownButton( + value: habilitarProxy, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black, fontSize: 15), + onChanged: (String newValue) { + setState( + () { + habilitarProxy = newValue; + }, + ); + }, + items: ["Não usa proxy", "Proxy com configuração", "Proxy transparente"].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + ), + ], + ), + verificartipoProxy(), + SizedBox(height: 20), + WidgetsGertec.buttonStandard("ENVIAR", callback: () => configRedeSat()) + ], + ), + ), + ), + ); + } + + Widget verificartipoRede() { + if (tipoRede == "Estático") + return Column( + children: [ + WidgetsGertec.formField(ipSat, "IP SAT: "), + WidgetsGertec.formField(mascara, "Máscara: "), + WidgetsGertec.formField(gateway, "Getway: "), + ], + ); + else { + return SizedBox(height: 0); + } + } + + Widget verificartipoDns() { + if (habilitarDNS == "Sim") + return Column( + children: [ + WidgetsGertec.formField(dns1, "DNS 1: "), + WidgetsGertec.formField(dns2, "DNS 2: "), + ], + ); + else { + return SizedBox(height: 0); + } + } + + Widget verificartipoProxy() { + if (habilitarProxy != "Não usa proxy") + return Column( + children: [ + WidgetsGertec.formField(proxyIp, "Proxy Ip: "), + WidgetsGertec.formField(porta, "Porta: "), + WidgetsGertec.formField(user, "User: "), + WidgetsGertec.formField(password, "Password: "), + ], + ); + else { + return SizedBox(height: 0); + } + } + + // Configuracao os dados a serem enviados para o Sat + List formatarEnvioConfigRede() { + List dadosXml = new List(11); + dadosXml[0] = ""; + dadosXml[1] = ""; + dadosXml[2] = ""; + dadosXml[3] = ""; + dadosXml[4] = ""; + dadosXml[5] = ""; + dadosXml[6] = ""; + dadosXml[7] = ""; + dadosXml[8] = ""; + dadosXml[9] = ""; + dadosXml[10] = ""; + + // Monta as tags do XML sobre a parte de REDE + if (tipoRede == "Estático") { + dadosXml[0] = "IPFIX"; + if (ipSat.text.isNotEmpty) { + dadosXml[1] = "" + ipSat.text + ""; + } + if (mascara.text.isNotEmpty) { + dadosXml[2] = "" + mascara.text + ""; + } + if (gateway.text.isNotEmpty) { + dadosXml[3] = "" + gateway.text + ""; + } + + // Monta as tags do XML sobre a parte de DNS + if (habilitarDNS == "Sim") { + if (dns1.text.isNotEmpty) { + dadosXml[4] = "" + dns1.text + ""; + } + if (dns2.text.isNotEmpty) { + dadosXml[5] = "" + dns2.text + ""; + } + } else { + dadosXml[4] = "8.8.8.8"; + dadosXml[5] = "4.4.4.4"; + } + } else { + dadosXml[0] = "DHCP"; + dadosXml[1] = ""; + dadosXml[2] = ""; + dadosXml[3] = ""; + dadosXml[4] = ""; + dadosXml[5] = ""; + } + + // Monta as tags do XML sobre a parte de PROXY + if (habilitarProxy == "Não usa proxy") { + dadosXml[6] = "0"; + dadosXml[7] = ""; + dadosXml[8] = ""; + dadosXml[9] = ""; + dadosXml[10] = ""; + } else if (habilitarProxy == "Proxy com configuração") { + dadosXml[6] = "1"; + if (proxyIp.text.isNotEmpty) { + dadosXml[7] = "" + proxyIp.text + ""; + } + if (porta.text.isNotEmpty) { + dadosXml[8] = "" + porta.text + ""; + } + if (user.text.isNotEmpty) { + dadosXml[9] = "" + user.text + ""; + } + if (password.text.isNotEmpty) { + dadosXml[10] = "" + password.text + ""; + } + } else { + dadosXml[6] = "2"; + if (proxyIp.text.isNotEmpty) { + dadosXml[7] = "" + proxyIp.text + ""; + } + if (porta.text.isNotEmpty) { + dadosXml[8] = "" + porta.text + ""; + } + if (user.text.isNotEmpty) { + dadosXml[9] = "" + user.text + ""; + } + if (password.text.isNotEmpty) { + dadosXml[10] = "" + password.text + ""; + } + } + return dadosXml; + } +} diff --git a/TSG 800/lib/pages/sat_pages/ferramentasSat.dart b/TSG 800/lib/pages/sat_pages/ferramentasSat.dart new file mode 100644 index 0000000..faf53a7 --- /dev/null +++ b/TSG 800/lib/pages/sat_pages/ferramentasSat.dart @@ -0,0 +1,100 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_gertec/util/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; + +class PageFerramentaSat extends StatefulWidget { + @override + _PageFerramentaSatState createState() => _PageFerramentaSatState(); +} + +class _PageFerramentaSatState extends State { + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação do Sat + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + void ferramentasSat(String funcao) async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (funcao == "Versao" || commonGertec.isCodigoValido(codigoAtivacao.text)) { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: {'funcao': funcao, 'random': Random().nextInt(999999), 'codigoAtivar': codigoAtivacao.text.toString()}); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + + // O retorno da operação Versão não é tratado, pois retorna somente uma string + if (funcao == "Versao") { + WidgetsGertec.dialogoSat(retornoSat.getResultadoCompleto, context: context); + } else { + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context); + } + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + Padding( + padding: const EdgeInsets.only(left: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Código de Ativação SAT: ", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 30, + width: 140, + child: TextFormField( + controller: codigoAtivacao, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ), + SizedBox(height: 20), + WidgetsGertec.buttonStandard("BLOQUEAR SAT", callback: () => ferramentasSat("BloquearSat")), + WidgetsGertec.buttonStandard("DESBLOQUEAR SAT", callback: () => ferramentasSat("DesbloquearSat")), + WidgetsGertec.buttonStandard("EXTRAIR LOG", callback: () => ferramentasSat("ExtrairLog")), + WidgetsGertec.buttonStandard("ATUALIZAR SOFTWARE", callback: () => ferramentasSat("AtualizarSoftware")), + WidgetsGertec.buttonStandard("VERIFICAR VERSÃO", callback: () => ferramentasSat("Versao")), + ], + ), + ), + ), + ); + } +} diff --git a/TSG 800/lib/pages/sat_pages/testeSat.dart b/TSG 800/lib/pages/sat_pages/testeSat.dart new file mode 100644 index 0000000..da77d71 --- /dev/null +++ b/TSG 800/lib/pages/sat_pages/testeSat.dart @@ -0,0 +1,206 @@ +import 'dart:convert'; +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_gertec/util/globalValues.dart'; +import 'package:flutter_gertec/services/operacaoSat.dart'; +import 'package:flutter_gertec/services/retornoSat.dart'; +import 'package:flutter_gertec/util/common_code.dart'; +import 'package:flutter_gertec/widgets/widgetsgertec.dart'; + +class PageTesteSat extends StatefulWidget { + @override + _PageTesteSatState createState() => _PageTesteSatState(); +} + +class _PageTesteSatState extends State { + // Inicializa o código de ativação com um valor global, para o usuario não precisar ficar digitando + final codigoAtivacao = TextEditingController(text: GlobalValues.codAtivarSat); // Codigo de ativação do Sat + final chaveCancelamento = TextEditingController(text: GlobalValues.valorCfe); // Chave de cancelamento + final chaveSessao = TextEditingController(text: "123"); // Chave de sessao para consulta + String xmlVenda; // Xml de Venda a ser enviado, transformado em Base 64 + String xmlCancelamento; // Xml de Cancelamento a ser enviado, transformado em Base 64 + + CommonGertec commonGertec = new CommonGertec(); //* Classe que possui partes de código comuns em diversas telas + + void initState() { + super.initState(); + // Transforma os Xml em base 64 e envia para o Java Android transmitir para a Sefaz + transformarbase64('assets/xmlSat/arq_cancelamento.xml').then((value) => xmlCancelamento = value); + transformarbase64('assets/xmlSat/arq_venda_008_Simples_Nacional.xml').then((value) => xmlVenda = value); + } + + //Reponsavel por fazer a conversão de um File Xml das pastas assets, para um codigo na base 64. + Future transformarbase64(String assetPath) async { + ByteData bytes = await rootBundle.load(assetPath); + var buffer = bytes.buffer; + var m = base64.encode(Uint8List.view(buffer)); + return m; + } + + // Dialogo para inserir dados + void dialogoInserirDados( + String texto, + TextEditingController textEditingController, + TextInputType textInputType, + Function function, + ) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Alerta"), + content: Container( + height: 120, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(texto), + SizedBox( + height: 50, + width: 140, + child: TextFormField( + keyboardType: textInputType, + controller: textEditingController, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + if (textEditingController.text.length > 0) { + Navigator.pop(context); + function(); + } else { + WidgetsGertec.dialogoSat("Verifique a entrada!"); + } + }, + ) + ], + ), + ); + } + + // Função para validar os valores digitos pelo usuario e realizar a ativação do SAT + Future testeSat(String funcao) async { + GlobalValues.codAtivarSat = codigoAtivacao.text; // Salva o código de ativação para o usuario não precisar ficar digitando em todas as telas + if (funcao == "ConsultarSat" || commonGertec.isCodigoValido(codigoAtivacao.text)) { + //* Chama a função Invocar Operação Sat, que recebe como parâmetro a "operação invocada" e um "Map com as chaves e seus respectivos valores". + RetornoSat retornoSat = await OperacaoSat.invocarOperacaoSat( + // Passa como parâmetro um Map de argumentos de valores que deseja enviar + args: { + //* os dados são enviados para o Java, mas nem todos são lidos, por isso não existe problema de alguns parametros estarem Nulos + 'funcao': funcao, + 'random': Random().nextInt(999999), + 'codigoAtivar': codigoAtivacao.text.toString(), + 'chaveCancelamento': chaveCancelamento.text ?? " ", + 'chaveSessao': int.parse(chaveSessao.text) ?? " ", + 'xmlVenda': xmlVenda, + 'xmlCancelamento': xmlCancelamento + }, + ); + + //? Caso deseje visualizar o retorno completo basta chamar [retornoSat.getResultadoCompleto] + /* + * Está verificação(abaixo) tem como objetivo capturar a "Chave de Consulta" retornado na operação EnviarTesteVendas + * O valor é armazenado em uma variavel global e quando o usuario abre a tela para cancelar venda, o campo (Chave de Cancelamento) já fica preenchido + */ + if (funcao == 'EnviarTesteVendas') { + GlobalValues.valorCfe = retornoSat.getChaveConsulta; + setState(() { + chaveCancelamento.text = GlobalValues.valorCfe; + }); + } + + //* Está função [OperacaoSat.formataRetornoSat] recebe como parâmetro a operação realizada e um objeto do tipo RetornoSat + //* Retorna uma String com os valores obtidos do retorno da Operação já formatados e prontos para serem exibidos na tela + // Recomenda-se acessar a função e entender como ela funciona + String retornoFormatado = OperacaoSat.formataRetornoSat(retornoSat: retornoSat); + WidgetsGertec.dialogoSat(retornoFormatado, context: context, heightDialog: 300); + } else { + WidgetsGertec.dialogoSat("Código de Ativação deve ter entre 8 a 32 caracteres!", context: context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 30), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + Padding( + padding: const EdgeInsets.only(left: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Código de Ativação SAT: ", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 18, + width: 140, + child: TextFormField( + controller: codigoAtivacao, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ), + SizedBox(height: 20), + WidgetsGertec.buttonStandard("CONSULTAR SAT", callback: () => testeSat("ConsultarSat")), + WidgetsGertec.buttonStandard("STATUS OPERACIONAL", callback: () => testeSat("ConsultarStatusOperacional")), + WidgetsGertec.buttonStandard("TESTE FIM A FIM", callback: () => testeSat("EnviarTesteFim")), + WidgetsGertec.buttonStandard("ENVIAR DADOS DE VENDA", callback: () => testeSat("EnviarTesteVendas")), + WidgetsGertec.buttonStandard( + "CANCELAR VENDA", + callback: () => + // Aqui vai ser aberto o dialogo para inserção de dados para cancelamento da Venda, ao preencher e clicar em Ok, vai ser cancelado a venda + dialogoInserirDados( + "Digite a chave de cancelamento", + chaveCancelamento, + TextInputType.name, + () => testeSat("CancelarUltimaVenda"), + ), + ), + WidgetsGertec.buttonStandard( + "CONSULTAR SESSÃO", + callback: () => + // Aqui vai ser aberto o dialogo para inserção de dados para consulta da sessão + dialogoInserirDados( + "Digite o número da sessão", + chaveSessao, + TextInputType.number, + () => testeSat("ConsultarNumeroSessao"), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/TSG 800/lib/services/operacaoSat.dart b/TSG 800/lib/services/operacaoSat.dart new file mode 100644 index 0000000..7cf6d55 --- /dev/null +++ b/TSG 800/lib/services/operacaoSat.dart @@ -0,0 +1,170 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; + +import 'retornoSat.dart'; + +const platform = const MethodChannel('samples.flutter.dev/gedi'); + +class OperacaoSat { + // Funcão que invoca uma operação no Sat. Recebe como parâmetro um Map com os valores que vão ser enviados para o Sat + static Future invocarOperacaoSat({Map args}) async { + try { + // O resultado da invocação de uma operação é uma String grande contendos todas as informações divida por Pipes "|" + String retornoPipeCompleto = await platform.invokeMethod(args['funcao'], args); + + // Após a String ser recebida do canal, ela é enviada como parâmetro para a classe [RetornoSat] + // onde a String é divida e pode ser pego seus valores através de metodos Get e Set. + RetornoSat retornoSat = new RetornoSat(args['funcao'], retornoPipeCompleto); + // Esta função já retorna um objeto do tipo [RetornoSat], onde as informações do retorno já podem ser acessadas + return retornoSat; + } on Exception catch (_) { + return null; + } + } + + // Função que retorna uma String formatada para ser posta no dialogo Sat, com todas as informações do retorno da operação realizada + // Em caso de erro retorna o erro + // *Existem operações que vão ter como resultado informações semelhantes + static String formataRetornoSat({@required RetornoSat retornoSat}) { + String retornoFormatado = ''; + // Verifica se existe um erro no retorno + if (retornoSat.getErroSat != "") { + // Retorna o erro caso exista + return "Mensagem: " + retornoSat.getErroSat; + } else { + //* Estas informações são padrões a todos os retornos(sempre vão aparecer no Dialogo Sat) + //* Para mais informações consulte o arquivo retornosSat.txt. É possivel visualizar nele a posição e informação de cada Retorno do Sat. + if (retornoSat.getNumeroCCCC != "") { + // Se tiver Código CCCC adiciona ele a string formatada + retornoFormatado = retornoSat.getNumeroEEEE + "|" + retornoSat.getNumeroCCCC + "-"; + } else { + // Caso não tenha o código CCCC adicionada somente o EEEE + retornoFormatado = retornoSat.getNumeroEEEE + "-"; + } + + retornoFormatado += retornoSat.getMensagem; + + retornoFormatado += "\n"; // Pula linha + + // Verifica se adiciona o Código e Mensagem Sefaz na mensagem, caso não estejam vazios + if (retornoSat.getNumeroCod != "" && retornoSat.getMensagemSefaz != "") { + retornoFormatado += "Cod/Mens Sefaz: \n" + retornoSat.getNumeroCod + "-" + retornoSat.getMensagemSefaz; + } else if (retornoSat.getNumeroCod != "") { + retornoFormatado += "Cod/Mens Sefaz: \n" + retornoSat.getNumeroCod + "-"; + } else if (retornoSat.getMensagemSefaz != "") { + retornoFormatado += "Cod/Mens Sefaz: \n" + "-" + retornoSat.getMensagemSefaz; + } + + retornoFormatado += "\n"; // Pula linha + + //* Agora só são inseridas as informações que não são padrões a todos retornos + //* São atribuidas as informações especificas do retorno da operação + if (retornoSat.getOperacao == "AtivarSAT") { + if (retornoSat.getCodigoCSR != "") { + retornoFormatado += "CSR: " + retornoSat.getCodigoCSR; + } + } else if (retornoSat.getOperacao == "ExtrairLog") { + //! Cuidado com está parte, ela pode exigir muito processamento se estiver em modo Debug + //! Recomenda-se que utilize somente em modo release e não colocar em um Dialogo, pois o arquivo retornado é grande + // retornoFormatado += "Arquivo de log em base64: " + retornoSat.getLogBase64; + print(retornoSat.getLogBase64); + } else if (retornoSat.getOperacao == "ConsultarStatusOperacional") { + retornoFormatado += "------- Conteúdo Retorno -------" + + "\n" + + "Número de Série do SAT: " + + retornoSat.getNumeroSerieSat + + "Tipo de Lan: " + + retornoSat.getTipoLan + + "\n" + + "IP SAT: " + + retornoSat.getIpSat + + "\n" + + "MAC SAT: " + + retornoSat.getMacSat + + "\n" + + "Máscara: " + + retornoSat.getMascara + + "\n" + + "Gateway: " + + retornoSat.getGateway + + "\n" + + "DNS 1: " + + retornoSat.getDns1 + + "\n" + + "DNS 2: " + + retornoSat.getDns2 + + "\n" + + "Status da Rede: " + + retornoSat.getStatusRede + + "\n" + + "Nível da Bateria: " + + retornoSat.getNivelBateria + + "\n" + + "Memória de Trabalho Total: " + + retornoSat.getMemoriaDeTrabalhoTotal + + "\n" + + "Memória de Trabalho Usada: " + + retornoSat.getMemoriaDeTrabalhoUsada + + "\n" + + "Data/Hora: " + + retornoSat.getDataHora + + "\n" + + "Versão: " + + retornoSat.getVersao + + "\n" + + "Versão de Leiaute: " + + retornoSat.getVersaoLeiaute + + "\n" + + "Último CFe-Sat Emitido: " + + retornoSat.getUltimoCfeEmitido + + "\n" + + "Primeiro CFe-Sat Em Memória: " + + retornoSat.getPrimeiroCfeMemoria + + "\n" + + "Último CFe-Sat Em Memória: " + + retornoSat.getUltimoCfeMemoria + + "\n" + + "Última Transmissão de CFe-SAT para SEFAZ: " + + retornoSat.getUltimaTransmissaoSefazDataHora + + "\n" + + "Última Comunicacao com a SEFAZ:" + + retornoSat.getUltimaComunicacaoSefazData + + "\n" + + "Estado de Operação do SAT: " + + retornoSat.getEstadoDeOperacao; + } else if (retornoSat.getOperacao == "AssociarSAT") { + //* Associar SAT somente tem como dado especifico o campo CCCC(fica ao seu criterio adicionar-lo ou não) + } else if (retornoSat.getOperacao == "EnviarTesteFim") { + retornoFormatado += "TimeStamp: " + + retornoSat.getTimeStamp + + "\nNum Doc Fiscal: " + + retornoSat.getNumDocFiscal + + "\nChave de Consulta: " + + retornoSat.getChaveConsulta + + "\nArquivo CFE Base 64: " + + converterBase64EmXml(retornoSat.getArquivoCFeBase64); + } else if (retornoSat.getOperacao == "EnviarTesteVendas" || retornoSat.getOperacao == "CancelarUltimaVenda") { + retornoFormatado += "TimeStamp: " + + retornoSat.getTimeStamp + + "\nChave de Consulta: " + + retornoSat.getChaveConsulta + + "\nValor CFE: " + + retornoSat.getValorTotalCFe + + "\nValor CPF CNPJ: " + + retornoSat.getCPFCNPJValue + + "\nArquivo CFE Base 64: " + + converterBase64EmXml(retornoSat.getArquivoCFeBase64) + + "\nAssinatura QRCODE: " + + retornoSat.getAssinaturaQRCODE; + } + } + return retornoFormatado; + } + + // Função que converte o arquivo Base 64 em String + static String converterBase64EmXml(String base64Sat) { + return utf8.decode(base64.decode(base64Sat)); // Converte o arquivo Base 64 em String(vai ser usado para visualizar o Xml de resposta) + } +} diff --git a/TSG 800/lib/services/retornoSat.dart b/TSG 800/lib/services/retornoSat.dart new file mode 100644 index 0000000..df2266b --- /dev/null +++ b/TSG 800/lib/services/retornoSat.dart @@ -0,0 +1,284 @@ +class RetornoSat { + List _retornoPipe; // Armazena o retorno em forma de lista String + String _operacao; // Armazena a operacao solicitada + bool retornoDiferente; + String _retornoPipeCompleto; + RetornoSat(String operacao, String retornopipe) { + this._retornoPipeCompleto = retornopipe; + this._retornoPipe = retornopipe.split("|"); + this._operacao = operacao; + /** + O resultado das operações solicitadas é uma String divida por Pipes, exemplo: “numeroSessao|EEEEE|mensagem|cod|mensagemSEFAZ” + Mas nem todos os retornos são padrões, existem alguns com posições diferentes de um mesmo valor. + Para solucionar este obstaculo foi elabarado uma condição que verifica se a operação solicitada é uma das três(que possuem maior discrepância de posições) + Caso sim, é retornado uma posição diferente do mesmo valor, caso contrario é retornado a posição padrão + **/ + retornoDiferente = _operacao == 'AssociarSAT' || _operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda'; + } + // Retorna a String divida por pipe sem formatações + get getResultadoCompleto => _retornoPipeCompleto; + + // Retorna a Operacao que foi solicitada + get getOperacao => _operacao; + + // Verifica se tem algum problema no retorno da operacao solicitada + get getErroSat { + //* Se o tamanho da lista de informações obtidas do retorno [_retornoPipe] for igual <= 1, provavelmente ocorreu um erro. + if (_retornoPipe.length <= 1) { + // Verifica se houve um erro ao se conectar com o Sat + if (_retornoPipe[0] == 'Failed to find SAT device.') { + return 'Dispositivo SAT não localizado'; + } else { + // Caso não seja um erro de comunicação com o SAT retorna o erro que ocorreu + return _retornoPipe[0]; + } + } + //* Verifica se o código de ativação é invalido + if (getMensagem == "Codigo de ativação inválido" || getMensagem == "Codigo ativação inválido") { + return getMensagem; + } + // Caso não exista nenhum erro + return ""; + } + + get getNumeroSessao { + try { + return _retornoPipe[0]; + } catch (e) { + return ""; + } + } + + get getNumeroEEEE { + try { + return _retornoPipe[1]; + } catch (e) { + return ""; + } + } + + get getMensagem { + try { + if (retornoDiferente) return _retornoPipe[3]; + return _retornoPipe[2]; + } catch (e) { + return ""; + } + } + + // Dado somente presente na três funções(AssociarSAT, Enviar Teste Venda e Cancelar Ultima Venda) + get getNumeroCCCC { + try { + if (retornoDiferente) return _retornoPipe[2]; + return ""; + } catch (e) { + return ""; + } + } + + get getNumeroCod { + try { + if (retornoDiferente) return _retornoPipe[4]; + return _retornoPipe[3]; + } catch (e) { + return ""; + } + } + + get getMensagemSefaz { + try { + if (retornoDiferente) return _retornoPipe[5]; + return _retornoPipe[4]; + } catch (e) { + return ""; + } + } + + // Dado exclusivo do retorno da operação Ativar Sat + get getCodigoCSR { + try { + if (_operacao == 'AtivarSAT') return _retornoPipe[5]; + return ""; + } catch (e) { + return ""; + } + } + + // Dado exclusivo do retorno da operação Extrair Log + get getLogBase64 { + try { + if (_operacao == 'ExtrairLog') return _retornoPipe[5]; + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente na três funções(EnviarTesteFim, Enviar Teste Venda e Cancelar Ultima Venda) + get getArquivoCFeBase64 { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') { + return _retornoPipe[6]; + } else if (_operacao == 'EnviarTesteFim') { + return _retornoPipe[5]; + } else { + return ""; + } + } catch (e) { + return ""; + } + } + + // Dado somente presente na três funções(EnviarTesteFim, Enviar Teste Venda e Cancelar Ultima Venda) + get getTimeStamp { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') { + return _retornoPipe[7]; + } else if (_operacao == 'EnviarTesteFim') { + return _retornoPipe[6]; + } else { + return ""; + } + } catch (e) { + return ""; + } + } + + // Dado exclusivo do retorno da operação TEnviarTesteFim + get getNumDocFiscal { + try { + if (_operacao == "EnviarTesteFim") return _retornoPipe[7]; + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente na três funções(EnviarTesteFim, Enviar Teste Venda e Cancelar Ultima Venda) + get getChaveConsulta { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda' || _operacao == 'EnviarTesteFim') return _retornoPipe[8]; + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente nas funções(Enviar Teste Venda e Cancelar Ultima Venda) + get getValorTotalCFe { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') + return _retornoPipe[9]; + else + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente nas funções(Enviar Teste Venda e Cancelar Ultima Venda) + get getCPFCNPJValue { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') + return _retornoPipe[10]; + else + return ""; + } catch (e) { + return ""; + } + } + + // Dado somente presente nas funções(Enviar Teste Venda e Cancelar Ultima Venda) + get getAssinaturaQRCODE { + try { + if (_operacao == 'EnviarTesteVendas' || _operacao == 'CancelarUltimaVenda') + return _retornoPipe[11]; + else + return ""; + } catch (e) { + return ""; + } + } + + get getEstadoDeOperacao { + try { + if (_retornoPipe[27] == "0") + return "DESBLOQUEADO"; + else if (_retornoPipe[27] == "1") + return "BLOQUEADO SEFAZ"; + else if (_retornoPipe[27] == "2") + return "BLOQUEIO CONTRIBUINTE"; + else if (_retornoPipe[27] == "3") + return "BLOQUEIO AUTÔNOMO"; + else if (_retornoPipe[27] == "4") return "BLOQUEIO PARA DESATIVAÇÃO"; + } catch (e) { + return ""; + } + } + + get getNumeroSerieSat { + try { + return _retornoPipe[5] + "\n"; + } catch (e) { + return ""; + } + } + + get getTipoLan => _retornoPipe[6] + "\n"; + get getIpSat => _retornoPipe[7] + "\n"; + get getMacSat => _retornoPipe[8] + "\n"; + get getMascara => _retornoPipe[9] + "\n"; + get getGateway => _retornoPipe[10] + "\n"; + get getDns1 => _retornoPipe[11] + "\n"; + get getDns2 => _retornoPipe[12] + "\n"; + get getStatusRede => _retornoPipe[13] + "\n"; + get getNivelBateria => _retornoPipe[14] + "\n"; + get getMemoriaDeTrabalhoTotal => _retornoPipe[15] + "\n"; + get getMemoriaDeTrabalhoUsada => _retornoPipe[16] + "\n"; + get getDataHora => + _retornoPipe[17].substring(6, 8) + + "/" + + _retornoPipe[17].substring(4, 6) + + "/" + + _retornoPipe[17].substring(0, 4) + + " " + + _retornoPipe[17].substring(8, 10) + + ":" + + _retornoPipe[17].substring(10, 12) + + ":" + + _retornoPipe[17].substring(12, 14) + + "\n"; + + get getVersao => _retornoPipe[18] + "\n"; + get getVersaoLeiaute => _retornoPipe[19] + "\n"; + get getUltimoCfeEmitido => _retornoPipe[20] + "\n"; + get getPrimeiroCfeMemoria => _retornoPipe[21] + "\n"; + get getUltimoCfeMemoria => _retornoPipe[22] + "\n"; + get getUltimaTransmissaoSefazDataHora => + _retornoPipe[23].substring(6, 8) + + "/" + + _retornoPipe[23].substring(4, 6) + + "/" + + _retornoPipe[23].substring(0, 4) + + " " + + _retornoPipe[23].substring(8, 10) + + ":" + + _retornoPipe[23].substring(10, 12) + + ":" + + _retornoPipe[23].substring(12, 14) + + "\n"; + + get getUltimaComunicacaoSefazData => + _retornoPipe[24].substring(6, 8) + + "/" + + _retornoPipe[24].substring(4, 6) + + "/" + + _retornoPipe[24].substring(0, 4) + + " " + + _retornoPipe[24].substring(8, 10) + + ":" + + _retornoPipe[24].substring(10, 12) + + ":" + + _retornoPipe[24].substring(12, 14) + + "\n"; +} diff --git a/TSG 800/lib/services/widgetsgertec.dart b/TSG 800/lib/services/widgetsgertec.dart new file mode 100644 index 0000000..024659e --- /dev/null +++ b/TSG 800/lib/services/widgetsgertec.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +class WidgetsGertec extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container(); + } + + // Botão padrão, recebe como parâmetro uma string('texto') e a função que vai ser chamada ao pressionar o botão('voidCallback') + static Widget buttonStandard(String text, {VoidCallback callback}) { + return SizedBox( + width: 240, + child: RaisedButton( + child: Text(text), + onPressed: callback, + ), + ); + } + + // Dialogo que ira aparecer após a função Sat ser iniciada e ocorrer algum erro ou tudo ocorrer certo + static void dialogoSat(String messageText, {@required BuildContext context, double heightDialog = 100}) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Retorno"), + content: Container( + height: heightDialog, + child: ListView( + children: [ + Text(messageText), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + static Widget formField(TextEditingController textFormField, String textAntesForm, {TextInputType textInputType}) { + return Padding( + padding: const EdgeInsets.only(left: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + textAntesForm, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 30, + width: 140, + child: TextFormField( + keyboardType: textInputType, + controller: textFormField, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ); + } +} diff --git a/TSG 800/lib/util/common_code.dart b/TSG 800/lib/util/common_code.dart new file mode 100644 index 0000000..be07eb8 --- /dev/null +++ b/TSG 800/lib/util/common_code.dart @@ -0,0 +1,20 @@ +//* Classe que possui partes de código comuns em diversas telas +class CommonGertec { + CommonGertec(); + final int maxLength = 32; // Armazena o tamanho maximo do códig de validação + final int minLength = 8; // Armazena o tamanho minimo do códig de validação + + // Verifica se o código de validação do Sat inserido pelo usuario é valido + // ? Está função foi desenvolvida para minimizar a repetição de código + bool isCodigoValido(String codigo) { + if (codigo.length >= this.minLength && codigo.length <= this.maxLength) { + return true; + } + return false; + } + + // Remove a mascara do CNPJ + String removeMaskCnpj(String cnpjInput) { + return cnpjInput.toString().replaceAll(".", "").replaceAll("/", "").replaceAll("-", ""); + } +} diff --git a/TSG 800/lib/util/globalValues.dart b/TSG 800/lib/util/globalValues.dart new file mode 100644 index 0000000..6bb6ff4 --- /dev/null +++ b/TSG 800/lib/util/globalValues.dart @@ -0,0 +1,5 @@ +class GlobalValues { + GlobalValues._(); + static String codAtivarSat = ""; + static String valorCfe = "CFe29200603654119000176599000073560000266137373"; +} diff --git a/TSG 800/lib/widgets/widgetsgertec.dart b/TSG 800/lib/widgets/widgetsgertec.dart new file mode 100644 index 0000000..024659e --- /dev/null +++ b/TSG 800/lib/widgets/widgetsgertec.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +class WidgetsGertec extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container(); + } + + // Botão padrão, recebe como parâmetro uma string('texto') e a função que vai ser chamada ao pressionar o botão('voidCallback') + static Widget buttonStandard(String text, {VoidCallback callback}) { + return SizedBox( + width: 240, + child: RaisedButton( + child: Text(text), + onPressed: callback, + ), + ); + } + + // Dialogo que ira aparecer após a função Sat ser iniciada e ocorrer algum erro ou tudo ocorrer certo + static void dialogoSat(String messageText, {@required BuildContext context, double heightDialog = 100}) { + showDialog( + context: context, + child: AlertDialog( + title: Text("Retorno"), + content: Container( + height: heightDialog, + child: ListView( + children: [ + Text(messageText), + ], + ), + ), + actions: [ + FlatButton( + child: Text("Ok"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + } + + static Widget formField(TextEditingController textFormField, String textAntesForm, {TextInputType textInputType}) { + return Padding( + padding: const EdgeInsets.only(left: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + textAntesForm, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 30, + width: 140, + child: TextFormField( + keyboardType: textInputType, + controller: textFormField, + style: TextStyle( + fontSize: 14, + ), + ), + ), + ], + ), + ); + } +} diff --git a/TSG 800/pubspec.lock b/TSG 800/pubspec.lock index b1aabc3..ec8bc96 100644 --- a/TSG 800/pubspec.lock +++ b/TSG 800/pubspec.lock @@ -1,27 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "2.4.2" auto_size_text: dependency: "direct main" description: @@ -35,35 +21,35 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" - charcode: + version: "2.0.0" + characters: dependency: transitive description: - name: charcode + name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" - collection: + version: "1.0.0" + charcode: dependency: transitive description: - name: collection + name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" - convert: + version: "1.1.3" + clock: dependency: transitive description: - name: convert + name: clock url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" - crypto: + version: "1.0.1" + collection: dependency: transitive description: - name: crypto + name: collection url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "1.14.13" cupertino_icons: dependency: "direct main" description: @@ -71,11 +57,25 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_masked_text: + dependency: "direct main" + description: + name: flutter_masked_text + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.0" flutter_screenutil: dependency: "direct main" description: @@ -88,20 +88,13 @@ packages: description: flutter source: sdk version: "0.0.0" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.8" meta: dependency: transitive description: @@ -115,28 +108,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" + version: "1.7.0" sky_engine: dependency: transitive description: flutter @@ -148,14 +120,14 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.7.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.9.5" stream_channel: dependency: transitive description: @@ -183,14 +155,14 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.11" + version: "0.2.17" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.2.0" vector_math: dependency: transitive description: @@ -198,12 +170,5 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.0" sdks: - dart: ">=2.4.0 <3.0.0" + dart: ">=2.9.0-14.0.dev <3.0.0" diff --git a/TSG 800/pubspec.yaml b/TSG 800/pubspec.yaml index 49d94a0..9ace128 100644 --- a/TSG 800/pubspec.yaml +++ b/TSG 800/pubspec.yaml @@ -1,16 +1,6 @@ name: flutter_gertec description: A new Flutter project. -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html version: 1.0.0+1 environment: @@ -21,60 +11,18 @@ dependencies: sdk: flutter flutter_screenutil: ^0.5.2 auto_size_text: ^2.1.0 + flutter_masked_text: ^0.8.0 - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 dev_dependencies: flutter_test: sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: assets: - - assets/barcode.png - - assets/gertec.png - - assets/print.png - - assets/qr_code.png - - assets/nfc2.png - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages + - assets/ + - assets/xmlSat/arq_cancelamento.xml + - assets/xmlSat/arq_venda_008_Simples_Nacional.xml - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages + uses-material-design: true \ No newline at end of file