From e11fd52d6e6e6d88d5e2ac8b5da33556f7488241 Mon Sep 17 00:00:00 2001 From: Gertec Developer Date: Wed, 10 Jun 2020 09:42:27 -0300 Subject: [PATCH 1/6] Incluido exemplos M-Sitef e Ger7 no code sample --- .../org.eclipse.buildship.core.prefs | 11 + GPOS 700/android/app/build.gradle | 1 + .../example/flutter_gertec/MainActivity.java | 78 ++- GPOS 700/assets/pos-terminal.png | Bin 0 -> 6275 bytes GPOS 700/lib/config_tef/operacaoRetorno.dart | 374 +++++++++++++ GPOS 700/lib/config_tef/venda.dart | 88 +++ GPOS 700/lib/main.dart | 24 +- GPOS 700/lib/pages/CodigoDeBarraV1.dart | 153 ++++++ GPOS 700/lib/pages/imprimir.dart | 515 ++++++++++++++++++ GPOS 700/lib/pages/lerCartaoGEDI.dart | 84 +++ GPOS 700/lib/pages/lerCartaoID.dart | 84 +++ GPOS 700/lib/pages/tefs.dart | 496 +++++++++++++++++ GPOS 700/lib/serviceTet.dart | 340 ++++++++++++ 13 files changed, 2233 insertions(+), 15 deletions(-) create mode 100644 GPOS 700/assets/pos-terminal.png create mode 100644 GPOS 700/lib/config_tef/operacaoRetorno.dart create mode 100644 GPOS 700/lib/config_tef/venda.dart create mode 100644 GPOS 700/lib/pages/CodigoDeBarraV1.dart create mode 100644 GPOS 700/lib/pages/imprimir.dart create mode 100644 GPOS 700/lib/pages/lerCartaoGEDI.dart create mode 100644 GPOS 700/lib/pages/lerCartaoID.dart create mode 100644 GPOS 700/lib/pages/tefs.dart create mode 100644 GPOS 700/lib/serviceTet.dart diff --git a/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs b/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs index e889521..76847a5 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/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..a1e1788 100644 --- a/GPOS 700/android/app/build.gradle +++ b/GPOS 700/android/app/build.gradle @@ -89,6 +89,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/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..fea45e0 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,16 +1,27 @@ package com.example.flutter_gertec; import android.content.Intent; +import android.net.Uri; import android.nfc.Tag; import android.os.Build; import android.os.Bundle; import android.os.PersistableBundle; +import android.widget.Toast; + 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 io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugin.common.MethodChannel; @@ -28,9 +39,11 @@ public class MainActivity extends FlutterActivity { private IntentIntegrator qrScan; private String tipo; private ArrayList arrayListTipo; - private static final String[] CHANNEL = { "samples.flutter.dev/gedi" }; + private static final String CHANNEL = "samples.flutter.dev/gedi" ; private ConfigPrint configPrint = new ConfigPrint(); - + Intent intentGer7 = new Intent(Intent.ACTION_VIEW, Uri.parse("pos7api://pos7")); + Intent intentSitef = new Intent("br.com.softwareexpress.sitef.msitef.ACTIVITY_CLISITEF"); + Gson gson = new Gson(); public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); gertecPrinter.setConfigImpressao(configPrint); @@ -44,9 +57,12 @@ public MainActivity() { 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; + String json = null; + Map map; + Bundle bundle = new Bundle(); Intent intent = null; switch (call.method) { case "lernfcid": @@ -87,6 +103,19 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { intent = new Intent(this, CodigoBarrasV2.class); startActivity(intent); break; + case "realizarAcaoGer7": + json = call.argument("json"); + intentGer7.putExtra("jsonReq", json); + startActivityForResult(intentGer7, 4713); + break; + case "realizarAcaoMsitef": + map = call.argument("mapMsiTef"); + for (String key : map.keySet() ) { + bundle.putString(key, map.get(key)); + } + intentSitef.putExtras(bundle); + startActivityForResult(intentSitef, 4321); + break; case "imprimir": try { gertecPrinter.getStatusImpressora(); @@ -293,6 +322,25 @@ private void ImprimeTodasAsFucoes() { } } + 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")); + 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) { if (requestCode == 109) { if (resultCode == RESULT_OK && data != null) { @@ -306,15 +354,31 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten } else { _result.notImplemented(); } - } else { + } else if(requestCode == 4713){ + if (resultCode == RESULT_OK && data != null) { + _result.success( gson.toJson(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 { + Toast.makeText(getApplicationContext(), "m-SiTef Outro Codigo", Toast.LENGTH_LONG).show(); + _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/assets/pos-terminal.png b/GPOS 700/assets/pos-terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..3e66328a3e1e599890b252625f11bd3fb43cf2b1 GIT binary patch literal 6275 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 literal 0 HcmV?d00001 diff --git a/GPOS 700/lib/config_tef/operacaoRetorno.dart b/GPOS 700/lib/config_tef/operacaoRetorno.dart new file mode 100644 index 0000000..b7ce610 --- /dev/null +++ b/GPOS 700/lib/config_tef/operacaoRetorno.dart @@ -0,0 +1,374 @@ +///Classe de retorno, utilizada para atribuir o resultado do Tef 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; + } +} + +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 ?? ""; + get textoImpressoEstabelecimento => _viaESTABELECIMENTO ?? ""; + 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..b8b3677 100644 --- a/GPOS 700/lib/main.dart +++ b/GPOS 700/lib/main.dart @@ -1,10 +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_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/tefs.dart'; void main() => runApp(MyApp()); @@ -42,12 +43,13 @@ 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"}, ]; void trocarTela(int id) { switch (id) { @@ -79,6 +81,12 @@ class _MyHomePageState extends State { MaterialPageRoute(builder: (context) => PageLeituraCartaoID()), ); break; + case 5: + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageTef()), + ); + break; } } @@ -114,7 +122,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,14 +133,14 @@ 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"], + listaNomeFuncoes[index]["name"], style: TextStyle( fontWeight: FontWeight.bold, fontSize: ScreenUtil.instance.setSp(20.0), diff --git a/GPOS 700/lib/pages/CodigoDeBarraV1.dart b/GPOS 700/lib/pages/CodigoDeBarraV1.dart new file mode 100644 index 0000000..30c4777 --- /dev/null +++ b/GPOS 700/lib/pages/CodigoDeBarraV1.dart @@ -0,0 +1,153 @@ +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 { + 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..f1c73d1 --- /dev/null +++ b/GPOS 700/lib/pages/imprimir.dart @@ -0,0 +1,515 @@ +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 !"), + ); + }, + ); + } + + Future _impressaoDeTexto(String texto, int fontSize, String alinhar, + String fontFamily, List selectedOptions) async { + if (texto.isEmpty) { + erroImpresao(); + } else { + try { + await platform.invokeMethod('imprimir', { + "tipoImpressao": "Texto", + "mensagem": texto, + "alinhar": alinhar, + "size": fontSize, + "font": fontFamily, + "options": selectedOptions + }); + } 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(String img) 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 { + if (texto.isNotEmpty) { + try { + await platform.invokeMethod('imprimir', { + "tipoImpressao": "CodigoDeBarra", + "height": height, + "width": width, + "barCode": barCode, + "mensagem": texto + }); + } on PlatformException catch (e) { + print(e.message); + } + } else { + erroImpresao(); + } + } + + Future get _checarImpressora async { + try { + bool impressora = await platform.invokeMethod('checarImpressora'); + if (impressora == true) + return "Ok"; + else + return "Erro"; + } 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: 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: () { + _impressaoDeTexto( + myController.value.text.toString(), + dropdownValueSize, + alinhar, + dropdownFont, + listSelecionado); + }, + ), + ), + SizedBox( + width: 150, + child: RaisedButton( + child: Text( + 'IMPRIMIR IMAGEM', + style: TextStyle(fontSize: 12), + ), + onPressed: () { + _impressaoDeImagem("logogertec"); + }, + ), + ), + ], + ), + 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: () { + _impressaoDeCodigoDeBarra( + myController.value.text.toString(), + dropdownBarHeight, + dropdownBarWidth, + dropdownBarType); + }, + ), + ), + SizedBox( + width: 300, + child: RaisedButton( + child: Text( + 'IMPRIMIR TODAS FUNÇÕES', + style: TextStyle(fontSize: 15), + ), + onPressed: () { + _impressaoTodasFuncoes(); + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/GPOS 700/lib/pages/lerCartaoGEDI.dart b/GPOS 700/lib/pages/lerCartaoGEDI.dart new file mode 100644 index 0000000..16d65a7 --- /dev/null +++ b/GPOS 700/lib/pages/lerCartaoGEDI.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class PageLeituraCartaoGEDI extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'Flutter Demo', + 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..3ab4823 --- /dev/null +++ b/GPOS 700/lib/pages/lerCartaoID.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class PageLeituraCartaoID extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'Flutter Demo', + 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/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; + } +} From ff47a01f81bc0cf5bc49b675a9504ddf9dbcd474 Mon Sep 17 00:00:00 2001 From: Gertec Developer Date: Thu, 9 Jul 2020 13:38:38 -0300 Subject: [PATCH 2/6] Adicionado arquivos de README.md --- GPOS 700/README.md | 90 ++++++++++++++++++++++++++++++++++++++++++++- README.md | 90 +++++++++++++++++++++++++++++++++++++++++++++ TSG 800/README.md | 92 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 README.md 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/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 From 1c6134936b9d690e00b3902b7c82e2740cb8f8b2 Mon Sep 17 00:00:00 2001 From: Gertec Developer Date: Mon, 20 Jul 2020 16:22:24 -0300 Subject: [PATCH 3/6] Corrigido arquivo do git --- .../org.eclipse.buildship.core.prefs | 11 + GPOS 700/android/app/build.gradle | 19 +- .../android/app/src/debug/AndroidManifest.xml | 7 +- .../android/app/src/main/AndroidManifest.xml | 26 +- .../flutter_gertec/CodigoBarrasV2.java | 3 - .../com/example/flutter_gertec/LeitorNFC.java | 6 +- .../example/flutter_gertec/MainActivity.java | 135 ++-- .../main/res/layout/activity_leitor_n_f_c.xml | 1 - .../src/main/res/layout/codigo_barras2.xml | 1 - .../src/main/res/mipmap-xhdpi/gertec_one.png | Bin 0 -> 79059 bytes .../app/src/main/res/values/strings.xml | 2 +- GPOS 700/android/build.gradle | 2 +- GPOS 700/lib/config_tef/operacaoRetorno.dart | 7 +- GPOS 700/lib/main.dart | 6 +- GPOS 700/lib/pages/CodigoDeBarraV1.dart | 2 +- GPOS 700/lib/pages/imprimir.dart | 81 +- GPOS 700/lib/pages/lerCartaoGEDI.dart | 2 +- GPOS 700/lib/pages/lerCartaoID.dart | 2 +- GPOS 700/lib/pages/menus/tefs.dart | 765 ++++++++++++++++++ GPOS 700/lib/services/serviceTet.dart | 342 ++++++++ GPOS 700/pubspec.lock | 40 +- GPOS 700/pubspec.yaml | 9 +- 22 files changed, 1317 insertions(+), 152 deletions(-) create mode 100644 GPOS 700/android/app/src/main/res/mipmap-xhdpi/gertec_one.png create mode 100644 GPOS 700/lib/pages/menus/tefs.dart create mode 100644 GPOS 700/lib/services/serviceTet.dart 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 a1e1788..15ec084 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 { diff --git a/GPOS 700/android/app/src/debug/AndroidManifest.xml b/GPOS 700/android/app/src/debug/AndroidManifest.xml index 7806c92..3c1d60a 100644 --- a/GPOS 700/android/app/src/debug/AndroidManifest.xml +++ b/GPOS 700/android/app/src/debug/AndroidManifest.xml @@ -1,8 +1,9 @@ - + + + + diff --git a/GPOS 700/android/app/src/main/AndroidManifest.xml b/GPOS 700/android/app/src/main/AndroidManifest.xml index 7290d8f..f974ee6 100644 --- a/GPOS 700/android/app/src/main/AndroidManifest.xml +++ b/GPOS 700/android/app/src/main/AndroidManifest.xml @@ -1,21 +1,25 @@ + + - + + - - + android:icon="@mipmap/gertec_one" + tools:replace="android:icon , android:label" + android:label="GertecOne Flutter"> + + + @@ -32,23 +36,23 @@ 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/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 fea45e0..e5b9d35 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 @@ -2,13 +2,12 @@ import android.content.Intent; import android.net.Uri; -import android.nfc.Tag; import android.os.Build; import android.os.Bundle; import android.os.PersistableBundle; -import android.widget.Toast; import java.util.List; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -22,37 +21,51 @@ 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(); - Intent intentGer7 = new Intent(Intent.ACTION_VIEW, Uri.parse("pos7api://pos7")); - Intent intentSitef = new Intent("br.com.softwareexpress.sitef.msitef.ACTIVITY_CLISITEF"); + 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(); + gertecPrinter = new GertecPrinter(this); + } + public MainActivity() { super(); this.arrayListTipo = new ArrayList(); - gertecPrinter = new GertecPrinter(this); } public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { @@ -60,11 +73,11 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { _result = result; - String json = null; 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); @@ -74,6 +87,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); @@ -83,6 +97,7 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { result.notImplemented(); } break; + // Verifica o status da impressora case "checarImpressora": try { gertecPrinter.getStatusImpressora(); @@ -91,6 +106,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"); @@ -99,23 +116,46 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { e.printStackTrace(); } 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": - json = call.argument("json"); + 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() ) { + 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(); @@ -124,16 +164,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; @@ -144,19 +183,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(); @@ -179,7 +214,6 @@ private void startCamera() { } private void ImprimeTodasAsFucoes() { - configPrint.setItalico(false); configPrint.setNegrito(true); configPrint.setTamanho(20); @@ -315,33 +349,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")); - json.put("VIA_ESTABELECIMENTO",data.getStringExtra("VIA_ESTABELECIMENTO")); - json.put("VIA_CLIENTE",data.getStringExtra("VIA_CLIENTE")); - + 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")); @@ -354,13 +394,13 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten } else { _result.notImplemented(); } - } else if(requestCode == 4713){ + } else if (requestCode == 4713) { if (resultCode == RESULT_OK && data != null) { - _result.success( gson.toJson(data.getStringExtra("jsonResp"))); + _result.success(data.getStringExtra("jsonResp")); } else { _result.notImplemented(); } - } else if(requestCode == 4321){ + } else if (requestCode == 4321) { if (resultCode == RESULT_OK || resultCode == RESULT_CANCELED && data != null) { try { _result.success(respSitefToJson(data)); @@ -368,12 +408,9 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten e.printStackTrace(); } } else { - Toast.makeText(getApplicationContext(), "m-SiTef Outro Codigo", Toast.LENGTH_LONG).show(); _result.notImplemented(); } - } - - else { + } else { IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if (intentResult != null) { if (intentResult.getContents() == null) { 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 @@ *cL?sm7w+!v?jGDdSa1sj*Wi-;+55cj#rKW> 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 literal 0 HcmV?d00001 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/lib/config_tef/operacaoRetorno.dart b/GPOS 700/lib/config_tef/operacaoRetorno.dart index b7ce610..cb85846 100644 --- a/GPOS 700/lib/config_tef/operacaoRetorno.dart +++ b/GPOS 700/lib/config_tef/operacaoRetorno.dart @@ -1,4 +1,4 @@ -///Classe de retorno, utilizada para atribuir o resultado do Tef para um Json. +/// Classe de retorno, utilizada para atribuir o resultado do Tef Ger7 para um Json. class RetornoGer7 { String _version; String _status; @@ -285,6 +285,7 @@ class RetornoGer7 { } } +/// Classe de retorno, utilizada para atribuir o resultado do M-Sitef para um Json. class RetornoMsiTef { String _cODRESP; String _cOMPDADOSCONF; @@ -365,8 +366,8 @@ class RetornoMsiTef { } get getCodAutorizacao => _cODAUTORIZACAO ?? ""; - get textoImpressoEstabelecimento => _viaESTABELECIMENTO ?? ""; - get textoImpressoCliente => _viaCLIENTE ?? ""; + String get textoImpressoEstabelecimento => _viaESTABELECIMENTO ?? ""; + String get textoImpressoCliente => _viaCLIENTE ?? ""; get getCompDadosConf => _cOMPDADOSCONF ?? ""; get getCodResp => _cODRESP ?? ""; get getRedeAut => _rEDEAUT ?? ""; diff --git a/GPOS 700/lib/main.dart b/GPOS 700/lib/main.dart index b8b3677..3a04ee7 100644 --- a/GPOS 700/lib/main.dart +++ b/GPOS 700/lib/main.dart @@ -5,7 +5,7 @@ import 'package:flutter_gertec/pages/imprimir.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'pages/lerCartaoGEDI.dart'; import 'pages/lerCartaoID.dart'; -import 'pages/tefs.dart'; +import 'pages/menus/tefs.dart'; void main() => runApp(MyApp()); @@ -14,11 +14,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'), ); } } diff --git a/GPOS 700/lib/pages/CodigoDeBarraV1.dart b/GPOS 700/lib/pages/CodigoDeBarraV1.dart index 30c4777..fc5d36a 100644 --- a/GPOS 700/lib/pages/CodigoDeBarraV1.dart +++ b/GPOS 700/lib/pages/CodigoDeBarraV1.dart @@ -7,7 +7,7 @@ class PageCodigoDeBarraV1 extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, - title: 'Flutter Demo', + title: 'GertecOne Flutter', theme: ThemeData( primarySwatch: Colors.blue, ), diff --git a/GPOS 700/lib/pages/imprimir.dart b/GPOS 700/lib/pages/imprimir.dart index f1c73d1..a43379e 100644 --- a/GPOS 700/lib/pages/imprimir.dart +++ b/GPOS 700/lib/pages/imprimir.dart @@ -8,7 +8,7 @@ class PageImprimir extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, - title: 'Flutter Demo', + title: 'GertecOne Flutter', theme: ThemeData( primarySwatch: Colors.blue, ), @@ -67,20 +67,33 @@ class _Imprimir extends State { ); } - Future _impressaoDeTexto(String texto, int fontSize, String alinhar, - String fontFamily, List selectedOptions) async { + // 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, - "size": fontSize, - "font": fontFamily, - "options": selectedOptions - }); + 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); } @@ -97,7 +110,7 @@ class _Imprimir extends State { } } - Future _impressaoDeImagem(String img) async { + Future _impressaoDeImagem() async { try { await platform.invokeMethod('imprimir', { "tipoImpressao": "Imagem", @@ -108,14 +121,15 @@ class _Imprimir extends State { } Future _impressaoDeCodigoDeBarra( - String texto, int height, int width, String barCode) async { + {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, - "width": width, - "barCode": barCode, + "height": height ?? 200, + "width": width ?? 200, + "barCode": barCode ?? "QR_CODE", "mensagem": texto }); } on PlatformException catch (e) { @@ -126,7 +140,7 @@ class _Imprimir extends State { } } - Future get _checarImpressora async { + Future checarImpressora() async { try { bool impressora = await platform.invokeMethod('checarImpressora'); if (impressora == true) @@ -136,6 +150,7 @@ class _Imprimir extends State { } on PlatformException catch (e) { print(e.message); } + return "Erro"; } Widget build(BuildContext context) { @@ -173,7 +188,7 @@ class _Imprimir extends State { child: RaisedButton( child: Text("STATUS IMPRESSORA"), onPressed: () { - _checarImpressora.then((value) { + checarImpressora().then((value) { setState(() { showDialog( context: context, @@ -364,12 +379,15 @@ class _Imprimir extends State { style: TextStyle(fontSize: 12), ), onPressed: () { - _impressaoDeTexto( - myController.value.text.toString(), - dropdownValueSize, - alinhar, - dropdownFont, - listSelecionado); + // 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 }, ), ), @@ -381,7 +399,8 @@ class _Imprimir extends State { style: TextStyle(fontSize: 12), ), onPressed: () { - _impressaoDeImagem("logogertec"); + _impressaoDeImagem(); + finalizarImpressao(); // Limpa buffer de impressão }, ), ), @@ -486,11 +505,14 @@ class _Imprimir extends State { style: TextStyle(fontSize: 15), ), onPressed: () { + // Não precisa passar todos os parâmetros - Sera dado o valor DEFAULT _impressaoDeCodigoDeBarra( - myController.value.text.toString(), - dropdownBarHeight, - dropdownBarWidth, - dropdownBarType); + texto: myController.value.text.toString(), + height: dropdownBarHeight, + width: dropdownBarWidth, + barCode: dropdownBarType, + ); + finalizarImpressao(); // Limpa buffer de impressão }, ), ), @@ -503,6 +525,7 @@ class _Imprimir extends State { ), onPressed: () { _impressaoTodasFuncoes(); + finalizarImpressao(); // Limpa buffer de impressão }, ), ), diff --git a/GPOS 700/lib/pages/lerCartaoGEDI.dart b/GPOS 700/lib/pages/lerCartaoGEDI.dart index 16d65a7..d901935 100644 --- a/GPOS 700/lib/pages/lerCartaoGEDI.dart +++ b/GPOS 700/lib/pages/lerCartaoGEDI.dart @@ -6,7 +6,7 @@ class PageLeituraCartaoGEDI extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, - title: 'Flutter Demo', + title: 'GertecOne Flutter', theme: ThemeData( primarySwatch: Colors.blue, ), diff --git a/GPOS 700/lib/pages/lerCartaoID.dart b/GPOS 700/lib/pages/lerCartaoID.dart index 3ab4823..4722aa0 100644 --- a/GPOS 700/lib/pages/lerCartaoID.dart +++ b/GPOS 700/lib/pages/lerCartaoID.dart @@ -6,7 +6,7 @@ class PageLeituraCartaoID extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, - title: 'Flutter Demo', + title: 'GertecOne Flutter', theme: ThemeData( primarySwatch: Colors.blue, ), diff --git a/GPOS 700/lib/pages/menus/tefs.dart b/GPOS 700/lib/pages/menus/tefs.dart new file mode 100644 index 0000000..67487ee --- /dev/null +++ b/GPOS 700/lib/pages/menus/tefs.dart @@ -0,0 +1,765 @@ +import 'dart:io'; + +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 Msitef + tefService.setHabilitarImpressao = habilitarImpressao; + 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), + ), + ], + ), + ), + Row( + children: [ + Checkbox( + value: habilitarImpressao, + onChanged: alterarValorImpressao), + Text( + "Habilitar impressão", + style: TextStyle(fontSize: 15), + ) + ], + ), + 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 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/services/serviceTet.dart b/GPOS 700/lib/services/serviceTet.dart new file mode 100644 index 0000000..9f98166 --- /dev/null +++ b/GPOS 700/lib/services/serviceTet.dart @@ -0,0 +1,342 @@ +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"; + 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"; + 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"; + 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"; + 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/pubspec.lock b/GPOS 700/pubspec.lock index b1aabc3..f19d580 100644 --- a/GPOS 700/pubspec.lock +++ b/GPOS 700/pubspec.lock @@ -7,21 +7,21 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.13" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.5.2" + version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "2.4.1" auto_size_text: dependency: "direct main" description: @@ -35,21 +35,21 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "2.0.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.3" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" + version: "1.14.12" convert: dependency: transitive description: @@ -63,7 +63,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.4" cupertino_icons: dependency: "direct main" description: @@ -76,6 +76,13 @@ packages: 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: @@ -94,7 +101,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.12" matcher: dependency: transitive description: @@ -116,13 +123,6 @@ packages: 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: @@ -136,7 +136,7 @@ packages: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.1.3" sky_engine: dependency: transitive description: flutter @@ -148,7 +148,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.7.0" stack_trace: dependency: transitive description: @@ -183,7 +183,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.11" + version: "0.2.15" typed_data: dependency: transitive description: @@ -204,6 +204,6 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.5.0" + version: "3.6.1" sdks: - dart: ">=2.4.0 <3.0.0" + dart: ">=2.6.0 <3.0.0" diff --git a/GPOS 700/pubspec.yaml b/GPOS 700/pubspec.yaml index ad5f0a3..f0bacb1 100644 --- a/GPOS 700/pubspec.yaml +++ b/GPOS 700/pubspec.yaml @@ -21,6 +21,8 @@ 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. @@ -37,12 +39,7 @@ dev_dependencies: # 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 + - assets/ # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in From 0eae8edacee9a71344a73a363f5492402794d32b Mon Sep 17 00:00:00 2001 From: Gertec Developer Date: Tue, 1 Sep 2020 15:41:08 -0300 Subject: [PATCH 4/6] =?UTF-8?q?Incluido=20exemplo=20de=20integra=C3=A7?= =?UTF-8?q?=C3=A3o=20com=20o=20SAT=20para=20os=20equipamentos=20GPOS=20700?= =?UTF-8?q?=20e=20TSG=20800.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org.eclipse.buildship.core.prefs | 2 +- GPOS 700/android/app/.classpath | 2 +- GPOS 700/android/app/build.gradle | 2 +- GPOS 700/android/app/libs/SatGerLib.aar | Bin 0 -> 96783 bytes .../android/app/src/debug/AndroidManifest.xml | 1 + .../android/app/src/main/AndroidManifest.xml | 13 + .../example/flutter_gertec/MainActivity.java | 74 +++ .../com/example/flutter_gertec/SatLib.java | 337 ++++++++++++ GPOS 700/android/device-2020-03-20-192953.png | Bin 0 -> 48939 bytes GPOS 700/assets/iconSat.png | Bin 0 -> 2131 bytes GPOS 700/assets/xmlSat/arq_cancelamento.xml | 13 + .../xmlSat/arq_venda_008_Simples_Nacional.xml | 64 +++ GPOS 700/lib/main.dart | 20 +- GPOS 700/lib/pages/CodigoDeBarraV1.dart | 29 +- GPOS 700/lib/pages/imprimir.dart | 85 +-- GPOS 700/lib/pages/lerCartaoGEDI.dart | 8 +- GPOS 700/lib/pages/lerCartaoID.dart | 8 +- GPOS 700/lib/pages/menus/sat.dart | 81 +++ GPOS 700/lib/pages/menus/tefs.dart | 125 +++-- .../lib/pages/sat_pages/alterarCodigo.dart | 135 +++++ GPOS 700/lib/pages/sat_pages/associarSat.dart | 102 ++++ GPOS 700/lib/pages/sat_pages/ativarSat.dart | 92 ++++ GPOS 700/lib/pages/sat_pages/configRede.dart | 304 +++++++++++ .../lib/pages/sat_pages/ferramentasSat.dart | 100 ++++ GPOS 700/lib/pages/sat_pages/testeSat.dart | 206 ++++++++ GPOS 700/lib/services/globalValues.dart | 5 + GPOS 700/lib/services/operacaoSat.dart | 170 ++++++ GPOS 700/lib/services/retornoSat.dart | 284 ++++++++++ GPOS 700/lib/services/serviceTet.dart | 58 +- GPOS 700/lib/util/common_code.dart | 20 + GPOS 700/lib/widgets/widgetsgertec.dart | 74 +++ GPOS 700/pubspec.lock | 87 +-- GPOS 700/pubspec.yaml | 57 +- .../org.eclipse.buildship.core.prefs | 11 + TSG 800/android/app/.classpath | 2 +- .../org.eclipse.buildship.core.prefs | 11 + TSG 800/android/app/build.gradle | 21 +- TSG 800/android/app/libs/SatGerLib.aar | Bin 0 -> 96783 bytes .../android/app/src/main/AndroidManifest.xml | 23 +- .../example/flutter_gertec/GertecPrinter.java | 229 ++++---- .../example/flutter_gertec/MainActivity.java | 164 ++++-- .../example/flutter_gertec/NfcFormatar.java | 23 +- .../example/flutter_gertec/NfcLeitura.java | 11 +- .../com/example/flutter_gertec/SatLib.java | 337 ++++++++++++ .../src/main/res/mipmap-xhdpi/gertec_one.png | Bin 0 -> 79059 bytes TSG 800/assets/iconSat.png | Bin 0 -> 2131 bytes TSG 800/assets/xmlSat/arq_cancelamento.xml | 13 + .../xmlSat/arq_venda_008_Simples_Nacional.xml | 64 +++ TSG 800/lib/main.dart | 35 +- TSG 800/lib/menus/sat.dart | 111 ++++ TSG 800/lib/pages/CodigoDeBarraV1.dart | 139 +++++ TSG 800/lib/pages/imprimir.dart | 495 ++++++++++++++++++ TSG 800/lib/pages/lerCartaoNfc.dart | 146 ++++++ .../lib/pages/sat_pages/alterarCodigo.dart | 135 +++++ TSG 800/lib/pages/sat_pages/associarSat.dart | 102 ++++ TSG 800/lib/pages/sat_pages/ativarSat.dart | 92 ++++ TSG 800/lib/pages/sat_pages/configRede.dart | 304 +++++++++++ .../lib/pages/sat_pages/ferramentasSat.dart | 100 ++++ TSG 800/lib/pages/sat_pages/testeSat.dart | 206 ++++++++ TSG 800/lib/services/operacaoSat.dart | 170 ++++++ TSG 800/lib/services/retornoSat.dart | 284 ++++++++++ TSG 800/lib/services/widgetsgertec.dart | 74 +++ TSG 800/lib/util/common_code.dart | 20 + TSG 800/lib/util/globalValues.dart | 5 + TSG 800/lib/widgets/widgetsgertec.dart | 74 +++ TSG 800/pubspec.lock | 105 ++-- TSG 800/pubspec.yaml | 62 +-- 67 files changed, 5479 insertions(+), 647 deletions(-) create mode 100644 GPOS 700/android/app/libs/SatGerLib.aar create mode 100644 GPOS 700/android/app/src/main/java/com/example/flutter_gertec/SatLib.java create mode 100644 GPOS 700/android/device-2020-03-20-192953.png create mode 100644 GPOS 700/assets/iconSat.png create mode 100644 GPOS 700/assets/xmlSat/arq_cancelamento.xml create mode 100644 GPOS 700/assets/xmlSat/arq_venda_008_Simples_Nacional.xml create mode 100644 GPOS 700/lib/pages/menus/sat.dart create mode 100644 GPOS 700/lib/pages/sat_pages/alterarCodigo.dart create mode 100644 GPOS 700/lib/pages/sat_pages/associarSat.dart create mode 100644 GPOS 700/lib/pages/sat_pages/ativarSat.dart create mode 100644 GPOS 700/lib/pages/sat_pages/configRede.dart create mode 100644 GPOS 700/lib/pages/sat_pages/ferramentasSat.dart create mode 100644 GPOS 700/lib/pages/sat_pages/testeSat.dart create mode 100644 GPOS 700/lib/services/globalValues.dart create mode 100644 GPOS 700/lib/services/operacaoSat.dart create mode 100644 GPOS 700/lib/services/retornoSat.dart create mode 100644 GPOS 700/lib/util/common_code.dart create mode 100644 GPOS 700/lib/widgets/widgetsgertec.dart create mode 100644 TSG 800/android/app/libs/SatGerLib.aar create mode 100644 TSG 800/android/app/src/main/java/com/example/flutter_gertec/SatLib.java create mode 100644 TSG 800/android/app/src/main/res/mipmap-xhdpi/gertec_one.png create mode 100644 TSG 800/assets/iconSat.png create mode 100644 TSG 800/assets/xmlSat/arq_cancelamento.xml create mode 100644 TSG 800/assets/xmlSat/arq_venda_008_Simples_Nacional.xml create mode 100644 TSG 800/lib/menus/sat.dart create mode 100644 TSG 800/lib/pages/CodigoDeBarraV1.dart create mode 100644 TSG 800/lib/pages/imprimir.dart create mode 100644 TSG 800/lib/pages/lerCartaoNfc.dart create mode 100644 TSG 800/lib/pages/sat_pages/alterarCodigo.dart create mode 100644 TSG 800/lib/pages/sat_pages/associarSat.dart create mode 100644 TSG 800/lib/pages/sat_pages/ativarSat.dart create mode 100644 TSG 800/lib/pages/sat_pages/configRede.dart create mode 100644 TSG 800/lib/pages/sat_pages/ferramentasSat.dart create mode 100644 TSG 800/lib/pages/sat_pages/testeSat.dart create mode 100644 TSG 800/lib/services/operacaoSat.dart create mode 100644 TSG 800/lib/services/retornoSat.dart create mode 100644 TSG 800/lib/services/widgetsgertec.dart create mode 100644 TSG 800/lib/util/common_code.dart create mode 100644 TSG 800/lib/util/globalValues.dart create mode 100644 TSG 800/lib/widgets/widgetsgertec.dart diff --git a/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs b/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs index 76847a5..27b37ed 100644 --- a/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs +++ b/GPOS 700/android/.settings/org.eclipse.buildship.core.prefs @@ -5,7 +5,7 @@ connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= eclipse.preferences.version=1 gradle.user.home= -java.home=C\:/Program Files/Java/jdk1.8.0_241 +java.home=C\:/Program Files/Java/jdk-11.0.8 jvm.arguments= offline.mode=false override.workspace.settings=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/build.gradle b/GPOS 700/android/app/build.gradle index 15ec084..90312f8 100644 --- a/GPOS 700/android/app/build.gradle +++ b/GPOS 700/android/app/build.gradle @@ -69,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' diff --git a/GPOS 700/android/app/libs/SatGerLib.aar b/GPOS 700/android/app/libs/SatGerLib.aar new file mode 100644 index 0000000000000000000000000000000000000000..75f1fbc22b3370b0a6d7378607ce7a25c5cb1820 GIT binary patch literal 96783 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

7du(9gU)7j#8JCNeK>rvk+Sn*1B7R*Lmuk zsrpJdPePavz82046?~4IIX7TmJ;%b|_eXYfERjK4Fcdm!QrOpX+ z{2(4`osgd;vZC+geyyhbz{@yU)B;QX3FR!C*V@Nm9$_if3}}9B@^do93k3T`2rn|b z%>B*k4e_I8;_EUNhk&5Dw8e zw-Ed%iHn2)P;n73@_@AaFlOz-MQ!71c}7J}ckiw8hJl1mK;1nsOBPUi1AqtClJG#g z4j85l(4}&uBQCGU5lR?Vkyyw3@b)QTmQ~6*^+w-9XVaU{5^+Th!&5D&NCjWkdBNdf z^5MP4g89Vc6klgeE%6}m{M~&=ikIAxZi?AcxEHMv#7zh>3meD0?g2jK%Rx3&`U@Z2Xz9AHj1<4Q;%=ub<; zsp}e@uw=2nKfr8{#(kMAA^yz2XS{{*I4YUGsmNztzAr3|`||rrVP@Ojv}Je+z8->= zt|z{XsJhg>u>Ev?u&|P$xVJB4%iBAXi3SF5UCpsddd{eWrl|ycWHzt?z*WaEE0H{0`4IZ)ye^hzEpJJIj!9n#K$Eq6dfp!KPz~A!jUxW`Q(`GlXAxAjZuia z8N5feZ}_0}1#u)sObN_tC|;M^UI@G5{6R(kdi)&agtEG-yo#k42`Yq~vAst5m^IHS z<*YWN`9fZ)rz5`LGFc_%+ze84*u`)1o)gRiR5d4)xIv@AIM2{k+~z&AxY{SqRtA_z ztlP+;CSNFqWZke3UZRAS@+-l4SX=HUZbb;Pe}kh^Z~DM)1)yeEAFP? zF~~~l(OuPOo{N}k77*Lc9G=U=hW7oG;p|<|q~PjxyY0>J`AN5nd<}F97I;pO-uXEI zLQa^i3|e?o{3WNMx!t>1dEx3|YRUU@tBgb)60Z-UER0|g$&LN-jo|f#qovv#;@D?i z;CXbNMuHf!$qk_R%%pd6;8yg=Nrp27N$}JotVV(3p<|fT`(0qdz5?exuU+iu8OSB* zpCd1z!d3|__1$co9RF)E5%$fW!55HWpRJ6no&MDb`_{t!`(guKT@vm?I#sBM_0$E^1nhjIb}8)VS!bi!JNaEqW?^}zKJj* zaqHLiHfFCC^{vf}jT{_r1FZZ`fQG!T-|r6x=MxVHce~#GBjx(~@WR0vTIxGE7&)++ z>)ZbhyfsAl!}_-5-xChpuDDa<_dqcJhWN|XEh703#2;L_{=#(r;k)QRB>c(bpzo+>Vq~ue zThaeJ!ds3XwSe{~;cc0?o4ynNry>7dB1}uLN*m1F26pRi0|fm@xxU&z!)~$vSe68y z^6YjP&=ST${(}IP=lZHP|K$2V9REWp{(6dTOQG`V52{~#n%~RQQCP;Kb{7s#6L!)3 zq9yR}3Cs-jEcKnN4NYNTe{8Kye&@TT_))FD3L@$MMbMAF>~{iMFlB8HtW~AMu3rTy z{yo9}An5*|1-z{xj`3dv{n`2buBenHjAa(qoo&IcUmv~K|G@A+NW%X`lF!DklKxRs zy%~2C5(OL_1MH&vlj8Ofs{JR5|3TERZTt!a{y*WN{^<07ub$rni~UfO>&t-p3-CMs z|JN4(YE-xPNa4=U6hDt7zsu?oPO=AzoNtc=O@m8L)^xK`krp(B4B(+{55|5j{Q9{ z)DLv7FUNmjfBT{IcdA?H58<~{lJDtOhCaogGX5N#e@Fj*g6wYpufYF7!0im?d%C?1 z8nDslA4ct4qaXL~ui4Bk2nYlH?XdVW5cbZz2Ca2HhI}@b@ct^e^x~jTb+I ze|^vptp4=;kNxP+=-Zj__jIe9>nHU83I1#K8p7cJ&|%*C_)*;3S@QRE>oe?6&`*8R ze?1$w_CN5y_6bce{NHs(KO=5u(BIRo$3+<8pZkMbyC0rz=hNTQEe_rKKe&Hvz_*q^ qkiTl=gCYN}z5R^%wJJ5gBfd8iWLPXsI5;-gpDV0E`NF<}gZqE&q*san literal 0 HcmV?d00001 diff --git a/GPOS 700/android/app/src/debug/AndroidManifest.xml b/GPOS 700/android/app/src/debug/AndroidManifest.xml index 3c1d60a..9f04d6b 100644 --- a/GPOS 700/android/app/src/debug/AndroidManifest.xml +++ b/GPOS 700/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,7 @@ + diff --git a/GPOS 700/android/app/src/main/AndroidManifest.xml b/GPOS 700/android/app/src/main/AndroidManifest.xml index f974ee6..e5de1b1 100644 --- a/GPOS 700/android/app/src/main/AndroidManifest.xml +++ b/GPOS 700/android/app/src/main/AndroidManifest.xml @@ -4,6 +4,12 @@ package="com.example.flutter_gertec"> + + + + + + @@ -42,6 +48,13 @@ + + + + + + + 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 e5b9d35..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 @@ -6,6 +6,7 @@ import android.os.Bundle; import android.os.PersistableBundle; +import java.io.IOException; import java.util.List; import androidx.annotation.NonNull; @@ -42,6 +43,7 @@ public class MainActivity extends FlutterActivity { private ArrayList arrayListTipo; 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 @@ -60,6 +62,8 @@ public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableB @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); } @@ -116,6 +120,76 @@ 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": 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/device-2020-03-20-192953.png b/GPOS 700/android/device-2020-03-20-192953.png new file mode 100644 index 0000000000000000000000000000000000000000..7e0c47612a5dc621cee83d0d1157680b93304387 GIT binary patch literal 48939 zcmeFYbyQSg_cjayN~eT$C@7sn_W&X#B3()-T|>7@HzI;`C?MS(N(~_;(hS`-^Z-M= zXT<0Eed}G{yVm>fx7PQEOC1hp?sMOJU;DbQy-)aabtM8^YFsolGy>(P;1_6UcZSi> zu+XsY0-rbxT1uj!;k>t&mwyg=4Nf@%4O|9+ypFWMUxGPhul1A``f8gDMH+qjs8!=YGc?IlhU!t9Av z?baN${c20NN6t)d^B$F1lrQ6so^ue@xBrxjx$F*?i#hKWZyP*7xalqOqd9#|E>jg@ zU+F1Rm3(BO&MA$9HdUHV&zhgoyG&1f*7G+^V=XLjGk_)X_< z>qh71n-Qt@tHbCyJwMnz;@l;;-BF+LtF}96PtL`)#PQKAh0*9F1K!3%(Kk5JWiFnu zrDq;+$>ZD;WJJTw!g!E{{qh~_FqYyEe7!q{3z)O-g!k_;y<%Ai)QiJBV~=Yeu)Do7&*H?s zVmy$w>!EgeFTrH`7!x{^F32vh zS$J{sI&jPH786yy7N5j84Hf>u=Y*Svwf+;ifLl*5h2`-hY0+>Wn={a~9S>V33>!mJ z(Uk$&|S(Hri^+Q-=5xL1T9e)95i zMm^{zCwm_bwJ?w14dt^>R!L_1_3#aPWLMuSw{jglM>|XqL27JCXGXh8C!u+MIouhX zMmmVS9);I+;M7p>VkA&{PdF;In`^P_V9OJ)SvVtdK7yxPc%kXQV_)m+(R<8y3gyga zWJ@?r*yKSv?b_`kiv;mcUoxeT`Gq-mrg!2lSueRQVIE+FKl{xp8rS}G^Q+%ivac#% zL%#}J@auoDQz3kmACHJn?a}Sg=!JJ#nR%Nzm>E^jnT?sznRS?zJ@$+c>x!w2|ETaJ zKkeIW_OI~eE}>4kPL|HPNZrUxG6pi!xGZI=XPzn#mG3JHs?5eEXPbSee#yq3l%gc5 z*dmwyl}S)L1tVI1M$I&;V!uR|&?9z{RGcvSaPN5v%WJ}+^| z-Hzz^p2u&}UPtjuJ$v$WN?Ad9H_;}M`m@2O&k41OF(0|(91`f`uOD}Oa{j0sH^nph z#$Q%e^QQune)fyS zi1svQ`4JsHlM2-eC1;)RJd2Y1`7iTaH8-)eK3YRnEp&L1$wz&MeWiVyeQtdp`c&9C z6VVcl5pEtC-)7 zuadIb-Dg%)-YwLd0!n$3a*~3m;We-;!7S-8@ThrhPqwSKYqKjZRvzW;SGHp+?+ot-?{x372e-SDc(zK->S2g&q zr=T~ck5l|*d~sZ<1Pjy$A_1L%hU~QM8)~C#N8JtF58U&2Or~fik9KEvDd{+AYekJ* zz_iA+c(nJ@3)IoowbeD!wbRVg4Aa()RgEf*xf^nfC5;eGF%3`Zoo7>K*I)y)bqxrw zIEhP%LWvA78=phTrj}Pc9%UFN%eG?^hvV+v7>>elj5&?*it%s7$gX?KRfGA{>kVbu zjxmmH36ITGIpNIzbW4he3BRaa0hD_LG5E}W$M8Llx(tB>|CKpYNpm0pka*+ixFjHKXhMH^ItzSR%z9f zk`AzoUCo$=YtBRcr0YFS=K5MpaqF>!@d$AH@ubO}BOI<@oym6*^&@i-1Qe+h3{QT3 z+JB~qnAwrmXV*;87W4YCEu-|HsyJ(B_ov!D$4@j#6ZFiq&!is~>=$nozAWPWe)*Ez zQ0RrdDNKjOw5smS0WV^IpJaxmqz1PpxP~FNo6hg~`ilw8GEGx|d|G?uv8N7c5EF1TK7 zQc4Hk2zqxftHSk9r^YkK0!pp(Ybaf1=nTcz#LdOAjG2t(*Jp=L+zs99ZgLR);YWSz zMLbVU9`7+7ubgn2{%WjudUF1Ib~U*_p(WLu!4#*}rEMtRala5cwmp$nX1rOq-R23~ zx;Uqy5FUhC%GzmFJ*q0-az1wfSrKvdB$>!EdsVT zPpvP`FG$UM@ru($3!eYJ(uL1Xbe4%C-e2!%kP(?7p67-_GHPp+^Qn# z_!37xr=A}L&JXMU%uA`QO0r4wWa^|ir0}JPN^eW}Ai6FnwRjRtxd&EnxDR{=I0kg3 zZ(bvzKYaHu|JYt{uS!SG^)!nfjGx)V+Z%)P;UDL?xG0*FyaEm}kn%Ustk_YNFPY_; z>{7OVd)G?`mcF9aUivF{m??=H0(-E)+>9>h@pxfIGXMKWmkdomCaO{s<$^jY_|Pt^ z(D$1OWGuwF84J{B&87%wKb9x7c^U2cE>+0rL?iYO4!S07P zf;RZ1MXhGh8fmu^SN z6N*~YES)zW4Q_Kc@3;RXt{x>FIqDMPZo51b!reGGqiZ<*cQF}c>wCWYdS-w>S>Lvt z1m*08bth{`{eZl3G0W}Ky=IP)IP4*R?;%Cvx7V=F{ZxW-o1>KPliSr?jObeOo*&%D z)MHR|z50e8d87*sXUmx6GHq?pjZ(S8gL06^EWQ@ znK1Sk@JUyfI$!zTQg?gEVDM02;B`{Kd6IU7M9j8*9jsQJZbP0(vKrYf+*5&uOE)kmO^earEiX;;Zn${A^(X9);OM~oyr=2 z$L%cxC7DnlkX~zQYQ{uBj#C9GNY|-UWK09DPKw-=89W!>!Cf*ZbYx6DU~U`@RjAd^ zr%f(J2@GyrpJ(29b*oED;LJ8Lht~78M9j(pg&W&Um%b;!ww3wq z+7|gaCeRyVx}u^LM7>7#Gi@_iY{VSL>L5z{szWqg@$QAj^@@g0b4WplFT>G6Y=G}0 zrbgGz-`f7yzIToX#o+;{`*`yA__i`DotPrIhEw){mknrsz+8bYZNx1h2Bd4Fu@ZHab4*CZTAgoi<04At= zI}RK8b_bVZoPNO$PKXvi17JDPcY95Hk?=+Rm=jR0*{DBONSu16N- z7C81%*1B!P+2y))o56uZwh5(Gqbi0S$1<#=3Xq{ zR_gDVQi70x%YPn^cvxOw z#2nj7jS_718e`Ts=GfP3!@5~Ib<>Wx7?BlwezqLTuzRFCM#Y~QSc{|i*=xgVfA0Dk ze&e6s`Y%`P_DN!tmuSsvoQfT?`U*n|R6E{DttFc`wq4D%8Cyfrn-BCd+t}?yj9PuY znph2#EsEAp!DY(e37?{X@iCu&`K-7oLlg~(5)Ch(-Dn*ZGqp1}xMOg?y}HfYugtIa zQ4+q?JzL~?!tb(cWPZR!ej=+z>3?yDz(l5udyua-@VdY4vOf_#CuqBK!Kq*QRY>!X z?Y8#mN$8soe*OVxyztFH;d1QJX*T_{}ZiQEVQ-}kf;ZX^_zLAce_A&Oj*&m zWdVXlValo(=Z~IK9-bf7ScF;1b=lH=B!Xy17Q`ih-i(N1N}l{H+S* zKgEZO$VSX@t++SiCc7IchEq77U0xtc>gL4ak6MAlV7Qz6N4oPIxR1f>8-{haJ!nB| zDsnE*k4W)f%#jX5mT7@Iv`)OClczhS}IJ!8;*N$R=qL4_fBr-QaU%la`Hy0DBT9>9bC#C}bsq9}QtKa>_jU>F%iD}8I^X@DFreJeUUfTODk4_cq#KaIrf0!> zi$npQh)Jkaty~-`>usa-d4lxjHGnjYez3H8 z;@j9Ih;Rgm3T*xgHZOE=c~Tb8g0rw)*48S1zLL;%g_v)facJ6YT$hAqefB>&B%#sT5^=BuljxzpM`6#qf-y1mk-y)AlR!FxQ{OFYvPF=2$a zxiOjb_}~&%8V3AYuTE#0i2V0Iz~YtYr&_L0%HXwg-rIW<0ap`EQ0eOf7z_PD*xuWK z)3>_y!`HL(@P_pan5Giln9)Y8|8XwN4*{F-J1H{VZ9N}w1ick!1|$F~?_Pg+=XqTv zjjY-`%DnOQfYN!mCKF3Dy@SB|c{Y)s6@pCqfDATt`D@6P z$Y-)+IunVsubs;C>7bb_XYM=j0qQl3vUNXruk3oO>~F=4CZoH}!SY3!mFq=@>(?IZ z=^pM$rv6@$4zx}`&|&>1rB|mS>}5}E_077X^p<9< z&AFA=hOzt9H}T8;j#TU$;83TGb{&0}X$Hbsb0Dqqx5z>vS=l$c6zjXf0-Ji93F88a z=8W5fvEkl1WxxSt>WnJy%`nl`bHoSfvkx$$%O6D50my*&7y15M`6=S|T8nt5XYCGU zEvGhK8#Ip16@M$D-Q)Y@z32aqMelf0S=B zB~6GqpQcFe#sZxAiPqB^7{C*!4hO&oTbRcPe>kF)c%*U!L|xcC1K@lk@Ta!vY$-A| zjDm#Z|G7M?{(9tI)6AN*n=2qu%X%2`scqZ%)v4o+ zd)<%}(v>aENzP+TTURJFb=02aHHa+aR`c0a-)ZFe+9k5`Z8b0RC~dvE>}b5MwMHB$ zofVKqQrX z=?G~zyfQIcP4g#VHkV# zJ;`^yNALLx5uw|hWBJ80C48w*tn5km&*0Mo=~Hv*aaQt(_dBh~J(x0E`X2+S>jk3g zEaYKQ+ic;{i~qUZIf{+3+BmkHjPG5+0|ICkTY#Lep$cVU@8o^`>oq-dj$c~rx{36r zvW5+YKB3gv!rm`|p&f_%#gILKk-J7le;o$|`QOabWKOV~45zIw=Fhf0njbfGgqhL0 z41=)yL_sXXXzZp0Q>OWKcBUXEb&0k0OMoKn^?71t0btyR?QN zIM(}5?sQN)D(hzeU29kZOZS+Yx*B1)8hKXZ-ax^0TcjiJaPy*bBwVfo;+QMf_k1l=j0?s;`-by2VuNws2#v&&>$w2sLmFsrO)?vRLbB1l;!s@*NM}LUz3S*9FFYRjf9RrgTbFOP9 zr7INXk4?7#o`h8@IjUH+`7FG zX1THDbh^l=SHaE)r5;9mLA z+XedSg5^|YRo~BCL_7NCx-mtn1_mC#y^aZ6y<0{kyXjU$d9jx2XrgKRHiwbYpeRJ| zuBL=?N%~!)^xql*7o&!pL3ky*@}D|F+57rnt0jD<9`rI zz+EhTSmQJ5TaW@!l4jAA-F;Wtw zG@vl(55)-n_BX^rTTDFaMCmUdC@QPTW|2$nmGo)c~=>fRHf3>Kzu~7Wx^2o3w`1K>jFol@ZV#}h6ahWttup49&|R}^D+f8k}dbXwWZy-g^6xevl$ z#p3aloq2Bc67jIcotdHWt6#?B&=~6+BObx{J-vP}4f=oem4>8KK={Pg6lnlS?-D?j z`?aMAIa=3YSv3*TT+sR=KqLJA0x-(UX(H2*sIdI78msWw;+qOM){m0{-NdvcT`d5` zJeqV{wzRqWeg;$YCs$KWuWtm`J~=>XXhR7RX%uZSunRg;1FxIl{@v$xMbdfVrt$~R z$G;?S%KHLjzfRq9DdDJaa94lGTPKqL65u!9H2m#TK#jL=f_cohDA3Fy=Me6?rhaZ7 z0B#DsR{j+0ClRA?2|f<$SxrM(Ib3}QC=i69d=~XTcw7R;nuIK^0m!<5CNApw;ksFu z{s=|FvQ*@g+l{9Q4_wRY<0Wea=Ua6f&K-W<^YCByNO|smxy&%XwP07EwR<0)$F>BIm*Es*sS& z%Wvtit8(IVT(y%q|1FAs_B0&n;_JK!ty^3JeY~tX_=A`a2tdTg`hNA9N6t;qx%4po zC5W?cD((?-vekm$E)K1J5N(>ZVy>B;LRotXPr&T#ED|AMrJF(IN+SdFf2GAVIV9=UTh5jI?lEFMbn}NE4LrVFl(9;^|td%a^IPGGY|4GqqJ@^GDF19JR zAi_vkP*b9sGR2mw`?bI#K-4a4^@t5C!e1D5+OGchtI(i2n6gEkoB5e@K<4`YWmTUc z6f@7SbjU8(a5r4CMH^9+&A@n8$IyOkx9#Q{=Cz(a0Xpo}CQC9} z6k(_{^ZXN=#3Igs8tXOJoe+n|J3JJeykJpv$&){8wf(+jLltZP0Ez|IN)xX`HU`+V z@zS5ltfb+pLJma{qGyoy7j>1&0e3$W&n+<+S^154=Ws0X>S!qh+!uX~yce*4Pi@$C zh1Y0RbjV9R(j{52M?b^SnRh-!E)pw~W&B0Uuo9iyOOFl$;p$(AN$13W74PI>mSr%3 z0$-tbe!9C&qGQ`WUfZxFfYbJ)NF6qA6<^Y1Gm^Hm$hOH@{V(Px?ia~LiRONS+QfT@ zuxZ(52DnN>H;Of^rI2;G;oFL-o6X4mbnf$O+fd-yn!6aUb5Anywl2C}uGal#?42!t z%SK4BH&|jsa>mB3=Y~Zzm&-!2H?B8qxvTFI33+bq``U9?a~@9)+6hHDwTmvPByrno z64v-Kv%C4qW4g}U2mCUpA5GhlM9fy5sLcdg$3^`@=>5+VJ^!cb}fWT6oCUS8b2Gh3{bKyswV8L+Nh?=ko~Aq?A247u>QmW_9r z<;`fNK9dc!_+N}>&e8fLx-(oZ+%vSFqij3t(#cKw$^K7QVDk?{83HaN@T;?#Z2M%& zY>tJTl>=wW^Anc=@uGnkiS>6?phzh=X#`MT?(@+=Fet-_CA3(0u_(U7r{?MYT>LS0w1k-UD&X9e)vX(cXkWK;`PD@BKNvEZ(B(A{BfSJo1sI4CE0}$qynGW zd*hSb081=T^9}2c0g*KhB6FEeS6UZH!1;GN=y)6F-dXl>qh6{;gyh3grHZEg@<`tV zkCMLeJzVcL%aEjobB>sl9JTvJZUYmBFbsGcezG1xS_NhKTCcOuG73N zz1EmZ#p5EalIl+WSJ$H+W{I}jOs-@NiES6_AXwXszYeKK2d;wuA$(?%6WKji*N!xo&l19ZG51A7IklY3LQY@ZMOFlKWI-sK4=78Z3q~ z%o#iV#Nz5>T4Q9B$op}B{R}0U_D*LU9a;LrFX%jGD{8F6%r92}sD6cR|BkURhs?m_ z@)3`ha@~Z9PmO2TQO{UX8$HMNKf=wM6Ihyun|i7GP%y*0_v53I2=$mLMRBwEFnX~D zBB2JjwT6!YS#l0-r|7*&+i=mSC%mHVpfea`NU|jJ0#!m!=X~I&bNDffkBP{KDab$! z5%t6)DJu2DX0)ulHp|bm-^LS@(EU@>Q4zvnF2uFe0_vixpT>KBO0F@JjW81?*j2OC zH#D-|Ctbo6ozT7eCG08^NM=pj-R2mpVDp#OPy%UG_XVW{-E?i~9&D8(Mb_Vk)z*9V zX=VJT7In2YbsN*>$}`h6i(jAuT+G}2eYcvW0*<8Lup58;IyZe}LM&ZDw7%r3*Ds;I znw2IZXa_K;?e}}Q>SllYo%fqMr1xsu3Wv-Ll2a^~f7ze5EwjhNilzmLQ^&mEMy7aY z+m_>!>_XTJbGm|fCjcQqU*-JpAJ>rV6cx!MlGv9?r7sXQpZ7!T)&d%=HoLrS#33xK zlpq*2z(C6*$E?emS5?kQKy8r)cr2*JLTgkY&M&NJ&(2~(dxGI)V3)j9U6@O zbUJ3<{%_=~jL-ejF^D9}#Q~!=WRydIP{5L9aZaHmTZ`>HjJo;^#! z$f6}$PWpIQ9!Lb%7aivO)8e;ebo&QENkq*B+{~|)N1gX){+=5CJ9*ouVZDB|7NW1; z*P9XAk|qmX8#q?Bt`2}^ihTxbO-3uBe>-(watIHH&AYX+-8BhQS;M`&;Oo*i=ev>- zX-)$T>+)EFi}r%`B#X$MDh-tXFm7e`?$z=VRifW*otbsfyU&Tfz zl2zH3raL*iHUxfrd38ZLVv>}F$OyBd!401Ux|d(o_C|G>;D!mvkXjw$nMeGYS37U( z7TH0w+K&9f^%O+rbVb4M72e~7E75ydK)N##&FeyJUvll@d6g|QfAX0zuF4fvHvyLY z^qXEj{<(k8&A6%CO;Rwc+=E^u$zp_L_VyE52`Wa&Ea!{ky0ZA9I z@f9UX(-qom)z8G$7(kX{wX-+3m4b?jazTpJwv#XWSNtC`lvyu?AWxe^X%*PI6r$l2 z!A$Td54!V=n=&Qtq_OjgP5Qj|b1;R#-|`zfa8bgWDBQ99fxo_vpo zzFTB`n%A0tNrBS%51rrfNXZ*`FpuwRNT0ngEqfMSDi#)HqgXbP*hW?@i5B=%wl1C9feD(_^eTdh==0@aX7{ zpHCY=6Q*&KbUuC1TWKczUQ?tuMKWDu@v8kp?Y)BJXV~V1RI4v>5>3jx|SOkgcGT$-;qv zJsyMgSwkYN30-f{Y$%`|L8Jz{l|yVf6HrCL!6yd+fb&(0aGiCA*2K>m8FXmYmo7c9 zrIvWX7ehKSEwK_TI^FHl&jiWd)`RxoPn?{iTunc~s2iv$Y#8Vmz|0$dvdq{wiq+U4BhsWd|-!10hb>)BupWu_qMz0LZ`gY4LH$l+O3@_ z#c{!7VN%0Ehb{9(FUNpeeb_eSkf zfZP!=fpuJ^aEmI+L@JZ&=T8X2dZNC>}vWq`Nm34=QaHW|bI{v_<(n7gE zwy3J=OF1+9xe3lKj?(IC<=)lRs@3iOLbb+SOUz+8kt*>0=#G+@x8yyZ{jj~6DVJ(YGy zTR^zu*$o%K<ZOt3U zE#>x@a0YO0$i72K@DuSyV>y)iu@+RRnr62|Cw4=K>j33s^~*)N)N{*I-lO#*A;x2z z$i(9^9WeITJ#6`xjW-`QkbSzXzZ=t%cueQ0S+QT;iGRM*NJuxBJ+O!xQs|d&11x>V z_hTV~+}|e(sGxc@xGgbK=K70UYJi9Mp^46YGTR5m>WwD)T#2kp7zHi!!>#r%YiAs0 zV&WmDa#|*y#Xs58UPmVMb2k;^n5@q(1dlXbDPw^(BL;hmKFhtD|re)bj{2+EZ;WcpcXd7*`)>0D(?m&% zhzUeBH)vSjQP?oR)-%MoFgSdM9)d3%VHjos5-q=#!^Yg>1-~f{Av6 zb>`p3Gwzv%MHNIq3dHqUpj0%h#^O**r|4->nj20%PC~G?1PK+j#`l4&492iJDhbHh zVrZSZ6L;P60|9@se?@H`T;LKD>Gg{bTD=j>S)$6R1o*b4X-*Aa3U}*=6$AT63ysKD zscc;s3ZvzHgGToxiBrUi2*Q|-EmLrMvP;Mdo{5WE(Ty5yq%5qTbyJz|)rYy|q<1*x zezlQYn((PQdxGA=>H({0awx4M_*~l7?AhgL(X`zw3wHf0Kgu=b@00ijWlmT2{Vw!j z`5M-rol|K>2(DHw5kZSDJkOcuQtj!3$JE4^gR7T61%KApsmYIs=_xDd8&>mJs1$Dn zh;wDQvqMRlp=Kf7xzn^*f zv>;ZLnC&(k1XKuKESmNGCT-{}-3T^$MbnR6br5f|BG9QrXZ+Wm1|Vtl;8)a>@J>8UV30-YSmov>}eO}3>m{D z^uk_}K?P%rSV_Gj7A8fIV%Z8#7RlPX;S0n_;I>_{(TR;;Ph^`+x)UQ?3pSVKVr$R^ z|DBd{Loy~6WrB}4&>eJR%k*_2OA6v)QUsHA$_r1E*z$Mf0MX;WnAE)T=&yspI&5$7 zNtwQC+@ZB%)zPcp&|t2qbM0X?i_n+y%HcHA_GbPLb5|3DLN#smviC&O+!&_h>!ILU zUdA)PRi1uog3R#2PLo! z{ZTTsx-54wmjSOFy)+LI9ghIDlw~47%Fov;7I}iMl(Xh8&VZ8MFCTLf5$wCVmCy; zR1O<$pjyB_fOMRbTz)WQCAvszmJnv;z(oQL1}UamJu>N1aK(q%Du{OX_&}Q1*IEeV zE360eelW>vUqD%@e^$8J&Dhr&d!Wc+8EVL`R&>Xli!jW}Zw}>(kTu7Iqn)-I2}dSp z-)W?fsDxd`?@$2ZF6PNR$1PnylMZ9KlThDsdD!1XrY@3g{}`BiF`WcqMp)pxStCb* z;>#CaQafE}KPO-mTx7jWqYJ^;?8YhGTLGF*A!f87)jnBWhU13`I5_I@_i8+s$S$hW zrN1l|2GGdMG&#g$u51bY)Yw?Cpp2KPwSC2vX%ThOTzM4)yv<* zgD9|2nvrJPn1IFHsOZ)uMMlH3oo!Mrklc!}jdhqBQ{Yv;>yVdKKE z_%-@9a<|Sgbrnn}k^(+{$gCChV|~lGbdiOcp1qq-(N@6}th*vh*toT0_xWKCn>B6x zhtC4;M!;AUqzKK`sME``8A?2yLEBSicMIYLQ>v>Q-~?`+P(g5O0a@z0?e1T(4y7xq!h73iOe z9IEE;NuT}POE!S^;kM{475Z+xKk@!6kzsj&=-6`x19Qs79W zI?aj%6Y#f3%zfYgiX-%TO|~7GUedN zmf1cJGbhuIdq82lPp|MG#9dCDaxfgCH9!v7f_6A3e5LwopPErEa8bal*3wn|RK4(E zs{kp|q05O|KRg(YI-t=z8m!$Z^bc+eu)@9g-r(^WPP~$MS5ao1Hb4qAtIme3Y8Iqx@BY&>+uXH*2|9u>CJLi?o6mo}6vv zJi5Q463&=9d}&q}j(a_mc`hECX1~IWiG#m4MMbzCB9rd8o>EV~S}r?SV8s_>Q_NT! zV)udrJ-;hABzDsEtw8pLQ0gC}GCtbD2#Fq9vXB&xD4wz|bX~84h5KH^{D=FY(#{tA^#6Z#^ zOkO@!TF8`L^2h!a6HTv#Awf6JlBbCf@)fz8&#dAii!0RvKsVtWPR2M( zOy>Pp>E<4UVEQn}3LG<|ovs$$$Xe@&4R6xr`q}ltZ&cyG8m+=14%q@0*y?muv1DWM zx&ct}xsf#Qc@6Wf7q^3VHDR`&$eu}Tj|;J%10&2E+%3ny_kfv9dz!S*T!!QHsWcWp zy;$gh?m`-c_(B@V{aMBI4)8HmdI!zNBMrMb!0X*j+osAeM1ovLjiV!LHDe9?4-$*k z?6!GXt)OApBCG@Cova?lEAPk#jfMAvsp$D@n;EqSgQzZq$I*5!AxnP1mfA>6X5rq*l^7;pnW?_)7`TIgmTe`Ryi@IOpQjeLqtLbP-@ zP2sAUnf|Zy`x{K=JjfIkW+GX7FaL9ub#vX(Q@cWYmO(ImNCZD&fto#tEF!R=YuO4S z(vW&MKANGb7byr`o%Z2h>J^8 z-X*urMBkx}_x@A;CgZKr^}UI~^xh?54tRI;-83K;3p~I}B)+kKxodJwy-YauU^;`i=pT1^mb!E8VQpZ+&>6)_u$WHf19#&UXqR;<@NUjpxl0T%n=wk^ zm0V4h66T&RA++$(MWnw%n=jwZG9|`dn%e?W7&iR-o61a1;6gRi@Rht1VYu_ljxf7A z%~j0&;E+i?Swp@UYg3N(0XZllhTF;qqyBQR3JVVrP!M=3nRi!%E`v?v5Po`p#fKSH z_S^Bp1=}u*9{kLcj*W`erBI!7>f_0Z%hvaL^PLhmuV(6wUEGv?Yq*;-_0mcbb z$achBaniS<1}B$p0-Uwdhs}hhskrMG-hVb`9eg=`BG4gEXSi27qxp)&o&=ZbTGN@HhQVKYjt%gux8jk?tC7v zvmD;=hgK-IQgn*_k43Iz?RsJF51aFaIqkQCBy^M)Hw`s|!JcRy$&7zeWS@)1YG3K3 z{sCAeL;vO@JpygfqhA84WSku;P6jj{?_ABmh$k=0P}nbVp^pN#)uE-VMcZ=LyJXM2wQ z#(|#9hPn=29bmEuRd_81QSK~G*Nx~krtEy434Zmqaxm`G4F1j>&RGBl@BQ|UT86zYHDHs-h^)8U!Bj0>3 zorkOXRX)*V)miw>;xNOwCSE$wPHo}JbTDVjuPppM{zqumaiyS8kh#pIqqBkPz3K%O zbS?aYUEP*&DoeORO;}8L7|?0p8m@2N)2D&E#urtQDJ|i~Rxs{A%rA`vSZz|WN3@MB z?=i9)s-qS0hGZf4_Gc3+31uNU}e(Ei0-7qSG3%;#y3~A_g*`ijrYlcXLa=ROaP8Z}= z8Ai!Nf{sjR;N3l0hQxZ!`hpJ#0szOm8Y^*);tr7S?z5nxz96z4|>^sovz85941{i0Z_^e)&NR{||3U(_I5q zYCJ0DEZfVj^PN> zz>UhXwXI9vL3p0!7B!g>P3u-WhcQPv`*Y2Sbb@#rZ&pGSC^!qjsv+v|BCIdSp7-r$ zzwUI%b-eG`j$+CZ-7<+i;(B8)+e3nA-9e|iXff-^hU4MsN2-v=fnE8BZ+8=|?Ku1q z&6!9b?Es3%hbJiu=czG&MbhAhOYNmmU}<|`hAPdc$Y6^tMHK1genDz`(4>ZyHaFVw zynC~pJ`gl^{7REwP`zVSkTC6Ok+Cb=u@X*9ZuiSVy26p! zcc!7*4tlJ!%&L-^gLd(s`1oOaO6qm24`AaiTd0>k4Hv93zF63Ng-cF^?7MS!+DTaV z3>E+7_X3qq)D({a25L3BaJ*0Y(&%+gZAhM~p^Oh**(RSbi3Nm4vq!m@AjE(fEY>{V zr{HKuKo`>hD(s!=i=?TReH9LKN({~L(V$Fo6m=y8Wv|mOWVkc{>X-sEM(HTxCmV%| zOUK1`F6@vsIL=0dByl>3**oGV*7zac=fKZ3?t6u#zx}qq#~}3;eKrswaIBb`oocLa zdJ$II{%?X&{oZ7Bk!Z~BL|v1qSrhe#Osu)h!&{BPVH^JP_t-Rpf;{&hXCA#tNKL6C z9dXIaVS^OyfsXA2(be$9{MWNxIzTC+rt(F<`%XMc6|f4UJ0xX#`X0qD?oAy0A!c~5 zd;DJS;SQTM`4c4=SPoH= zCeWAZ_fP77a{8P*AN^sPZcY(=r)3Pq*?uVkwA6iuYQlrh8)uc$8tS4SuI z-nPk;(Jid6a)e#wUbf$rORejs7&;P-IH5`ni?dy2CshDvY`p);q3xzrJsGFN>@DA7 zlI9+X1yxzG@nQVkiCLdEI03kAuB0|XT^gz~4ti`=PrHoX22ewny`AmpVxw~|61YB^ z9DYm^Wb^uH&`O$4>qdiv^32BVxzw{w9Hu9_y<7&v++rGkf|;N2!#d#)?@YJL(n1rc z@Ng>F$^Fj1+=BRB#*7C4{?A;teBp&ehVyq)@CKM3<#gd&7&d&Rx9qouoDc%4t7{sZfTe<|M|x`>iE*HIGR?lrVf^@hwwXXDwe$Kc_4uMcu`Huq{_a+j4mdw7 z7z-U?$WWv9wG;uE1c=BkG^KQNTlr#~Bm;$R(qURRB(BJooBiL389#+dqL!O&JtGag zr@PF9O8*VOut%br_Jp&>>hOo^`t!Z_@9nG1zu~?)y}51%v8exE8yQkaqES-q=^|C4 zKPVDEYDLBqj)V}1{?=q^30FUNJiwfYdzwI5wztBRDvfNJ{a-|VWmJ?~`?nw>96~~A zP&%Z$1sR5r5CLhBk{oL25&>aok?u|j>5y*eMpC*vrS#pS|HpT&v;20Lx$oKg%3mZ~ zIXRPw4Lr_mM|FNuZU>N|->kx0TmoKtt`j09N!HuXnvUlUOu!yb}01 zT<*nI_A7F->QdT^(+@4|xxcklrnYEe<1GXfB6!x!UjMC3TWH^sr(ll^yB-1LwOeL2 z=#F)b(l+A6G9>&z@6p`B*sj`(Dw(1VZwR=s$kGxTp<&WyMi4162-MS1lD~R!AAi$z zH40N%ODAbU;gGNuuk%Smp|_oRtlp_4S_e&U-D+w$en^2a_4vf}GzoKR)`_NdD~&ZG zOF!g&qQkdhJ|F+2J1@lan#lHiv zc#fZ5IE-YtFlaN7{(QO585nA8-u^f+zJ<>#%y>7hIYKKbauKd0yjs~9P|u^Kaq#2x z`TSR11vhONh7ks2Ab=qqQ@dN;_{)!@aFLu*gg`RzP<_fmww8E zC04v*&k7M9VU9XD(^H+AiVCHMao!3;XtY;bQFjou;pTp>5SHAOjdQ0)sL-~r=wgL)$Q_ z^0X#~i%`UVHx`4%RlJVVh86z0WfSB7+#4(``pb;@;8-~b((BQrEDis5x&d0vw)3=UoJ}8F zjrCy4RjnKpH^dsRERnE7LjNRjs*>prK3$)D51umw$9^AvC8Zq@ymblnxtKSnsejh^ z5koEPEjNV=JXF!%IN03obte_J1Q+*=Z|7w`*RB+N11&M{K_;Q)5pt?geTOUORjBa{ zdz0~zFc=|f>{L7d{{C=FPqZ<#);=n2Lx<+?fOmcbsVBLMVoMUpT8z!|e#^cd|2sXpKs5fM5zBEee_xP6KJ~+- zquR91M2JMl97%2_bTHn|hI1p9N5NI;T2pX7;EEM!63p`yZi>!tn$-s`Jf2%XmUwl| z$O&v;@Yi$yJznCMUifUN?YGtGJn9u!6JS~5kU{BzxpmY3A96v#c^7ZUKTggWjh(B1 zf|5lI0pkju8J6MQS)ljj#Y3p#xg=tA+^zLZ9wdNT(WYNZX%ucNMf=+kn0*Jso>^K? zn@X9jjs)2@lG`r8;bkM__th2@Y`%(uZ5H9UN)6^oBRazhB1*uZt?dRdXmq&vy=J=G zsAKh}P%~et(Dk$-YSSDEEiuhQgoIW-_Up`Y3S!0<6gC%@7c?4j(N2ehTYrra(bW4p z{)>AZtfJM#@9^3Wf2O@5Wl<9~V*D=H4>>;Se*D97!g{rWdKcM%w{syS4*0h|Y7#%9 zb_~k0+}x~zVm}&#(^57OZN#K&bZ^8Xdi@@V*TNLOp3hk6@Su)pJ%UY)mTAiPz$a47 zHZ(k?&*xA-^l`B81o`lPk-|;&upN=SvA5|o05RIXZrP6gMPO)9A0UWXW~J zGVHx6+p}rvmH+());A}8DLQ!{B>ntkeoKA$uX}1^TGX|NI;r5%)+>7UlKKNN* zBtz3b#_%&MIoDH+^-3$38(NFAj4p9Cy(crm0gx6ic#rzLTf~&XJ1@e^D!CFeGNLRW zXB#%%P$S~br6v()Wda8L;YXcEP71kzto(E~w<)+$;aal+y*tV0oT`Dir1oB{$Ea#> z#)Z#4|9#V}Z)^OHC<_l2?J4;bndNogccS(YqTYe!qxZ{@PFFM@rfIcm&oU)hGq&VAxW>cK{I z7gsP%pej3xIxNLEFpgpSF2Z3&vx3YZqp)wBJ`d&1TeEtwAM z{K=`=PvoPAoU$0h98d47;H_uUG>Mnl@EEUo^6`=c&PO;ZeC2S}TNdlPn5ndAPc|mh zTV&|NeGn#wH$0Kj&`sr0$s+Q6(g*<;$@M`pZ?ru^@@Q}K2tne)r(&Z@w%!Q%sD8pl{=QxJP*-80mg zbv9BprSt)#^3i0~;s^ZK_6VUR3gZ%E7^iNM?ET1Bim9cs!W64Bm2S(BnlVVOIT173(~E?$DO*vJ zE3A~^n7VnOf>N)lB$NXajWRCAL=JA7gNWIms6c;OxIg)Yz)qUdKP%Lz>gO(#M4Pxy z$ZoSP@!41ASbZCds6Hwy+#dvJaQ@ThCK=0&#+b!bl3jB~5S#C^&RF<1-ip!55DAU6 zn$C~w7*ikoEL(ZN%S>O&-N`<8luFg1FeO0Q6aHG$siLd1(r^H{7|u-%gWplLi!-GQ zSK=M}-ND2d$&@Gc`#CWqVQ0a9h~@nX1!k1Iu+aNx2bYNL@Ov{yy45(BVQ&xvCxnq@ z)E-FdI0K5Eg`1@cYUYB+cF3mO3dL<%&l)5IVK-Zsq%X6ZK?W(z@k5k!-}1Q{6V01X zSQD`tJ1+28a7P$YLVf;%KAU~oQuPLj&VNcocXezsLg~ufFr_~tUuTQ=STvoESr8i z#;u@Pwhs@|jS1wBpTVkxd_HS`SL8|4N1Z9t#2#n52EhWUdk{jx&Wdkw z*RWaMh5$t|KR<`oJ8WQmfxy`+SOSlWpCp#N_-_30QBTTU`5Qax&qfjCdPx*h45KRH zm8DW9y;vb(Jj97@|6w(%fsOKZ*&Lt>THw{M;QBRiwG_Z zlLlMYu5@Uc-j{-q(S0(Y7;iXPJ!K$SshE)eN6;FpnuN%YiYMucJ#%q7`zRD4HVRtT?rfSmnvCNgsa8$K) zP!wBUdvqER4_DwV<%`x_v;GO*$p}0mp*b`BfT~Bs{x{RpW{_SrE%Xo&zW+3MH)#3v9!IS1oc8cSWw}gh^$_e39Tff0Q%_iM! z^4S*|#!C75+9^E=RvR|p2?2YraY#3Tk6=Bm@o&{G(@nbYcSJvm+b4W zCy%M|4R>br8V8dl_$bPuZ%U63{2k! zR@)WfrpZ9yu0i8S{wd6)N|!f7smJmc=YE~T2%2&8woOLLh`LkvG{ZvjV?y#e#GJX4 zJ%m@~^%#~_>r2{}Zh|p&W5)BAEl0{^!Z!HmpDz;fP>~L85yU**t|;{GrMc2QCR=6b zWM`WVHR=rN>Sk8NzW0g1y9ze7`6R1~;lBTkj_%x#`+nT#1#?d~RkT_rH*;>H+N^q{ z(ZujRhjbYbICV!n6uuMGE;IS7N()a;MxNI-g@+j!q0!L#<1Hx_C64D^Bz|E$tV=?B zw)AWgt)1^oLRmOyn8}u$KSFRB;T-<-6Nq~J57(DNIFNLjX8xIZuey)cO&-%?OFOkn zMgmrZY}#Oq-NU^I4GEPlJSfgk$(q@nVf+{Sc8sE36lsd;zgSdKs=er*EBp$e{$j;t z?>A{FK5q}&7Y)2EZX#D~D0sZ$aD4@-O#YI*|BW%NA#;0BO}bmrngEDefv%t@#)T3? zc?$kX&VMlG1S$b=W&4V!UW<1hYf_7LKOCO(8Z46(hU9&a(Cd>!tHc&zoV7>XsdKSp z8YDrT*>R(RuSUvL_cxU|O&RxOmT)A_2TK1d@M;|)m5OE#!)pslH0fuv`v6O-*iZHi z_T;}K3CH56D0-2&22q5!Eq5PO7K)H#OXCQ(B^xeJ`nC)|%B=C9qT_RcUuSwX!I$Uk zYK7*PQTXeE6ndyaDDAAkC^6h?#vXU0?Q(sFz_R3S*}51zMB?)yZCfWU#4Gc@upu3&mfQpCHP6_~v-{#!2oJw#aPLBn)|E5J>b z3dYLKZ#21v|HWQ$(&8!jqZ230$`mQkq_2g;Dpz_4KFw*4U9Y~yk%`3A*YM4L<|-W< zBe4X9Un1C(s`P>0PR)Q>q9j6AiEc@xhR1z0@oO-AeDRS@<%hs7ESm!34aeXw=C}n7 zdzG}59raTuGljpb?^JH7oVHehj4r~E_7vSnvTccD!Rbj50pgr^NoO=|05Mx@XQPglz^jr{e?A!$v+q zGF2R55~#D|R0FiDDDGEMUBeM;ic>K@siir7i!{Ly#@c53Ow1YNa%9$_k1eT|5xa4y zccesdK<`YNa1<@_Mu0JKF^c?kLf40>(F}grOe8Mq6_Th8Uy{~xp0UWQ#veA4b@s^L zbhHu79!x0s#ByYqNX`HVRuD zr>o02b}E?WT#MdYGCTq2QD4nW^CJJX$GC;x{dPY?!)LyLPRCAY4W<~z!}ZZ;wXIij zR!snBNfQK+BM33R#R|=c``Ls>O)Du?5}{!tg<$7#UX`GxIfMKDa7?dsNT@5s7N45? z&2jPv|LzO!#;Oblvdl0EVpElgE*KKpqQe?UvOb6VD5d0bh3cZVI=%czi9!bUWMk6G z_4im4F&i%{dSy{hrAP3~DeF;I5fm7;p~_O~VRjoKzA{Jd#I)E2bC7iQB*_orrsmo$ zP`*xun>&{Z-T&9M-Dx$|MBwO@_ftIE-+r0Vw)T+tNeAq^Fxc!S-tCj4vkscG5NF_E zOw_#SNq$MATQ|Z#QIIk=+G;4k3BAdLGHXyd5unTykD%d17QQV;FO5%SYg~~l>Pkv4$49`CA5-)13i8xl8eE=lYtHc z8v)&GI`0*2b+)BpD@c)pSJ2c>$=4FGocQzMBw^f(?0bPzl^91<2)9h{e4l-eab5Bs zQOQ65)#^R{0M}n?U1vx$#^KhS9~dl;`sr(59q$|@CK1PpABOKTMx+m)H!s5*) z(xypFU;9YNwLQOTjQQJvKQK74j;6S|b=d8R_EX|LU4)}u0H%r(`+E+D(IM$6uA(rX zSXFT#Kc#c(yTV?*OrqDFftn~$(QnuYSdes{=w@3fG@!dE$4Y9a+4T^$Yy?eq<@%S7qO z)a8B8?Pxr;UD#EdJ@;xO;_j|fLn;P}hW>yqj($OKvlEwNC;Brmiq7{Qj6#bfD-qmq zAV3+A-k2mznS&cl8To%nnT+!HUVT5d*CYhw_Ue%gOVgbll1aMsYh`p@ESq}i6zR~s zJN!;c9z9{DI^9Op-HigVH|c)3mgG*1pw0bZr-xy7QJBa0Zz%TVTW_w2k#cwq=v8l} zl@}3ScKSi3fRR_TW)?)0ln=%bUIJq)@XVo|zVX)+dN9saC?W50ALL-zvTOp=+`unu zZw_BR*@g{|hH}n4!8(d8g;?E%@0B}@QYGYJrt1FHABBLP+JKJNY`6jJ{?;^S-cAxa zu807^z|2Qu1jALEOW!TkNAev2+P%tZl>%39@sy{%#LsvHi(TG$$tZ(sPrmgRhI@#h zG9_y=E|{kh9gJY`Y~elL=Q*;r^_5on7s?Ry>;*(YNWkCIE5E>BnT)Ryd^Q;}>vPtb z(&rTpdB$N?sXM4-iPXz2XY`q?nG*xwEa7uOWF?=&EdAvbIg&dfQX%R4C>=YC?9=QKUiRXFV29GlX0et zAGb6=XtV7(f9<7UcaGIhK=QUql3WW2x*+=|eoE4y5%R>%71s{daIyf_Fl1BRQ^j0+ z{5qEXU+zTF*3^>D$SFwxoTx}JPMPkmX&=~T5tSua{IEiEbc&vedJpbcsn{7FIhZPH z{F=VV^uo-PBr^GT6y92d)tyJoWw zy-=9`p0hp3MNXDk=SvRbF_C^;m}8tlQ%?ag3cpic79mx-9e#I^)a&>4j~`@Gf{hd} zo;O2IKdv0xhZhu%LWp$llAb5d37ptPr;TBzvDr_8~zL8AIg< zJEppWIeA>+ywYTInzz)`n{|<>8(l*5HjM$YfvGDqMKTbLiIiGMSfc*K<#vr2BF_#+ z>GxjHVIC`?ev{d^Gs-IO{R*g*tTLl&Q`YG^gKZI+YOAeA5-C(mn`GFH53E{gw%4{Sczuk`!L>$@bF+3om6YPy8XGH%-ug7stde$lNy$ZVgZQ z-a1TS_w2gwmbMK-Yi(KKrtC%Xo>!3={wX)GH;EVRI@&$(RDh`w66S|lN_E12i@Do&h?SX1 zO7~lS%KzELd#@5FW|>A?)$&OwPO*_BSUVdZuKLKX>0Wzwx1pTVbr2%B&?@f*{tVc0 zK+@8K!b^a+K-7QcSV9{uw{5M}%zXdKUaF*7|6HB~yCtKm95IUvo4R7%*AYK3r5@=w ziMPsYDt!KCNS!okdHA2pXh1h$?o?4WGhlH&RBGtASPQ~T%rGv~*cc}qZOZLFf-C^h zl$rHfGF_UcmdiDL%dq?pG6oHk>A1@YpDpnv4lS>q_;~Hf5j~qQ9-yvqEk}&DWHg%0 z_{l8tiRK)twb1w)TR-W?(m(WFrvogE@bm|xXpEE zs8EM%SWtO%o2*dIcP97+rtjrqdj6VnYar1 zhtzkK?3&wO`E8D@~b)ABx8+4&qUX}M45Nl7E5G26`ZHAEv0Al zK$hgYwF*2_(JdSC7XpV9s6JWSjeRU0?h**NP*4fApW%&OGha4(M2{JKO3?-) zvzm_qc{WO&`!W(Y0d}Baqkb081R^w@>qdA?Djm6)!33pDIa*rAV~3Gs597MJzO<9-^G?NmCZvKRWUyM4(}+cingP+K9@B9 zkSJLdOmx@s2TM4&<5-IE#dymGL9y_lmtwfMp~#*`Ulhvo`DH0jx!AeON{MpKPeZBM z2J>x-biKZ6^l8^z|BfCSDTs9&<^Xhd zEL=}D2m=R22+UVvwJ{LX>Za+M*pfR=T>!mbY1iHUOR*~*L0`xx3>gi6JoxETkY zmTn(YV(0nMy7^9;0`#8>=_K9vO6@^=j|81oe-E1?lahd2OM7A{VF~(<;XNYXn0qG$ zfE;bzB7w<{7iAtpPLb5WvbS=sl)70wr9S@-8mn8QyGwC1dWE z1}4g7`tDmfFy717`;X^z6+=P@T!@IH6xeiQ$n_$_3+qqNe0K6*f8i$~@bxDZ&|ZbE zwleV1sJx9oj5TKHLT{ApMI_`KAoz`-O2j4c+UK_75YOrf>dNQq!V-s$Cq# zw?IoUnDpLCN@pzRbd0|zshN~^6){?u$iIdEu8Irhh4Y$}CR1oc*NqEZXw|Bu4h(VJ zlYrF2#kw5;E~J7@gM8x*bgL&%I?R{Dz+6-d3-fwcUvFXA(| z>+%W%q#sCPCvKpgiS#e+5A!5hrAq~90(w}XCp+FFEr!(8Jfghft7L-S;l(G0WVyy8 zWyQubd@1K;wKZ%_g{0CHx#8VzR9BAa?sZmD>=#;!8451{%Rl%CESfBayh~{|xSXav zQ($npcgf@i{`=!J{#W)6m^p=Slit=G*5i#Gieri( zZQA^RZNMz47e&eTy!SnwOQ zj4hZmz=vU+&kpf`6n$muKK^b)eMG>2<{SM{4>tPFM$Df_dmOhaPSpbpVF~_1%m%|c z3{v&oAp*ORczeeDhh12wqi)(w!{0S0?N5Lgw4+ko_$;&a2rGV-xLMI)P6D;X7-;lh za|wJYuNtFz(8zA}t?=l1T2-%L)N%4-d=zr}AmuvqqxWDXocLmLoN38Q%O7v#_?r=? zdl;Jy29MsiIYq38?+n8C=(0+s=?ZzK`5bgJAJRO^d<0;4;cSssl8Zkf8m#En){eLV zsWSEt!`Y_v_iM@CAmA6(VVTCBkL#MH--(tzac9GTI8Y1?yW;4+m{O~rcPrC8c4T^1 z`WMdgl2B&C);@#J%oVK(Q0J=+mZPk_3j;8f%=sL4fg-+QvPI0|Izcucjr*j4rhCM~ zQ%3FnPMY>rsM77%g|m{$L`evFjl#$C6^b3B&Hr4IILAL3O18roa&KpU6Pji6SC!cV zzCq-{RlXeIkHue>zw-b4%4PYZrHt?W$3^v(ypWl?(}mWVJt7 z(GjyC{oB}-MHW6k6*GDE{@&y;qtF*pjkA=YnvCeI5>kf$Jp%?LlcJI&u%CnY7)UBx zUCsuhkGpPCrwmWH?Ba`ZL3Y1wJ7i!w;^u`Okz~Hr<8@S<(8J+avb1dZGCVxmin;C? zT+~y4PD_ck7wTNnH?RQ>zGD}HY2mBj>HpKoyYX$%1s|;bb3CGSV2OWC={kT#^a#gj zl1r(gD${_L$!tGWv)<7nq!584l6P zQt?;oU|18s>{ zMY`+yLFU@Q?SmUP%<~K>TTg2}a{Cly-L9BT^wQ|jSOfp9AwOD4E;jxLq^e?27g^fA z7;fVf>!e^c4WW7pQy)yl++MJ2EZm7XeP_!jPk=~(hI(1*e|Xfc%>O3D0p)s|A3(pz zXu=Rlka0Bu4(gX$gDVlwnyTbBe^DCOcJdODEeJ$1QyrE?conhzhw+kKWJ*7~U5GZZ z!+?PlT9F$$+eGC;3|967UJT})ZnsdGYLv2#GRB-SztoJx_s4W2E?1y?8w9?JH*b^OX|!hd-*Vc!9jCLh;HRj5?Go1UeGk}evF zR|1MjxneBtdTDtCBShpK2}*Apo6(Zi?;W8;Vi*mtKWFE#*EkCP0L~O$z$QJb-re8q z0Z?fceN`zn%c#V9J}d@udRXmBx$@KF;m28nq(p&bcgkuV((n_*E%L1luuv~@T|*ct z0cW*{@g9+gF-)^q(VvLsmY=*^osHu2XQAB(Q$S3V-=#Nq7H=#5_=M#znmyS3x!+ey z|H?2;|1fh@Vl5LNjChku7xi*=Ju;br71*U3c@M(5v@Rav7$i}*>5wH1YQ?YWGn^j}ya^s%?nN`~lbg{JC@*enH;1?KFeLJp!AlVgo%A8Se# z5hf8)1$5czTDkUq`~ZFSbpNJTIV7vc;p;o0Eh6FlGAi;8DD?CX75>Fx29wArG88E~P@P@p3~rInoW4{&$LO|P z9eyIIiD$ixN>xfo6(R>2BKBH>T5&DSg-8hk^f2lK#vxh5tE835+#F-rj2Mfup6^)I znjP8TD<|8rhspkRR{NfAqpfwsbsx{1!bQtS%AagLNMG8Yb=?%TYRVt9pURor;M!-~ zD0XkJNcGz`aT}T`gornljEls2*6zc#Ho9WUAEqd212Y>2A6| zEWVU1arrc|aC^g!G8h(BOho$STZrc4G5Ta^b{0qGnhoqz^iI{$3p1X`-Y_CA&RsuQ zGT}^jy;sFly87Wvfn!h=a%xQ8aF|}81?HebT9vJuXSXhU&PGVP*@Nb9*8lexzrGn70R6YG_|d@bkHur)a_l$Hb3Fa z{Wlyak=FQ9KjCw?Njtj-<52e*;}O%N9JlsH6MO!hs)#?jL;RLEnUg6m(0cNF-&~p6 z32rFCa=ZD(S`I}Lf8>c#7@^LB=$6l+#c1d*`{wMI%ljQ0j=^Yj3 zVb_5=2UhIWh`)l5VZp(4c*4ogQFp+?Z`T<}N;3Si+|~=)q(&u+*_*?=cdARRCuHEJ zsq~a_L?}9l{!||*3kys|llQ-8Wpq!Z(T1c49}jt&V>>|Wtzl%^S(&*Yhf?H)z2okOR1W0$SFZ3q>E!#u zbY^?zk^0J&=8a_@oc3`E>4z-J3!y&&gl2{UoC7*EV5_n_R-V9TS?8VsCWRfdKzU$Z z7p7(ST*k(+3@Z4VKAUCKP*CxmdqylSc{@T(ioY@muZqvk^phlCRNEfWpk#zphoM?A|VRj>)tH;D}X(zQWCc~!fuH0 z^JKmlHwF~mh#@ftgBYus()DFl5RY*4*XxnG)cJIHg)XjA_`~$sh1(@_vNoAA$3zbR z{KQ&E7H@>;k$?I=5EOJe!7Wd%wD1 zJb60!M4ub9Qw%~5M}aeTW|E6d%U2?)XP1qtUQ7EhqlL`(sk{$QjXf}J;s zZH)vh-}H=laH}r6NnI@y0av51?;x0ld1~UC2roRH#YtXwX5I? z{m!spBKiR6Ei?3BQu+p~?l|$UhMK|HX~PjrdxTUIAr*pYG}y}Sqfv?Ed&$6{sEV&> z;GvY3VUl2w;D%q7bQz+MNSktF*{5qCFK4rom-l%{Q0V!MyY*6n{|w&(-WtYNH{gtc+#P zf2!T2H)q({)UXB4WVw|+7(t0zRubOIW}xAtXI-b-l!LFWK?^mbexJ+!$b|4$YYSU5 zeExtr<-G}MQtzbDC0BefXU6AGVOxgM4n+tKGO4^+R32MnHJdz|`bc$wdXeyjF<}0w z)Xr@(ad$`K6g5nx>)V8<;aJMO)*=|I(`|~CGOhJ+RXl3zfk*4}suF1$^1t{Rw}%-t z80F=VALXWf+BZH=))U>M+1(`$&$<<+T5uz#JH^Q=(<8 zMxrYkCtmCDWxRmE_k_BuB(`k1lWjlgH6LYjq~h4wr$8tbZlYRaD(Dvk0s9DTwz5R> zM^Kg4$a2u#Ur0r7%BM%V-9nCKEh#R#`=7$nnla<5Pc`$CxF0Wz z`}}73iMgAIn$QFNQ+r5LtsK5c8D9Q0{n8aUvN!@QU?8PLt*c6-)is^vx;)gpmW@f* z7WRVay1zB{>skvw?$|zMYL%{A74JBc)qa+1C|n-$xt>rCZ;LZw$c>H@(-14VDL(aS z;?teo6;^Xr{o1cI1lrG5!(f_(k0ZO!uEvP0=~H*&gPgSt2-)XF_Q|n|g-fV!hr%bG z58S@xjL?h}w+O*E_(2%O#d66YbpO`6@?u>nMi&uv?d{(M<$2OJ7Qe4tz?=G zmzUkaW~bIWdq44A<+Nfj+3L(yJVNTl$FJy#kFB*;bu_pFwObTkd{Gy0;CqFzwVR{N z+JD}iu&sts#pgUk%z#^QNk$0|O6MWMaXv)mD&$OoTOH;Q_>y1(;+A-mJWdXZId z5Na4Q=8D?l6pOQdb1e*{G-2>xdNseGRTeV$8Ul<7f7|OW)8;vv1SWkrL5hM^(4`B;8skffZ23wG-nU< zed)>${-!_N$tJ@7m)?P;{gF6p5k*MkIt@uz+XL96CAB{BYl_Bcqvxrv-=ho3N(z7S z$Le|^qoe;9M2hP2_Z4_}r8ABS+HXb85C*#xD@}R-fo(l+)Q@<)%er&Y`dT*0AJ=!` zwwTdBej(-12-Z@xdHF;g-L#p~ln5a9QTIz0y{o$;2g`$-iemh<_ z2}^oa2*NXem9_=b9>%%Md{xBb`B$G)^Py2``A7$rOrmDM?{hQtkw<2B#|>^_C~-nH zPnK4Nc^!jxp^91_lbL}OpxOMN)_u`y$kbt&mc!2%qVP1U<2PaZ>*9T!vlu;I zRKoS-6jpv3))LXz;y~X*$Fm(>`nlMI(_gtr46BDDovfY4mL_#1-;k2<4l~^paD@=P z{F3V}V8ife*{x@Dzpyqc;q_P^>d;&HyIPga`8|Z{a$VwoxMLWGFDG3m%h&j>=DWmI zpCUypCSwg9Yf848T&aZJhKEV?riQ%FD|9&cFQ&WX_A7ou`RrDk{$~N*>(W{{%oHO=i5K=L*woxBG4rYfBul=4lg zb^f2#&zHf@3W{>s4-4C5vyDInq=q?2U61h-7er!eRWgmX=?EZkO8;1bq@5x~t1|0L zav!Xd{m)}S_^8NBs%RO+BiI0W;f@0K9MH*3!g#GGV6yULHPx$O-)zE#ICJ==N(4iG8S`5Ii=hjBegJcF-yL=?MLjFY}X^T%Kyls z29%M&O6H|bpo8!J+&*By;OF{U&ulqEd>sjZDK^??vvqq>15%?CQhqVXHP&>U1?)09 z&f6dVI$YOB>LkKW7LkhINZo(fHceUT$>To*CI2s*A0?|JhidI5?UA^W(@^Y(Y zgz&MK6S7!;i&kD}d1f&@0M>}9NNcuPJ5B0f;G#VLg>c#j_q3s=D-y^| ze=#jzYPL$QkKlRo)S6?b{Y%D4UklKh5_`cbrmlRTf2N7nt9 zfgxVCr%Dgx8=uuAFF2C66(B|Pd+b$dSX9J$eI)WG<+7D}_jU1wZ!I1UD(@Zg&DB;} zAt`8D1@|Hl?VGX&a+;>o`xni>Z*u~KiZ^EtMJ?7^`9<@7T_VMev^>}TI1B&)aIEQ9 zRk9KGWbTNZue0AGF^4c)v@Q>Uymv0hGVNuae*>w=D zi&Zg|Aja|Dx1CvVY?EA?PEt%g#<*7X4%{_PfXPt)H1f(Jg{nej&3+W=eXVvoY`sqm z&8)x)r^ic2`7QxXoh=VQYYi38Ll?wKHYqoN8jaOlBE1xtfAsh=N!8n!L<`dnVGbdM z#^f=SNtA;iZD!lyU)LU-U<_aSe!N->rD7B{TNPR()1r7ArO3~0DAX6#yv|q397SaS zL~G)ve&-4_7PtYk0F85L5ftve2(xGOkY@m~Y^p<{{6ymJm-nIKHKsUQypht1?DdYgl)3$)<(n!&G}P)JPMI_{WZrfnHst2nXzdz^hiTj zW#)Fv_|I`fMDta`c1BCs&Kj=|n%`Ait|ti`xD9zEBBjVpTcfFqcj{p~GeLd@k8Lz4 z`w_5Ss?q=0X%|k&3~jH)^7Jo(kr8v&5bzZJtyia5CBF^+%1*bx<>MP4n zhoU7-A_g?C1|vBhlEwf_)88lD|D}{rfH6-^P7m_#OC?Ce+a-)_6bZ)v>L*RO?Kcxw z-S&F7;o_a=-?eYPTYD$vFgZP8WJaN>&)D<4B8@F-e`b)pz)R`JhMPit-}xF=8{ke& zi2|oSQ~z6lac8d@0@kbVrf+~tjtb@#%&oWfYX8Q=ChndgLH*b#4%(fq2PySOq01t< z$RAiNRWLqs+P^Op{Woy<(qNuP>Q^QXdF{go?gJ;$SB1lqXb&)l_LyMu0;m~$CTg>9O%aR-cexL30jahI*hgjT+E;DfgSZ!hslNu_A9V6WKpi-zAJu{mKX3|0sooi;7Fmq^);6l zclhn!hlDqqZtbuNI_wnJ#Bv9Ziw!*$m1(<*QWn>8=QGQ81*8*Z1ASNsp8?iR2-HP+D8i;VNV?;ep(pS=ij6rd zCo}LhtyjRtiK)|r77((lHbqvuVCIt!h#&XR_H8+`(KxYOj+E1A)TM5 z4Ff6VT_Ra`KXFHeif@Fp4IfAQ?~RM+b(jM9I@`QFw?o=Ky;iK~8gn=Y^4C

)6Zu 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 + + + + 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/main.dart b/GPOS 700/lib/main.dart index 3a04ee7..9a406c8 100644 --- a/GPOS 700/lib/main.dart +++ b/GPOS 700/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter_gertec/pages/imprimir.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'pages/lerCartaoGEDI.dart'; import 'pages/lerCartaoID.dart'; +import 'pages/menus/sat.dart'; import 'pages/menus/tefs.dart'; void main() => runApp(MyApp()); @@ -50,6 +51,7 @@ class _MyHomePageState extends State { {"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) { @@ -87,6 +89,12 @@ class _MyHomePageState extends State { MaterialPageRoute(builder: (context) => PageTef()), ); break; + case 6: + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PageSat()), + ); + break; } } @@ -110,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), ), ], ), @@ -141,10 +146,7 @@ class _MyHomePageState extends State { title: Center( child: Text( listaNomeFuncoes[index]["name"], - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: ScreenUtil.instance.setSp(20.0), - color: Colors.black54), + 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 index fc5d36a..bf99a70 100644 --- a/GPOS 700/lib/pages/CodigoDeBarraV1.dart +++ b/GPOS 700/lib/pages/CodigoDeBarraV1.dart @@ -29,8 +29,7 @@ class _CodigoDeBarrav1 extends State { Future _leitorCodigoDeBarra(String tipoLeitura) async { try { - String teste = await platform.invokeMethod( - 'leitorCodigov1', {"tipoLeitura": tipoLeitura}); + String teste = await platform.invokeMethod('leitorCodigov1', {"tipoLeitura": tipoLeitura}); setState(() { resultadosBardCod.add(teste); }); @@ -57,10 +56,7 @@ class _CodigoDeBarrav1 extends State { children: [ Text( "Ler Código de Barras", - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 30), + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 30), ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -70,9 +66,7 @@ class _CodigoDeBarrav1 extends State { child: RaisedButton( child: Text( 'EAN 8', - style: TextStyle( - fontSize: ScreenUtil.instance.setSp(15), - color: Colors.red), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), ), onPressed: () { _leitorCodigoDeBarra("EAN_8"); @@ -84,9 +78,7 @@ class _CodigoDeBarrav1 extends State { child: RaisedButton( child: Text( 'EAN 13', - style: TextStyle( - fontSize: ScreenUtil.instance.setSp(15), - color: Colors.red), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), ), onPressed: () { _leitorCodigoDeBarra("EAN_13"); @@ -98,9 +90,7 @@ class _CodigoDeBarrav1 extends State { child: RaisedButton( child: Text( 'EAN 14', - style: TextStyle( - fontSize: ScreenUtil.instance.setSp(15), - color: Colors.red), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), ), onPressed: () { _leitorCodigoDeBarra("EAN_14"); @@ -112,9 +102,7 @@ class _CodigoDeBarrav1 extends State { child: RaisedButton( child: Text( 'QR CODE', - style: TextStyle( - fontSize: ScreenUtil.instance.setSp(15), - color: Colors.red), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(15), color: Colors.red), ), onPressed: () { _leitorCodigoDeBarra("QR_CODE"); @@ -135,10 +123,7 @@ class _CodigoDeBarrav1 extends State { dense: true, title: Text( resultadosBardCod[index], - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: ScreenUtil.instance.setSp(12.0), - color: Colors.black54), + 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 index a43379e..93bcabf 100644 --- a/GPOS 700/lib/pages/imprimir.dart +++ b/GPOS 700/lib/pages/imprimir.dart @@ -72,12 +72,7 @@ class _Imprimir extends State { await platform.invokeMethod('fimimpressao'); } - void impressaoDeTexto( - {String texto, - int fontSize, - String alinhar, - String fontFamily, - List selectedOptions}) async { + void impressaoDeTexto({String texto, int fontSize, String alinhar, String fontFamily, List selectedOptions}) async { texto = texto ?? ""; // Caso seja null if (texto.isEmpty) { erroImpresao(); @@ -102,9 +97,12 @@ class _Imprimir extends State { Future _impressaoTodasFuncoes() async { try { - await platform.invokeMethod('imprimir', { - "tipoImpressao": "TodasFuncoes", - }); + await platform.invokeMethod( + 'imprimir', + { + "tipoImpressao": "TodasFuncoes", + }, + ); } on PlatformException catch (e) { print(e.message); } @@ -120,8 +118,7 @@ class _Imprimir extends State { } } - Future _impressaoDeCodigoDeBarra( - {String texto, int height, int width, String barCode}) async { + Future _impressaoDeCodigoDeBarra({String texto, int height, int width, String barCode}) async { texto = texto ?? ""; // Caso seja null if (texto.isNotEmpty) { try { @@ -177,9 +174,7 @@ class _Imprimir extends State { fit: BoxFit.fitWidth, child: Text( "Funções Impressão G700/G800", - style: TextStyle( - fontSize: ScreenUtil.instance.setSp(25), - fontWeight: FontWeight.bold), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(25), fontWeight: FontWeight.bold), ), ), ), @@ -216,35 +211,24 @@ class _Imprimir extends State { fit: BoxFit.fitWidth, child: Text( "Configuração de Impressão", - style: TextStyle( - fontSize: ScreenUtil.instance.setSp(25), - fontWeight: FontWeight.bold), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(25), fontWeight: FontWeight.bold), ), ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Radio( - value: 'LEFT', - groupValue: valorSelecionado, - onChanged: radioButtonChanges), + Radio(value: 'LEFT', groupValue: valorSelecionado, onChanged: radioButtonChanges), AutoSizeText( 'Esquerda', style: TextStyle(fontSize: 15), ), - Radio( - value: 'CENTER', - groupValue: valorSelecionado, - onChanged: radioButtonChanges), + Radio(value: 'CENTER', groupValue: valorSelecionado, onChanged: radioButtonChanges), AutoSizeText( 'Centralizado', style: TextStyle(fontSize: 15), ), - Radio( - value: 'RIGHT', - groupValue: valorSelecionado, - onChanged: radioButtonChanges), + Radio(value: 'RIGHT', groupValue: valorSelecionado, onChanged: radioButtonChanges), AutoSizeText( 'Direita', style: TextStyle(fontSize: 15), @@ -265,8 +249,7 @@ class _Imprimir extends State { }, child: Text( "NEGRITO", - style: - TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), ), ), ), @@ -282,8 +265,7 @@ class _Imprimir extends State { disabledTextColor: Colors.black87, child: Text( "ITÁLICO", - style: - TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), ), ), ), @@ -299,8 +281,7 @@ class _Imprimir extends State { disabledTextColor: Colors.black87, child: Text( "SUBLINHADO", - style: - TextStyle(fontSize: ScreenUtil.instance.setSp(12)), + style: TextStyle(fontSize: ScreenUtil.instance.setSp(12)), ), ), ) @@ -318,10 +299,7 @@ class _Imprimir extends State { icon: Icon(Icons.arrow_downward), iconSize: 24, elevation: 16, - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 20), + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), onChanged: (String newValue) { setState(() { dropdownFont = newValue; @@ -349,17 +327,13 @@ class _Imprimir extends State { icon: Icon(Icons.arrow_downward), iconSize: 24, elevation: 16, - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 20), + 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) { + items: [20, 30, 40, 50, 70, 80, 90, 100].map>((int value) { return DropdownMenuItem( value: value, child: Text(value.toString()), @@ -417,17 +391,13 @@ class _Imprimir extends State { icon: Icon(Icons.arrow_downward), iconSize: 24, elevation: 16, - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 20), + 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) { + items: [10, 40, 80, 120, 160, 200, 280, 320].map>((int value) { return DropdownMenuItem( value: value, child: Text(value.toString()), @@ -444,17 +414,13 @@ class _Imprimir extends State { icon: Icon(Icons.arrow_downward), iconSize: 24, elevation: 16, - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 20), + 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) { + items: [10, 40, 80, 120, 160, 200, 280, 320].map>((int value) { return DropdownMenuItem( value: value, child: Text(value.toString()), @@ -471,10 +437,7 @@ class _Imprimir extends State { icon: Icon(Icons.arrow_downward), iconSize: 24, elevation: 16, - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 20), + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), onChanged: (String newValue) { setState(() { dropdownBarType = newValue; diff --git a/GPOS 700/lib/pages/lerCartaoGEDI.dart b/GPOS 700/lib/pages/lerCartaoGEDI.dart index d901935..ae862a1 100644 --- a/GPOS 700/lib/pages/lerCartaoGEDI.dart +++ b/GPOS 700/lib/pages/lerCartaoGEDI.dart @@ -52,8 +52,7 @@ class _LeituraCartaoGEDI extends State { _lerCartaoGEDI(); }, )), - Container( - padding: EdgeInsets.only(top: 20), child: Text("ID Cartões")), + Container(padding: EdgeInsets.only(top: 20), child: Text("ID Cartões")), Expanded( child: new ListView.builder( shrinkWrap: true, @@ -66,10 +65,7 @@ class _LeituraCartaoGEDI extends State { dense: true, title: Text( resultadosNFCGEDI[index], - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 12.0, - color: Colors.black54), + 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 index 4722aa0..4ab94b3 100644 --- a/GPOS 700/lib/pages/lerCartaoID.dart +++ b/GPOS 700/lib/pages/lerCartaoID.dart @@ -52,8 +52,7 @@ class _LeituraCartaoID extends State { _lerCartaoID(); }, )), - Container( - padding: EdgeInsets.only(top: 20), child: Text("ID Cartões")), + Container(padding: EdgeInsets.only(top: 20), child: Text("ID Cartões")), Expanded( child: new ListView.builder( shrinkWrap: true, @@ -66,10 +65,7 @@ class _LeituraCartaoID extends State { dense: true, title: Text( resultadosNFCID[index], - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 12.0, - color: Colors.black54), + 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 index 67487ee..3c6a0d4 100644 --- a/GPOS 700/lib/pages/menus/tefs.dart +++ b/GPOS 700/lib/pages/menus/tefs.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -131,18 +129,15 @@ class _PageTefState extends State { } } // Mascara que pegar o valor do input e transforma em um tipo Money - final precoVenda = MoneyMaskedTextController( - decimalSeparator: ',', thousandSeparator: '.', initialValue: 10); + 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 + 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 tipoPagamentoSelecionado = "Crédito"; //armazena o tipo de pagamento escolhido String tefSelecionado = "msitef"; //armazena a Tef escolhida String tipoParcelamento = "Adm"; //armazena a Tef escolhida @@ -201,14 +196,15 @@ class _PageTefState extends State { 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 Msitef - tefService.setHabilitarImpressao = habilitarImpressao; + 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"); + 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 { @@ -219,8 +215,7 @@ class _PageTefState extends State { 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) { + if (retornoGer7.getErrmsg.isEmpty && retornoGer7.getPrint.isNotEmpty) { dialogoImpressao(retornoGer7.getPrint, 17); } if (acao == "funcoes" && retornoGer7.getErrmsg.isNotEmpty) { @@ -253,8 +248,7 @@ class _PageTefState extends State { } // Verifica se ocorreu um erro durante venda ou cancelamento if (acao == "venda" || acao == "cancelamento") { - if (retornoMsiTef.getCodTrans.toString() == "" || - retornoMsiTef.getCodTrans == null) { + if (retornoMsiTef.getCodTrans.toString() == "" || retornoMsiTef.getCodTrans == null) { //Caso ocorra um erro durante as ações, um dialogo de erro é chamado dialogoErroMsitef(retornoMsiTef); } else { @@ -447,10 +441,7 @@ class _PageTefState extends State { child: Center( child: Text( "Exemplo TEF API - Flutter", - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: Colors.grey[600]), + style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold, color: Colors.grey[600]), ), ), ), @@ -464,8 +455,7 @@ class _PageTefState extends State { padding: const EdgeInsets.only(left: 15), child: Text( "Valor em R\$", - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.bold), + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), Padding( @@ -489,20 +479,14 @@ class _PageTefState extends State { 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)), + 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), + child: SizedBox(height: 30, width: 160, child: textFormFieldIp), ), ], ) @@ -551,25 +535,12 @@ class _PageTefState extends State { ], ), ), - Row( - children: [ - Checkbox( - value: habilitarImpressao, - onChanged: alterarValorImpressao), - Text( - "Habilitar impressão", - style: TextStyle(fontSize: 15), - ) - ], - ), + 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)", + 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); @@ -626,8 +597,7 @@ class _PageTefState extends State { } Widget get textFormFieldNumParcelas { - if (tipoPagamentoSelecionado == "Debito" || - tipoPagamentoSelecionado == "Todos") { + if (tipoPagamentoSelecionado == "Debito" || tipoPagamentoSelecionado == "Todos") { this.numParcelas.text = "1"; return TextFormField( enabled: false, @@ -650,6 +620,40 @@ class _PageTefState extends State { } } + 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, @@ -668,8 +672,7 @@ class _PageTefState extends State { ), Row( children: [ - radioCheck("Crédito", tipoPagamentoSelecionado, - radioButtonChangePagamento), + radioCheck("Crédito", tipoPagamentoSelecionado, radioButtonChangePagamento), AutoSizeText( 'Crédito', style: TextStyle(fontSize: 15), @@ -678,8 +681,7 @@ class _PageTefState extends State { ), Row( children: [ - radioCheck("Debito", tipoPagamentoSelecionado, - radioButtonChangePagamento), + radioCheck("Debito", tipoPagamentoSelecionado, radioButtonChangePagamento), AutoSizeText( 'Débito', style: TextStyle(fontSize: 15), @@ -688,8 +690,7 @@ class _PageTefState extends State { ), Row( children: [ - radioCheck("Todos", tipoPagamentoSelecionado, - radioButtonChangePagamento), + radioCheck("Todos", tipoPagamentoSelecionado, radioButtonChangePagamento), AutoSizeText( 'Todos (Msitef)\nVoucher (Ger7)', style: TextStyle(fontSize: 15), @@ -712,8 +713,7 @@ class _PageTefState extends State { Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - radioCheck( - "Loja", tipoParcelamento, radioButtonChangeParcelamento), + radioCheck("Loja", tipoParcelamento, radioButtonChangeParcelamento), Text( "Parcelado Loja", style: TextStyle(fontSize: 15), @@ -723,8 +723,7 @@ class _PageTefState extends State { Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - radioCheck( - "Adm", tipoParcelamento, radioButtonChangeParcelamento), + radioCheck("Adm", tipoParcelamento, radioButtonChangeParcelamento), Text( "Parcelado Adm", style: TextStyle(fontSize: 15), @@ -740,11 +739,7 @@ class _PageTefState extends State { Widget radioCheck(String text, String controll, Function onChange) { return SizedBox( height: 30, - child: Radio( - value: text, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - groupValue: controll, - onChanged: onChange), + child: Radio(value: text, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, groupValue: controll, onChanged: onChange), ); } 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/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 index 9f98166..10a0371 100644 --- a/GPOS 700/lib/services/serviceTet.dart +++ b/GPOS 700/lib/services/serviceTet.dart @@ -20,12 +20,7 @@ Map _formatarInfoRecebida(myjson) { } class TefService { - TefService( - {String valor, - String tipoPagamento, - int quantParcelas, - bool habilitarImpressao, - String ip}) { + TefService({String valor, String tipoPagamento, int quantParcelas, bool habilitarImpressao, String ip}) { this._ipConfig = ip; this._valorVenda = valor; this._tipoPagamento = tipoPagamento; @@ -198,11 +193,13 @@ class TefService { } mapMsiTef["isDoubleValidation"] = "0"; mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; - if (this.getImpressaoHabilitada) { - mapMsiTef["comprovante"] = "1"; - } else { - mapMsiTef["comprovante"] = "0"; - } + // ** Removida esta opção v3.70 Sitef ** + + // if (this.getImpressaoHabilitada) { + // mapMsiTef["comprovante"] = "1"; + // } else { + // mapMsiTef["comprovante"] = "0"; + // } return mapMsiTef; } @@ -225,11 +222,13 @@ class TefService { mapMsiTef["restricoes"] = null; mapMsiTef["transacoesHabilitadas"] = null; mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; - if (this.getImpressaoHabilitada) { - mapMsiTef["comprovante"] = "1"; - } else { - mapMsiTef["comprovante"] = "0"; - } + // ** Removida esta opção v3.70 Sitef ** + + // if (this.getImpressaoHabilitada) { + // mapMsiTef["comprovante"] = "1"; + // } else { + // mapMsiTef["comprovante"] = "0"; + // } return mapMsiTef; } @@ -253,11 +252,13 @@ class TefService { mapMsiTef["transacoesHabilitadas"] = null; mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; mapMsiTef["restricoes"] = "transacoesHabilitadas=16;26;27"; - if (this.getImpressaoHabilitada) { - mapMsiTef["comprovante"] = "1"; - } else { - mapMsiTef["comprovante"] = "0"; - } + // ** Removida esta opção v3.70 Sitef ** + + // if (this.getImpressaoHabilitada) { + // mapMsiTef["comprovante"] = "1"; + // } else { + // mapMsiTef["comprovante"] = "0"; + // } return mapMsiTef; } @@ -278,19 +279,20 @@ class TefService { mapMsiTef["modalidade"] = "114"; mapMsiTef["isDoubleValidation"] = "0"; mapMsiTef["caminhoCertificadoCA"] = "ca_cert_perm"; - if (this.getImpressaoHabilitada) { - mapMsiTef["comprovante"] = "1"; - } else { - mapMsiTef["comprovante"] = "0"; - } + // ** 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 { + Future enviarParametrosTef({@required String tipoAcao, @required String tipoTef}) async { var retornoTef; var myjson; var parametroFormatado; 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 f19d580..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.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.4.2" auto_size_text: dependency: "direct main" description: @@ -36,34 +22,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" - charcode: + characters: dependency: transitive description: - name: charcode + name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - collection: + version: "1.0.0" + charcode: dependency: transitive description: - name: collection + name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" - 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.4" + version: "1.14.13" cupertino_icons: dependency: "direct main" description: @@ -71,6 +57,13 @@ 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 @@ -95,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.12" 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: @@ -122,21 +108,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" - 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.1.3" + version: "1.7.0" sky_engine: dependency: transitive description: flutter @@ -155,7 +127,7 @@ packages: 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.15" + 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.6.1" sdks: - dart: ">=2.6.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 f0bacb1..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: @@ -22,57 +12,16 @@ dependencies: 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/ + - assets/xmlSat/arq_cancelamento.xml + - assets/xmlSat/arq_venda_008_Simples_Nacional.xml - # 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 - - # 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/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 0000000000000000000000000000000000000000..75f1fbc22b3370b0a6d7378607ce7a25c5cb1820 GIT binary patch literal 96783 zcmY&f1B@szkX_rhZQHhO+qP|c_b>k1wr$(C?fZx1?viFaNs~$2r1M5W8W;o$00064 z002M`AOICV)tMOpz?ldT0Q8?liO$8trP_BhX^SK2_|qqpFCRaswT(xr{36YUG_^!Y z_qnbGZ3LPqxG2JaCAdK4W$o(|2^|Q|9lU?(CgYic$`cL%$Pb4dd`&Nm{kWL7m$K5! zp8~typ59)KpFLc)L906H*JAwfhL1zw0yyvE##74F|E%+|=OV0tn_K7vxn}#>Z##OD zz$<)Qb7~gtNc$~e^I!I^?fYBRYJ{_uD<`8Jav$vWa$pONgjuZeW@vz(Q?VGV@NY>~ zcuQv&_2=t#JfiglseAQ)ARpYpS4~xKJga{%3tTqST5SVSFYd4=ht9|z-ljjW$P8gk zshbCmo*aO>0|$PC8Nu#E6c9TPLO~19MfO|dWXoZKpQr=vo%$wEBp@I)P**&ypCIQ7 z#&geY&26W7j5WiJ^1Bf#86XfaU-YDI&%x%UYKpICxu8`z!dn5i>r7G-YQJl&!4w4{ z8F?Ul=?z(1t6apg=G$kF4;^&`XwT0q9tEx(9AhwE&WB*JIz+yVcO&X7L@>>( zICmEhPUk$5H{=VmT)}pp2!EITr1Iha-eJ1^HFu^E`p@6@{EqM&AKpko z3Hre$8iu~84RbB$_*7PInL(qYO6Y{7J%!z)U790=Ac^4CIvY?!UaxPMHPz+kBHO&7 z>k&;qu$T&^*-^YuP&1gjXb&p!O4Dtdw8oInxpZ$ zVH?H+Yfr?|QN`J^_(?a6$Oo$R)A&KltXz9|g>@LI zw7bbOjKA!_x4K7s<~EdOZ%P7-ox3BRsnSsA#Q~HAW#M#u@?rt zF9!r4dMx^rC4p%=HjGQR(b2d*ew}#}>ASUMgi;Xqr%s}xdA?^KFT2L70Ed)TK}5$k z5J$6)Z*waQmBEM>`zj^Z7wFDCKW_-=;BcIjC`0E&dt8LD2`5GrL}{Fk@)FNNT#6MGDuTEJTD39LI?Ckt_etTGo zDPtIXFY!U0TfknGKSNP`fnOJ(PIsoiYFWd9$ymDN$X~q~0n1qC@W&R7{%q-q&GN^+ z{`qj^3EhJXi7!ffU}+v7w7{i%gk>mvd68TxtlfZR_~XVRR8<1Yke95_h;6`HI-fB* zE}|XG$y|Lty5ri~wjfBQA+W0lI%wT)wYM(8fv*+%rZIEO<>2f1@z`rM^uWjId`cTT|sUody;AO73 zbJLyRTU3E*DSJKc*-pza_*hn>hK+5Es%?;pzR5lVgVJgpx7S{H9Tw~%d`!zQV&@Wl z=<#@6%m;M13*_B(0p(w+Cf4iX5!6Ksi2~=}g6eq{&)>od=yO@4-(i0ZK;yM3u*89A z=#^eAfKg7g?)R{i9{2Kx+AvQ5lN6=9mu#tSKD7h z)$ThSeO|uunu$`Sk{d`Y00~I$5TXI!dX5)N%;nO${Yy2-NoWys1aZ2jN({W6-uG5R z=&@aWfw2s+6&M2E!A#wKG8i1IYoc21$ zF<5QRX6fqP+57(6T-5;LMRggASiz9(&9e+F02CI~y($YqnEw8k(C(1nFi|7n-)2a4af5K)k(vrGQsouc zz{AG=c3gxIo&kL~x;Lu;TjO@gHP7rNxBU18!qw00FMeuXlNohZLc;{^;3bJx|+^A^6{^ z;cLvbS~~lLuu!8NZ2Wsg2=X7uOdWcXt(m|MxKqKjBvx}P8r&P=~&1z<%t`o60@QXb}6^Fg{;j zN-dsp&Yj=&>m-M8nz{wf0z)h8hUHbN%o6mni2BFMi-agk1atoAg*keZ5H$s=7L}JJ zAa)P8<4>E>&!k$s9L~*P_!|}p;b_^x+}L}0+tjvlk*p#r{bA4=D)8Ot^Z-1!>xQeV zb0o_6>qg&H^m9oew!CwBc>B7)BFCn&27n}!Iw;6Wh&3uI%BxoYZ*@_G2?Qw!ds+shwMT)3YFl~nTpmyz)?6)+Fy*jb z`J04lH@fD%&b`ip!<}siPQh7Nrf+OGO$IU8_gt)Z#c*P%$F3lFSW3^Vb7zZ3_4my{^Bh1yIPaO9#0PQsFWjLU5DcAj5%h3`2BFq=K^F3cCI)N~*2{ z%raPt#A$Syw!PLC262GRLDI{1FdRYZ2G#@hkHIv|24=*qH*1u$Kot_~lCxy^K-L@u zD|A1k5w3>2nZ}vxa!V} zRBsTtskaaXv-68o8~#U@%;MH`M-&(2g098YM8%bL8tw$so|uq^AR$KJ7=e#VOcE)S ziDJvyTFa(u>oST>-3;upYMnlTOab3v<}zZ76b_YST%^5vkO?80gZ!BM2AUGC?ctwt zbo$S0E7SUQE44|A}-{ditCPS+a_Qj57o2bnA%0f2SFsMlD2eMS(zYo5&DLK9`MO7PkfUSLm? zXithk9*G?H2G9DOh=vfWv(3wAlncPeX&59@DAho)w8VEpuacS~?He;gG6W;HvCCc^+|~CWa>00 z9bL=CYSnF9_7zF?PWJL!U?v%mYW12Q-7g0QXtBOLD^-y&c)!>5h2~J~4x73gHk z<@rL#`mR!bm8KdBI~pWQlV%!fX6wJ=)Oo4mYWMYR*^_l`9%xhqXc;;p>88ro>ke}G zG&E}2e}a7X3GgT7ZY>Rp!AE>C)Ba>y>KI~-jnGYVb)y^hoPQuocKV0@@Z(L40j`?p_!V(Kv%{zI898{x8Yn;Oq?v~ zfd~&EIsZ+Dc{9S$(2FBPuephlpR8{oFirVU6m?|ep`jlt0;wVsS0H8&3w#E~c$Gqn z**94Bz}c4Hh?^Yh=Wx=H;#*`Kkcv7!hMd45xyNmSj@Vdh#ts1&Hp7Q?Z7OS>%?5?( zEuAe0(7^#X$S4CE<)Sh4G^JLPrtsU38amV=;{1!qBE>W4(AdlSN3tg&lqq;%KdpZ` zVU?BTFI=?&w1Vr+uJI!z_PVu2OJhK$_a23 z9{@!)!ii41+0%hvf6rr+@sdE9_E&$Y8{{ur7J~GxCDSy?2_{oeB>f(t$Wo2UtxFps z93FF(I`rE_bSk@Ue_R$wd67SsI<)$=j1t0xgK}<3%jTF z_!y?R z+6!;ZYNXLh{eEesQEQ4?ylYeqZEAb__A%K}a&crutXv+u?JTnxaZ;vgOD~y58CLSx zki?ZHCn0xb+*rkwY`jGs48~@uH`VcSO2Z|R`-$jDRp3MW%H+SLp3bf+V#>s>S1{5% z6gwTRQZZ`kbTW-A4;u}tGiO#ue6D!$M`IG!Cgp@4+q(KPa^^Xh#EjCN@HX!lfwC!m z6E7>Yx=vMO4iXl9=LLBXLQrbww$N zDe$vA97V+VdG>@k^RpoQX{Es0M0z3_hv?DhNGETmhp2zyfTmU)CL$r9r$_74fr789 zwVPua`Ut!))o2N2tG(7mRjpVliHU|eU7mH}E=~F1rq9F+0I>G>(S#fy)}FzTlhzpI$Vy!o=n z6A=jp1u+?+maOSacYV<57on<}x*B6icRGq?C6->32YNCWFi0TpaA`%`ej!3D4DDUn`KhalKr^fyswr5Q+BVf*T}3OztumH*^vLuqDi5RBVCR zzM?2Oi_|9Ua8(Tmu6S#FsaAng>*!Tdg~T^b(jUo70SXa120$VbAhtNYtOZWJO^!W7B)uBER7>_$89N zO>2Fa|8{@pW;DaqK70nF2_&_ew?uXQm=Ax&9ao~v0Aa_ncB1B(Fu}b@$Q1p~2PMb` zF@*9VE>NQNTvaVnUE$%0mXpl4D8r&rT>uprbDF*8?6!W%roG@C8) z#f+$x{v=+DOcrOxje~78k+qaXk0|fX^CImH_z;_ zS9zzt!f$3GCuYz`!w*yRAo{5Kg6ApMr4Now4dI&M@&lwEV&m^~wCrsAV@4|*07w4Z zju|VMllq-O^VQBdFMh%TC=o|INQL)+z!BIZoRmKI_JOWfs0uX(OD zg=JB0OG|ejz0P#B+1K)~N?Z^_S8+=-z-!LOqk78^{wa2d zj7OuiL+vV zg-Tvh<;5d?rZ9Ws$Td&==GEye+x|O+5YYdDJmM%p0MDg+V=lfNYh!0B7D(I?s)J5{ zb$R#piR$h?&;vWG0PM}0(3Zmga%X2@s2|O=>>_a;Xef4O>oUgUIIGf#?%_zax>; zRMO|5Dn6s~rI}Xee8@29IyoShIB21g7Xksg-=8nDCdnLd`Av_}Fl8pp0^~sxC?OJm z+*iK&;qvDL->`H&#liZRJPIc+VrcOCIdp|yfh$hh#HdX#p}y|X1%idT^Q0`sx_y%` zH5p5s6bLY!4kyZ@ADx)fXT#2RVC@C+~xKU6|78es(v3S07~>KrS0aZyKh0`X_^p{)>) z@Z#mc#cNMj9P?qv(`4H)#}gqn8;4CZQQjVnht_2}~jc4AMKWca%5@sOOVL z&H;j?Ae{G%?0iHHL2M>51rlN!=HmFE1e~bJUqvb2xq>nR3vuED$hobakU~UOP>YY* zIB^iPgYskIQDP+MyCtUlBE;Bo1EcG~niJr9vOW#E6b_=qb)H058A!xj%=6n)UfPvY zvYw+1Scym}UtitY!-VUr9iC?u7nD-vR{tBX#{z=TyCWvrB`IrnX+5aZabvf2(+epa z_oT?K2Ar*_UVrcIpjv$r&@=7exo>jp{$!MVe$^0Z?-fu-hr8UWzW}`E2=+anhG-Yb zKuN$yP+w?+4Z`%p0KX|JELx#btM=Wpms0WPJ8NoyAE%VI27_u^(_zC7LB%^oW;6h~z$sWHBpRaR4@J zzW-89auqR0pQ$;{;q7aE3RV;5`${mx1C-9wPg$O z3@`GiYYP|SeT_c*EiHr29iD{HNcP-G9Z@Ex=fcTf5J|MTXG{5xa=wA~l|V1b$vU&V z=XfWiBuvk>J(y9l08y}GYtRGoYTNzo1%59IF7?F8{IE07>@E>MnN!nMbL_ap|n;aruo0cu@%#3ITTEfREn0r_mvbU_K5lsI}|h9Tw4iX6R}C()!h2@YAbGm{XB z#tpTo2sXW&Cn?2$z3{m_oJztNT?Ff3iIm%5^|D?Y0B@kgL%htoIPxNnYtbDBLKUij z$u~kVKTNh^Vk=ADpa;$QmyE)N?o6&D4`E zWEJ>PQ`2h~)_K-c6W~fmjAkLKDb+)o9uR-j4 z0Qt3uWYS3A?C_s$d-wK4aOqo4iPVL}TX_i|VHpSnZy@xCNjkufk_xzBO8`ur;$~8? z$&op~$?Ehf6Fu4^rMnoQ8X~JV8GbD8%j!%&;J5#>9Mc5r?Plhyr;6w-Qbh8bF^F{wu$25Pg@bU&)UXal_2&El!4zfpBnSGL;fJO`4DHEgog_>xi1&f6U} ztV*tl(u&7k;wf65HpPAh$UjV-NW4VjqW2t?=RC(X6^$&@mHW9l2Fl}5vxvt*ZzX+0 z#Z_imrnaS=ZV=O1wa6V7{#ebp39()u1c5buga4|ONfFkZ@h>f_>9sf_YA@{IUAjEA z1>kPqKDasdUt9~$ez-Zta-kivyE_)}LEUc`4Y^uUIGOj}4DWR<(ACIp{azhpv7~(S z(>swY>Gc7apsSx=alO&e&DrlAg%u7JbJ9v>6Aq$(20Euhq+F~jbB-Yxn7wo$H*&B* zZsT&en4EX&(2~DfubDnTmFO=p9hW&#Mo}7|4IeBy=OsFqqbt(L`A#z_wOnOWpq2I< zV}hoC&_xZGr{fS)Eg(%C#qYDQ-X^uxHk`COD?4PSlrA>>`=6pqT(_zTJdmnq0NoV* z0Ok0C^1Tvz%ANnM3)eF-TE6(#BppdoZD4?%i!$q_DD%gq7#G z@{W|&%c+hY&B@aHOjMI)HY0wvoUJc24o_9qI++{^lC~tR(oW;ns7IoS(xOSfU_)T^ zPu8Pm-^GDv*s2I*X_Z1QKEbVNMqD! z?}4F=T}Fw@8VEiAlu!quCX?td5gHT?8YkpH6^l$XP8hxt4Vnkk=)uTgB6cQxNgA~F zpbC6)M-H0eH^Y)~D^zl?%ce+o zB`$=GG>_6E^dU*|oqG!;VD%oK`^f})fye&7NOv2qspkv!`x!ZL2@(X3`xyoCwKm_D z+WZ5Iogr>HToeEE3@xH4C@lR3q9`Jb61j-{!V)PIQOqW=h_rz)Sr!pA9*=0Lh%k!z z+IkZ);YYz^Nv6^&2OiI)DM%YOBp%6=r58#Iq4AtK4ImUvo*m|UIDUHAXPGYK+2|r3 zp<)7j?2|6?Y^ ziJAY>wgIx!4Ao}zsK)NhQe`4##M7s(G9`mt+}EoL4WX>cW4pep>Tr3NK+PI2*uL81 z7_yf;F`;MP(|rQJfCFnJd-@OjvwUzUy@AT?J?a%U~S}V5$|&T+N@tR%n5x7)1N>?R4#R&;RNK`T{#H@9R|G z!?jjuA@hIaui5{ydhMZZ0eGV5wR$4c48j@tQ5a^J-ylw|E zWn#oMckYB?Nq!&4B>x5n?S{}Vx8L|vrt()^psd|)zw!Ger3z(Hs|%I7?4G*omYgdE^6(kVWrI@NJi>+)|Yg?6-eRkdVjRuI3wp3M%XXH zYQ_v{TI)K* z%KCR@wdsP=CnOUAcqD@Cjpejqcp{K=xzEc=VXFfM-90N!HWc?Chy|7I1_XcO(a*r z#bqTU-C^!~*(<%m@fnv!EHe+Q4cy8Z%su>0D80c2A*rEKu<)vFbsvHOC`cEOZ~&@DB&x$N_1=$q z{--wJeQm&-xGu4mFWkQ;khgO{|HUKSW6(3&!o3z{S!F^EWS0YfK;u(_<5+1b&AK*giFw z#W}$YZedDr`Xt}XIYAxnVdB3;=md4Z1sZ`Y&^@&LDQk{7P}gR#|6ZQ`sM)Y}1F#;u zusC0VuNwic8+|T)-nM%a@MW8{W7g0N+5zi;Q*d2}a9yi#OS5n(w%`*jz^0plPtpl~ zkPGyJxM>b7K;($|a#U~b3HG25)dIOHd%n~Pc~~i>|4zA}C)S)BtVI!6jZ2^pc7i?d zgRMXh&=K{2licX`JZ(_()J2&^A2qL$!A}oPD;Is!%=2pB4fQ&vx`aYH4p{eT2pV#? zKu)!YgA+~YIj>}W=P@tAj3P*rZvq(yW`TwpWTJ8{(n)T>COx=SoQ}7Vq$Qs*8a7(1 zTg%5j2Q=0;9ksi|{!G+P&O#_2qqJ*{8IHU#v92))5=l`E57dS+G@50(%5yFKgjHRA z9NR=iiVa_fD$x-_O@Dj(*y4H8euQglPwcJEdC&oZSzD*9=SI^OCMEo3bfHni(n+_> zc8Qv=w5&r~Hq2v_fbBWe5d!AAIgEi{QmSs;bE)<*gD+8>HnR2<%3~7`=qj*k5KAMp zM(kFCg2{3_QpT-}YmS@Xg!HU46g&HdjAM?%aY{3~xcqKYv_@oRS1+{}o8CY(r|8Tm z@gI-R&vNC?oqu7|4E_9MlM%xzY#Jz9(rEQ*R#1q~5{Sz6f9ZwnNWSiLEbti71$y9p zJs;W-o$I&$!P-bM#brj4V0nxfP-VD`r~xXCu^u9PmzbuSFZ{BOh{X!#3h%E8! zN0YTqDT!d=G?nj(VrwY$KNT;(C$otbE)c3_;!*3>(m`;IzGQ2}4)JA4st)1E`JELJidOBT)CI{7K>_jj=2#=w zhXZK7!emEyA~Yb@Y9a56RFR6TTpnac9P1q8Vb*=h4mqIcu@x?5yvA2_gRG0rkmrExp6!m- zKs=aCcSF6&4TY~){e|J8)V|$mf75KCd*T0F#JWS2Ec{qVy@BOV|0P|0RYR;S=z1yiK(q$rS)R_g zGLrrqQsNw4oouz?^5!)`ZA1`Z;uN(OO6GgsWHxngXK%lP_W=TEWfmPjvP5v_hmv~5 zE{;xn3e93B6K#M&ZmY&a@Le4%Afclpq?w>&No72;YAoqS%aO0CIS;Z$#|*;yzR-z! zmbwS2fbIa;n$KL>4^=jJx zqYOv9)bF>9brqk+fD(QqJr5t9^3Zx^#uquch!TNe&Vx5OXh6}XM`7xc3KlIYUcZ4* zH$yQK7B&`3eHB3YRo>NuJlKe!B*)%>C<^IhQJBAWs&wXHb9sx-sj!hCmcEKC`>~ui zuwJ+MBEJwD4N!N0qdf<>N5-+XMbj5{f`%a>iTwv{*s=geJn-yp4RfP0?`nH?$P8lv1tq?k6ef4YscxPjrjf$_ zRc~z1pOr6l@vHu3?1fY~bwAup&EH!%I3E)XHoQg5jiM^?oSFQiHu}n3@aU*+oZ^h<=hzU(g2(k6`W_yo=A;9kJ}od8*!0W7zS>7fc=XyFL|_jWf>lz`L(&Q~ z9Ri(=Du+njx+Yc4@^630HHQ*HFjSUeK#cNSTRw0BIN23D#S)_14a#zY z0!q-m4fbpk#D^1qG~N+~E7sker>nJ)B!umc`qy$~87t!EBHu#e;}mfQa%#L+9P|`3v)4@t9$|c(7E|v0v1PU;=%SF z-RhJg_kJ*hqv;_SA-U3(@DZI0V(xdaHTOG+TY%DI&|Z_yS84z+<)34&&j5tsK>vfbtO24=T~r#tQJ+SJHdp!e*ih9}@l=$-Yu>LVmPYPWTHQxsy6rK~Zm$?&x%Oza4uKK)|@| zQBtJ{L>2!qRz_i^Y%mQBXAjn|kq!vN5yGj0s`E^wknnI0_oas^R%thf^A}Jg4wtFD zNbbEXX9uD4-_>r3om>%sUeGt%oQu8!%0BN`(nT z8AI`QxFh{?k&uDIy-+C;Y8cVcK3aea5B5Shu<}{o!y4iU5p>E#KNF$~ZVw4~pg#j0 z9XYa)D zp%s}p97G1Xqf@Ek1*8%8zX9Z6J1)@Ol+QuXrJp~bU>hGC5t`EPv6=mSryZaU%IA}C zK*?zDbJOv2u{f1rdClOy!YxL-7~~)?t-+VIG_(8b`H7%80&fv<*xl+DX<%*vYT$L1 z(xugYKn|mU-i&aboH<8<3GptfjC~ya++Kcp^7dHw#yRD;|1gFbbgNqv-jqLwzd#EA zZz_k8QR1u}5CA|C1ONc}Kj(DpOq}d3O=J!2EX_=vUFbY)ZHiT7?Kc@@%|AxO1;wk`hH^2Z&Kx!rG*QdpRy2T&dv+wNNDAh3 zjE;M)zcWL8n+@O)jB`9AoI*)Dwtxh67MQ+O=dGjHe%?r;dK7hk9N$$iqR!h6>;EvD z4=mg$(C)ZeqNTr-Dt}!+H?{b*+v^@eSi`Xdf_@A6i4bTWj;Gp|!aPw3nBM6ls@$fg zrV=LxVi1!AJR0w{gO^gZkN4ARjudWSosqC%j1;Pyg}X+Bs1Yi*;Cj=OQV!Zz`U_=s zt=q_~0a{zevzGWg+J|kqP*UBF>A6`i+CzPWZ44)y|7;K-Mj(+#+U*}khuPt&%L`)z z{}jSj-Xt~;bAfI#CSGBl;x0;zS&dQ-$x0iqgt#I3AZ%UyJ3Iw9p7$Dm?)Lh?yk49= zXqf!9X3HHd-sID9PohuM&-D1>oBHIhRP*?rt+}kma`H|+&CDYmXi4s{B{&2Q{%J5o z4`;V2GZg-6_>KPmD-8*HYB&`P01%J@008~3(#AH1&d#RJbXJB=Rh^7uRXEeT)TLuKd)0bjftEmHYP{d#Cc;e zDrvzX13RB91 zik#9Fxd$O=OxH8%$s6$9T_$p!39X?P(@~cGqp_nq4a~h}^t`=0{CNk_xC_-1UDR>peK*?j4EYM>G_)gf77B?l*JR`ix}xBE!?_ky+1W^xtPOoxb|#OkVZNd-mj>vW$7=t|Ms}sDiw|K zlq*zzWU3%M6CJ9zKN=I+zKlmhV^2ss;M0>n147<-z%!@&)LK;_m}W@)RJhcyFsI+` zn;DU~;!QLpu>WQ}q=fjC@||-jjyFgg$S$0#Mvwev+khiPu5EsoOWZRWgEUfv%ZUq6 z2It81DNs(>Nr5)75RcxcLUMa+-e5gb#u=W_C1{}pE^8F3>cJM=Ml3Yfi|-cHRGwE& zgP*o&l{7}46SsT^k}_NoZW5nHUm7oxFB@ZYE6a7g2|cDkFyJG!Z>U)jq-N0cFsvgK z?y%%IuVkLezbDN?cO+s~RIIw*5w2biv=bu_mOm8&(>6y*w>^AAp6M zn>$~EpVi%OBUK%sj^a;-e66ttL^$?Lfx@!~2R3WjgK@&C^ajZ#`Ft9{H&k6g1us!a z{{7;-)UmC7!~wn3}mr1NMRdjs6OV5Lk&{#GP6q|yEW>kOcoWxBwT%`fND z+1Jgs45}7zm~pf-dY>rc-6Q*Iq0#6V#H4QaQf_lHu%XV#oV0iT`>Is5KppR{dQijL zf}DSfxf)7-y=3M%K3Mv}>no|WB?g1)IsEXv-cWbtLdkd^I#IDXC2qOz4jwZdH_rL# z07=>v!b}NHdXpg)2125f7J6=c>z>}PCbJn7%NJocUqr(7w)iy%DWUuGb_E8jrt^?2 zh6sNz7i@%djONBPAb;myY4nK^LvX8KArSV}TMPB#uOM1^5(=CKwzBG`%|6N&MFm&w zMM&&+UVD8T(ZD!)vu#LhdvVhN*3jNaq3*1{c!lE!+AlTHa|ALrXi-v+iRod(b&5ib z`Zy@{C*jAPa%ri@#s-7X6KFd6Ty{?Fa|wvPSJ&@*eFu?e-Kkx24(US(0Z~OnM>!J3 z0ScfqLma)}JcvQ7h#CO^`2-#O$^N3Zw9hx1NbnZ47l%~vHLzzW=QiG3>`4U=?eZQG zkzDtAmIH(Q_fi#?61SK}&_x3#4o_$%67Sv$6SEEgkp&3}aM8f8k)rg`VDoWbsMsq1pw z11C+Fyqxeh9cyAj-mVOSNWQRs$f~OMjT~qD`I2uM>T>JO1AacxRj!1JYM-z zLF9rvS!DCSIZ@j(ij+t}npMxGav&L6g@Ndb-P~=Fu0LoX^e@vKY{XtgGvz&e)-)3y zY}+92jMc*)dD;4d=5krnEr(Oe9YTLuQuxqtk$wWwec*8!)(w=@tBIEns3uLDZ_0;z zlERj#@|@Bu@x{UZ)Ttv{O-T1#g48xqBj3oxF;2=WBJ;DRtP45NExDbC{y+`qGv-G|(fHN?qKw8Ic2w&*{e#3!b*m z6dXy;UWCqHFPdsB8%sFIk{8oDiIb={^Z*JsryOJQGy0OKZkR9JLjVWy*nop|*2hc7 zHE9LJ1pq;3V_NDE%`S11aFW>EWZG(3X$WTYuxFoevngB2teZ65m`5y{SmdG9R2gr@ z06TAmh_Z=cmTU5uH?oX$|2k9;72x(XXP%3E@S{RfPn-=Z6vIy&TjtqtB@aYrxydAHqbvWi;m zST=KinH8weyTWM1|0a))wuBfH8!?soa zw}|O^Q5|-+Z8Z0)rYjI7TiE7U>9-JW%%4f(!1%-VRR04zK*YboO;$ZpjETPF_X|^z(yx9(Q1Omn9<`LFm?C`f zp7iyZ_~%LbRBzsLG{o7H^`;$6@3jZC*l2oQ2Ocs%dB;BS4|2XukB-gbAoW*)qzTSm};cHjeQISwG4Z0v<7!&E%ca`19aCK`Q zYNCenNNV#WR^tLoqqx0yQV{#$*g~HK;?d5|uF-jOqeOsQxx;9aHdn;GC4L4)Hl-_k z9DSfG=mfr|=?&>BsURF{J&e~)VVH2RT^e)aoiQQ`3C*X9DW;bZC#sSR*JB)$bl7wl zI0{&U{r75bos_H@{EIp6|0{`#{Et>!-pa)lWDj!whs8}(>PCQIL(5rym=z#>1y9G> zz#E>`RE8S)-e8zeKx08J^LW7c4kj!sFW%7PXzXGB13%mk;NSsf+Jdo!$q8q7vDOi0 z(74~r8EPHSKxIbg$JUvHT}tW7b9uZV->S;)5vECccRQ}7I7cb(?1yn8M)tlup$Bv? z{Gj&t^qCsuul#QEA(xHF!m*fKo0dKY4_;)}ihHp={{~tMU9#toBcw287qs8^QlVW$XcYk%=TyL`la} z6T!>HZy+Q|2U1oi&IKk~+WcMf3sQLQZ+A#B(%l4BFaIw4v7zY$tWv0r`Yr-cwW%)C zxmcglXQtsJY&QiK{Vv>9#KkF68qjCPIw<2@3t)!t)h!}&+4Jd;8hAPKtq&&cXdv=q zen)$m*!z?R1Ri9*qLZW!i6QvsM9Bge2ZU8_rKvUdRN%ej2M(BPMogKfM=+f|7ozgJ zZaLod23T@lOZ9}P*htc{e>(45;a1(*z^5F$y`AB7GHtpcQn+EkZwp+E*42?B~UV?pt^!wC}<@ zx0HH{c=MnUGOxXTVu1Jqp;;GMJ$nV+<(oIx3&?6OT@+b#Uw@A5m!}l~hFf4WI?@!r zXK-BFAediquA{pUG5g=UxrW-6I9xqA7tRz563H3XbXJe!9-P@uLklw*Sc0ZTQUcsLOiHG*;6zCTlyvKtRo3{&- zH<%yK7RbgI9G4TP*`H%3(oDqI;KXp{p@@EdDjCd;y|-VKTEJ}%9s;q zF*}pd(@}FLVLEGGfuN!pGBWXLAp8im!-bma`(0BwT4S^tH!w-Spw;4qW+lHZ=2Za8X%nuSaCtisCgpCly| z>J_9QQ|C|=zaLgCb6_f6qCyv9LP1`kVC>C&GpQ35jC^?f#M zHgoOarMnr(L)7s`y1TobQTuI~c-d;4sSC*&kT==EJQbfWA~a=+hB;dqz?hj?X=tSN zmuXXKD`+5D__i8~!^p;P+Vp+6ANDSE**wd^g zMzVg}jaQTC%xQgr;J87 zD4disXYu4dL&RsO$H_Z=1OIz9dQXWF;k&BntF-}c<9%!)hJ;$xJC>fZ{cX>L;8l%x zLWen0H5^ca(nvOjok3CFDt`D1Lp?UMLnZHkjSO7UV03M?`kv9crbL#sRv39s4}H0x zLj}25hk6p7deG5g51l%jlv$-o-8c@Auh>>g0tHj-Fxo3s6L-D%P1ZduE;-LLMc*V` zt_Zz1l$oKiJ4IIFuyP+OiN$gDtD&|az%DWsultlNjJ<>gBUX7;5iqAL8Y4=b^^<-b?FrVGJw2KLIV8eD$r3{k<0@*Rf>~vR zyb*{kH>|4B69>tRF$EMKwW8cimNm$L2iFzw(0y@xx_pyulQ8YZBd|76L+>v0k-;qS zxMFtJJ{z`ic~r2rp)oX^K=aZ95qkenACd;Z&*rZkDEVT_i{R_GN~XOxZmO49F8m-` zjDd}f!LZDHZ`{k24=lHxEH^P%;x*wu1+Ue5fyavHo@}$ErOckpY6b}?1DWe9l>5d`|h+&KWiAIz#hh zZkrmvQG*H#K|u^9VI~cU?;fhS$lk~-C`tIRxu3$_c7HVTK;<8XHqQ2lSnNGagj_9n z=Hn18-JM+Hyih-Cnfk1=yg=DTa7nhP^IZ84=)2!(d|VOBa5yEzKXNpr*@S#u#U6A5QRw zy*!4gKXi)?&rOEXL<^D8 ztQ?|k`6f{rlChHjJp}AHpjEUpV2d@OduairA{jZ28OwPIk1eYc@PGiPGRbnF7|ARfDA=Z=+reei#J!g@VXDUKU&skwxkya+j=TWz zF*^w^5H-40wJHjVPpivmGM5JWt9s>p_qL+@NKNcyWOl(XT9ea$WBgNTZB7mUQoM@8 zLPF8)YEMi$>YUZqVuc2Jlz0Z4j8G<<>oI|2fT|k}MyS(7AQC%5+kz0QkQJ5Mi8`TY z>|tUs_3ULZwXCipK9Yzht4Z&$fr=k=;%dWmMY4HIA`iP227x({_Mfd9d3Byf;6Wd? z7=hjFrl!BmissDEN04^`T2VWft#De*(JtULP+oF7)K$xYj3^IgJiC%aMJL4RmCQy6 zf%myafIUU(>FwCWH+=Z9y@3$^@Ajo*c)lb-$%J+UMJD#$Xw7i4!^pqkJ6Mgru(!oS;aH zO0cXQsVFYN{BHMvNE^T(qm4osV_mV`3sEt-R}amN8ha8PREl z2sRlBpcZY|6Fcn3+j; zMu?wpu^!{SqsZYtMpD9*1b7|B!@)#ju9FkGkRl?@y_=~?Cv z)8Q@u@xI!ybE4wta`{~*5Tct;&VZd-%|2>1*cBdYBptXc842&wa7rZqopBVCB~v=* zYS`kglXBSVAX0@b{PlrtpM|x-ZvPy(EyGf8WKJS0Yqy&0n!TZ;&twDtM=!+Y>Xo1r z%H`p9B25~YWZM_YGPYD%I9AG9+OyyD3GYr+oPe<^RVZX2mtVizRT4Y8>53qkrIAtJ ze*1IM2LdQBSRJ)Fm}{4#yU3A||7_SO`0<}iNJ51n!2l5qOpxfmF+K190n^J{nNTX( ziyONdtAb2HR_-9Pe}MY9_+PS+qDZ4Zm%2<>bp&ZWS3?Yl=8C0i$*~Zay_L$1bDL%v zn@#W50k2>}>P}_5qyT(rAq@YC9|_Bw0)dE^^r;8}P)FOmP^54XG%3(5+B}!mg8p0! zk{8=YXB5Ue-9Bt4KiGdBkE34Y6r-W|JE*e(wd(Jh?pX%LB7HF;xBy z&3kH$FW=gny1WvO_S*U&rJGHTLeHv zPa+NMPlu)nd+x=OZBDDjGAfZEPKBlx2@(amG8vukizSqH4H6Y8+cNwh59;aJGE@n1 zbZj&<@FNuws2$6~t1?w+!@z=9f3l)|U38T@CY&z;j!d(Ovh^0uo!>8lFF(KdPVzYX z?r+6VA%VM(_|{hwgQKD^-{ zl&SThx0ZOVp7JO{%rW(o`|#QTx|sTj{fj0~S)8535gyPTleVue&Q8*ZhuCW#;Oaq z2<@tBpDo!GNLThDWFw3%HEq5tl(wXbIDNmlS!4{7K5=&g#!;)AvToSucCoE7vKB9M zsr%tQ zk!iBCWYgt|d#Wl#nKb?3F*lPoZDNkS@P zLX;nV&r*Bdx=Zd_keOlkX;qiyf{{**uPieV6#N4uIA=3a8y(9ehSN%1krhDm|(^u0Cn~;axJle=K`Uo$^HjU&w8a za=Qvus6MhjOJj=^9X-Ntvw&;NTW* z4_c{1KDpzHv(p*+6D33%pKzgm__$lN#_g6dHtU@3EtkB6KfIc<+s~pSh$c#U6L_>9dJY?@mr}Y8PC%YootXIJ~6)pm!z4JMyLz?X& zg=EUKk)yP1nk6etYYaWH4Rc!%9_%&Wh*r^92%hvkuuo2gR-7I}#j+jKKTNwnz`6RZ z+JIt%^=MKYtXP8! zXX)&wEl@z{bYkFS2TZV1pp=2avi+VPjCczJo!uxgAkpN;)<*A%sSf?oM3{o<#8)<9 zB7zgLRwgp0DMWFV4x%rT#!4CA(qwSlIvwU-j-HYd&Qg4m;wk<6k;8aiYe}F#Ka8zV z<7Ow%~2=lf86j>>cYvC;=rwODl_oj#C<~Jd7lf8g*ZgQ5mUC zKKQ~AkqtL(xcQrc?(7n%zqy}hC>LN=rN7dmm-SHL2P+XqZa(#39zSt*y`y*zovt9v z2%2z;OA-yZAE)VUdBcM^7p($F--piwg>(J3Wrg%FPmx4+JaqCAQ=kQ&2~`p!^_8Ob6to5~yR zO^`t=df}|}{qhp{QD*GJH8oy$hXcO;8vzhnx@80jm2{gvlocnKG`2Ynk?isL&gc%- z1O^d?nNpt8)Zpi9dmR_oMK{oo$v;<+wsLG@tO zYr?q1{$GI44DANubgwXuQKW%N{A;qWC*B8W_CH4Y3Tg|^>+FtKgghXgd_LSLs1GsdmAp7Z=@#RWKl(um_AcKGLl5sA!kRD8I>gAr|h8` zvea!w`RWY^s(&4oDjkRYI!s%=9Skq&4+Fy#LlL!cqN~JIoZ9~j@yW(#Oh;xYGwxg$ zF$RND==%U?E@=)zGyX{)vW~AVS@mvD$sQpARQoe>a-!0x;C zTdZQ6@r2vL@f|t|Q_^vtLeJooh+xlrmwmwvy0R-=UH^ti?27AQD;OtuZo&v+nZSn zQT~KO-!W&UKdRYp)tlBVQ9O=oPWCfr^pgB%mfYdJB&ip45)WtmZppjK4b?fUO4P^W zTnNg!w^l_$*SysBsS%T-j)RM`58MfetS8w0lDsDj3ac^xFB}7L=yDKxPLA-XRMef* z^Z;hXfEvo^qF$rWXhj0sxoPbF6-l#7&yewom~Kkg^CaLEKowA8)UN##z!;<4`X%s{9?VB2R+h-Wbyqw3lmux^6ztceWTfhRB9wxa#ttTfvm-=kp#t zkjy8Z68Weas}!SToMldUwcbJZWNS+Iq)$2baQJ&+o@j-Iahs)NEAI&q>8`8NnClp| zI;3F*eZ_l_{|jiOFU(a__HL{%4a7xX(Hx8>Myw&sI3%LG=VGitQRldqco^drx5aT< z2hzGL;{TD1v#0xg(otu-eJa)W(#$1u*lm@n%r;K7Q1$X>+`$cAP$SsC_93@!bbJ9R zeLMV=jB$s^Ya33{5WNCLeAZD(m?NZ_9Y|K1dMU-R*mo`h!$A1r&Lxx_BjEpS55*kO z!iOj?9=~Tn}`g$xnjMzzNQSbedZAstuPir6q-D4Rx3QldB? zJ{fJD>y8vQbfv6K){MA}>0tJh!@kz7 z;kDhwm89RZ5feJugqNb_Ebm2qGp}%gUzHt)U;hU7zxaysGXKhfW{Lm*=0M8M4z3QS z4z|k1&MyBhO8UpLq%`#@`$Z8f!IV&5wlW3C)N~8lAZof{_yi3V?bJYe=n83#6-=Mh z4rhy^J194B(lB-Lkzmx_Vl?z`StGc$KQgO>a9c2s=XZh9=FsUhj;mxqJKIapsJ zwGtt9@C4M(_{+ZlVADN*-br0rG}C!!NgwEU+FTP63xy{S>h&#b41Gg1*|NMB~7u%d}T^H#vp$=2M^<>i)wn zjfD!4GzWgAGO+5Eu;l)hUyp~c;3G+HtrxB%Q7Fu#a*4Ve8We_I_gMi*^CyUdbX_--Y7R>o-v_sLcI)D-HnL2h3%&Q-GrEXp5H_#T)D zon?`bg8cuSI=6H_4?{wLfeAtVH|25v50v*$<#1Ydu2{?X{?u=5%~NP%Mj_}XKQK5+ zcd4O*(F&>2?PR}`!_P%(P&e~T^k2*8k zBm@Y4th@XzE*JLpR`jt|T0EJx7m^O@DDoR8lGR%Mo&olYL?c-K51YP%{TO-_ zarB`N6~;lxaY%wX}Jo9LXQr$PtHc4U_@8LoUhh#8%@TTtxGZ>O&6%2FgzIBQXe% zIGZ^3E|cSC;*vqsmu4}!SYimNIMDM3G&VE>fls;e6PC0uvLpS&M^Gx|GQHEyV+Jky{wA+sCRF$>Zw2mi<5rStF zRcSk_mYYUaY`dg7^d*&|IYw&ZtxDYS>ZpD`q=>?+51jK^)7MkY6$$OxVH&KoZi-Wz zKB{aLMNh5>jus?IF zWuhfuOYeL3VtJPK(ENdiuwiwqVO+GyGao(z%~o~gUF2DI=4#+J#-YSMx+}jgyW*>N&!g!)xluDs`kRS1JvzU`H)>b5EH}1C`?cfc6@F7z znc!6M#tKa?qS>S|Wgn8nf#uL1nOfR8Gt*bwvYwDmo5hJBq!bA0UFTL)48OD+yzs~f zKb~X1aTDdKI?Uwrh`s21 z$jW4UHsQKOB6vLPL(ITzyVxkWD$PHo-cxm;n4_x9lG{lpqy^q$kyE}`H>ctlDT`3~d*2dIy2phRW=x|$CQBU~6eM1JrX7;r zp3lXzn#@q2ruysDlX!@qyFheIJGR18Y%H6%e4mN&0h5*5j5yBaN8bTiA zRaU{hV?BGBgiRDdGC>DBjni?f0^pG+6{qg)lVxa3A6LPwZW4TIxr6$q*~CIgyw^A_mFF#jpTj zw`G|;Y5J_5XS( zPT7H7%3K<$3~{a_PT5#@SZoWu_|dG6GSZM;)Xuxbeej7)!x)#W!%PV|gKwYmVPbh# z7pY!j9#mLURq57YEte8X&wH|&3o@ixx~+xQ*JpG(9?Mf)_VFpB(ZWa$lhvAu3X;kAExE%5 z^6@GCo5;Zao#g7!E525DJY>5{+Zkk@ceF`LhNYNn=Kny;X<5=#)cfNJIM11;mV9(p zzv{FIvs{-iu~@fqX6O7&xeB1+G4CsX&>zgay~s*%JUr5o9RfX9CmfR}`_+v!alb6& ze#I{LNxmc8twvJU*&kP6L%+k~XlVS553Xv4Q-?N?QWpAN&Sw~? z`x^V##u{y})rv!kijQO~deav<#&><1)t7+DYoZ%%R~W6DKO`7EG@`Ig({K%_(d&x0 zQ3*dE_F3eXA$1!T$~-dW66DrYcwvbzDca)wQkpPCUP_6z(o(D>qtcbjs3_h=oIlD3<IL|c% zbcT`J)HGPbsz7DuGU$h8$Ygjbth(l)MZP|s1k$=<(bb`njB;UC>T6;X)n^^h5+uB| zQoIh&zK`(@SK4de(L^-%bO1a_7`h;TSRyaQ?RL$g>-~Zrsz|IEYvjW*DUy5zL_euY zS!Q)i((RiRYEz1%z+|RBVce1dCbdq{NK(Jg7FgpgdwK5372a06;xUw;=}2^9;_R@- ziaX7elufiHVH#|1KP&ok#x65RB~Wyc^*Fb1zPsO=p-fX?OdA6n`Jhq^am`ICvx7i0 zSd5sV&^)HQteU?XcvO41Px3}Or4>VK3>0A%i$vJ4rJU9c^gzme4{m>X(;vJNWgc0N z572A&r}+T`C~sJ2N*r$a#&&=yb^my5&rr7)z>VUV=T9&6fKj4?UrZ43?XoZZ0u#Y-nUT+KiG@eR(jx5y#qg>2;$v5*ZA z+Rw`ezmG{uUh__vz*G`$@bmJoB{ndxNvh`LhCp?N>;-q~r$Y&;0fN-$f6ij|1b*FQ z!h?ZXVg6sH!G9`)FV&E7z?8xIq<3F%Uj)Z&BeO+00H+b*C$#y-NNqg5MrpKSTB`3% za7nM^fq$34OVLQ-^qq*8oQ!i}nh5O+0{*UQ6Q6<#iMK_4S)=~~Zcd9@c zJsFCSoVd8xnbG<+3sd2HD;?y`1~wBjSXExj12jpdj$^awoY?G?D7Qmn`miCKcp$I! z9-dgf!Trz{-Vks?4Y|GZu$v3ra<7wY)qHNY*3nNC3NdJ5Qtb(vB$PaZdNZZ(@d;_j ztWWn~?*eHexC$X0naVI)u6DEtuI_$>Uj{~Y^5E$La68k-Bu`L)q^Kf`j&%+|g0`dS zLdwbhwsj#k1F5eLV&o4jW}vEpNJC^hXb!8}usOh~sKa|?1XE6&GoTH765A2@fRs%SgP?8hmu5HY$vDlQ zF$6tn-+Bl&uj;`tUr(FOB)GG{*`DHbE5Mx9AHYjnXuFpj;>E~{H0vZ=lC?}vSo)XiSK^4{u06n~O zg3a1&-jBn7)d<@0yy&hj4$e}+l3!05e4Z=MP|#6tH`tmpwFifJG>w}Yi*wNuw{NjW z?d#xBSO0rna-rr7irYbW*Mm(#-69M&u`&f=qMjz?k=Azl^M$?4GG4~72H~HoUZrLo zdAkA{5YM#|eYw`T@l2rr)!6y``y9p?qpo7 zpK3StBH_8_xf@k$SdMK;ea3ysOx9wz`0@Fp{? ztm3nQl)bQQuY&MF55I00mqG?zoC z-%aPs_LZCA=Z!8dxa)3muslAL9-rBfqbf>@b4GLl_@c3|fIrGSl1qtPUy%KXJDZqdY>!El-C_} zMt|FS4?8ArNKYo7fi85;14kE~^J!qVoKiZM+|@v0@mCvNxdaP2u^yq0IvlmdT>>Mg zC5U|JGkDiU;+^G{sq#q{bR4+KMWzx30@+z|Q-hA94U!(#b<}7!I(iGGngz z*!@;eZ)m07aWifbXcjup z%=@f5!c2KFUES>dkCEPhkTvd|md4kz4V;!1IVJ(QWoNr~1|$3A3?JG4_tRtL!0W_0 zN%*cyUf(srld>YTCLlRcWrP>fg)ub|Mb2S+Sd&$fYcyiNX)rU{jm1&VPnZ2Acdy$@g5BHJ|X z*l_UVcw+x-YZc~5M$E-3yz^j^3A{dzDLF{)NVwjx0OWA7m)O&hsd(ad#u~B;{~*1T zp~Uogi+_H+Hoi{1zdt0qlh00PzSy3%|D9T=YCv+o0kRCahoModI2(@_cPUDoHlX&p zieh6~y^1;;Fn!BtKSYw74gCSF5q2?bdeffy8r<$yn(P4L01gg4`ByNk#=|qep;Id1vUXtNDtK8u*A#P2# zS=a?-{Bx9#KD$lIV(Pf(JGa6OUv@#cXv5B<8BfzA^E`@}kcsPioVz*1RuG-vDcPbnoN=L_HSNMYN@~9(kM_+{4SW8ud%cLXZ z%PH#vHcLy%bft*U!=!xdsB)C~GTrdI-qXC$x#0mx%y@v|2%R=+NBp-O=rXzfEf&=M1Xo4K5*!PjOB(Yhh<3mslxFLr{4fT2E z3?=&OtT9KBwYc3Mx!?g7tT;7Z&{L*CE5L?>!V`YT1n7~oP6qYe{E=ww;gYJ=MrWLA z2#1JvnCg&EBlfQrejpcT%qAp@DZi4{6I^Z~FtXsnq!3qSb@IteT`p{uEjRBiuH~BOoaOEo*%SBXF64z> zitkOZoG+H;)}!m36z(9OcI;<{>z5?c3Cw#$k9f*)LaL;Sa7%r z?)w`+|~*uolvauaMpVI1ZK%@cP)y1J9YcLYFQemfq z*7JTEb#)V@cadXs$F!#pjEkiz#SfDB8pcG$-8etKpZ-+^`YX`I%6TGW^BRcrdfE)q zB+`=;b#U!*){qZ=>SDIBsfe$6AP)L|Ht_HR$2!9vWe-1>-g~fr8R=HU>YqC~_(#7P z?r41o|L6J&TbkSbzc`=+jkJ5xK3|`przrjPr$ruHKk%0%_qXmoJLqN*(QwF1BJFxRi^aBQ`p(0!Q zs`s0%-EgZk8s#)4v}&N**OXghy06@~^*y%RbV$4PJ!-e>^v~K#Y2So*dLPEoNIo?K zTy9=+-~3K;ZUCPrzVoF1ciYC~I{m0Nk3o`O{NY584h9JGEM|{4_pg>nAFvJRS>2|jenzn)c5{LV{J&v^Jh5`G93n-YAi$ay{fC)5p%9 zpJ@UIKC*wmj361;-5BHw4X;OK!f9~@N9>l$H z$D?KV^J#7#+?bdCK;*`JON`-Sp7&~+Rdapzu|jVNPpsruTJ-9gE#?1(HYmT&Hx(n5 zIojN-9uwlo_gk;!4*WfO)kejgDmtjg4Q-T*3F-!m>3%5HFHP+T2A^k~kxQbu8sHuzeoHuHe8< z9t7mXtGMJc3A&P;uDML`&@@25k!R8wR>y*(%P7*QX#FJrF5MU}lBw!^V z#PM6m9u4Ce4u6=v|^)E%rV_U{+StixN>U58ka zLGo4?MQpE=t9Vfvja`Z83E4oWvmdIhoZ0zA0tGE*_xV>utRAG#z>T3rJNRN7x#szD zSD09}BBUZl6L+fM`EmBfx}i(4SG&dgMb%gdYaGC~_JZ<3`tWlrWL_W1w^RqFKd*{OF=@{Jz~ zt|P1=@gPDQLWx9%f^k#Kfd>35B~Dl|GI(Ot61Nywge-2t&Dcq4Rvm4DL{=MYugp>6 zK-~(mEhI-ewdt)n!{2#{_-AKnjxmoBAYDDzIjH@uO=!gePryo8m^BOxpS7|LVyn4= zQSxcnS*+uC5n8gkC-Ls?gEGt56MhQwPz57{ttS2AN$mWbZtjf87&G2x9IwR)C>f+c z%MJD3#Z%N40&6@l*GX@r6kW3M4G4vyJCf75ikfOIm@zs4yNyFL%#&U1bAdjLlg}=F zw`@yNTy5M+ux2ZjJ?iNAq_{kIaXZrn=>@wM43*z60j{UxC|t1Ca>OA@+yBMcH+5;& zrOT#m+qP}nHY#nu>B>smwr$(CZJU+G>F#sg-`?lktRFDPcp_rP6EoIGytv%*Pi@un zJicpbtoywL;dNeEECf}-{jxw$io11JxRtX?q-9q_iy#(EQjLS9osHfmN!=#Uo2lfK zFB$}9Ps}rkiaHx{8qR773J5_Zv@{X?E4hnU!~UUygpZsStOyy_`F&}l^5O5;9HaU~ z6ATs-{$#swEDdV2DJ-rz;5AGpOt?vNLJybNSnqRUqA0}mZfz=EB+GB3hF>GTcn5W{ zqd?`?{AMk1`g7h?0mhy}ldwIR)QlkYk#xwZ(Q-LYxPuVY>AxhZ&EK1=jj4*h_B z#~#v=w=rxG!n~5s2ldJ(C7MEm6fLKn9{TN^6k-kgq7@4e+L8ZW)S|wn#_mHWbVyab zLehR@5s1K7E%@4=|CZ`AJT}x+Z7s>)-qmv{?#01D7^|sw`K)-YskKrWy6lfd2{Ot` z=vOo|!4M_BS` zpAF&e5a%EVdp;5mgm!Y!E40-h-#`N8>N7~KIgj*Tl$yS`CGFTzj}2%1+#xc zlA7>DQG9OIg39sB{NhtotRI6g%L`l@d{MZB%6821`1BhKR&Kz0At#ds6+Lz;%+ERl zlJsxQ6zkh)@m5`UtM&F4MQI4q4|p-PjO&e=X{|{$uNI2gi>z5e{d$qfID+Qo+W1N+ zFf&F;svy?Cv{W_|47?SgPdNHiByGG?qu2S*vOB=$xf86S$=_m3YU^m?m@GDE`-Nqs z*CF$v3)o8Ccjd4O#OukZD$R~8BoA}-MOm=}tuQtXfA*ihrw)BmfPflkroc#F?+(+uQ;Do<`+lt9kG~l z+}$Bry-@}9-DZE~(_58J33MN;KFf8`tzKxch`+K(hn+U{nTytlD>SvRCF7xy6zEN) zGT@Six<+4gFZ&fHtK9~D-L&pnDlK`3b~^}l!=8I>NXr>2H`SW>iH>|qOgT)X?MA)P zYwtQtr|pKkt+Jf7o}NrxgB(idT^DrTb>TLqj!83gStM)Xky*TDC5Rr;co2}a^6?!r zCZzCwOE2gJ9)TE70n@oH@B<8l2>3YTGiwU*tV4-w@<3QDDclyiUsdeui$BhQN!U^D zt0WK?M3tl^c7I1GcwrsFIA;}E9W9(8M}LbI3WE0;`Jm*oSRq8+2fHs4e1IhnMO1g< zS$GQLYdk$tnY1npThQ0J8NXBTN2sq|b)>p}%Elnpt$Qbp5R_!a`0Ntnc#E}l%N;(9 z_R6*64sjV+G|ThKdE$ps3HlEp$%B;}g;BuId%m5T@`wdD?6h|ceb=S_5EUj6cjQf| zpWze~ScnI&CgDqK=OYN}e=~&SV)lM%n?&?ue$1+N$#TFwBx=J_mWrns z=)W?##rif_IkTLacm(KH@5&~^>Vw}9XBZq)Gd|%JEj);<3THTFW}l~7u0V+=YQht;AFIL7d&XR?7KQ1Q&- z78wkiAfi)bYox#P_{V8jICamNv++(_#+m=3?-(;sOED;_YH*D!F{9TvBJ?(P&Q65v zbu^mqDohGp{VbgDDR!7!7;GvdZMUmO=YOnY{xPxPGaQkvaw;FbL!#$b*`LZjac)@T z7E?c1V(zpOc_^AxlTxyG_6wiVUmo_h{3Lp-V1vsF-iQYcYr>A<#CIS)+HwCB+i@o# zEQY<`62aM{Lqy`hzGKIqV+VCy2Fcri0O>#=Qnq)U7#h?LdD*(%LJLF`JpqWEN69pu7p2wNhIwdJotz0mgs z{!Ji33 zFNpA;*P{0z~3@a}H zQLrC}mSc=-dcCsvu?Km6%62xG36MNNlGg zSV#A4LvlE;8Wkt*)!8CgHLcZTtA&to<2W#Hze0GT{}V#7f{eJAaeP;d~Qcv6v|Yi zP?V-=bpMUzi~L9-e;VrZIt;mfh0EDjK{>joa^4u;DGPkPV~{9e*Cg1sZQHhO+rDkv zwr$(SZQHhO+ud`&iP_nG_nX}xRrM#UA~GxEDa1K>vU*)_jw7qUuY;m@JqFJAZ}Z#D zlkR8NX7JZc5{IamEgeot`l2E0Y!1;gTdEPb?JW0fn0h>?ErEcM+T7Rmza%w*l>EwW z5hs|4tg)sgoWJ%mm(h0)0S2hH_oChEzThhy_{+mW_9NYC6PB3ZUo1}n_Ag#_y5q{kwKC%mt6boMzDl@tu~jdNLMBti(79bx z59A9?BnXAG1;hq;2BfNSHT%yaYnHo6GkBzQweoUP2O`9C48<+-g+0ovq@(3BPCJ?* zusS&~G7BfBiMhlNy8X5_$I~#=44$BTWq2M)cS*#!Q$SQ-z6voER!oT3!m&QadXJ>q z)MI(4XfjM$<`3_#TWBfu*yxnzHY{C00cJ1=d;oED{K$^a-ZlP~{AVM5je1H~V!jUlTUIM@9Gys6WA^2TO@DJnzkW zN@X)!nQ^!nF(o#S0-sN<5|uYko}g@cQ9+E^C=>Ic+w4Tqd7wXk$9w>LNv3~{@-V&3 z?7h}bRE*Ok{HP9C)OVMG?S*Tz+_Om9mf^!8z9`;eb$cmrOC~M=#;@|0=c-toA#~F2 z?C|O7OFch$6pLQ2T{wW{KH?OWxx;(nvXzmCFOqKz>1v4Sd(IxmI`3rZImQV(g|qmK z4gKT;Ce>l@Cm-KHAn}*2dCtxwu4|cZWDwgIdW~!p(eatvHwU@C27HOyO$txw5u)n) zKZl4$jxqb1SQuVk7+q6Yz^-VEI0iqbz|Qh{lI>QE;}Ye+twLQ=GZcyel_zb*##_AY z1+1TPr-p{`1P~RtUT^TS!=uGFXwnk)%*~-r)iWvdeZ%zB^OGh_P68=2w+oGGJ${FR zuQ~P;*pGq6gk)oKu&C@C8{$kg9EZm^j^w^Shi{npCuGP7Uj@t0rq4kKstdqZEU+TM zePmi_N>c2+myia0sU*5k-Nf+9J&MP(vncd2lh%hl3%Pr3zi@tX+_H_xpARD~paVN{ zv;F(00k&W>rQaRfhVFioX2+@OMW#)?xh(kc(o~S?BaWCC2IqK{9C!swvxG&V-MX)m zUHfd(Hs}7Jij#a~Aa{sAEw>M<*&QyHz;V)}EyZ<9!BxcAvNK$4ppp z(Qe4^)6t^SI~b!}KwuK(_h_==i~qy%msY5n?$*C5c7)%`yi(%*vJwQ#uKJKmrkAIhWMd|WK?4R{5W#LG{Sxd>ClE7FHj(bt22xEuVCAY zWHBx8u7;5*zO?ohOcQI{1@R5iw=F1kEAZBp+0@yAX2O51!2nl|=X+(ynTC7+MEZn3HYZ>%PMdG8}xpW6lb5jrA>jJk2>$ zunG}oFi>g)Oku6oq^#P9FfxiCPy0ah^X9a4g*AXUB6|92$@@Doq0#BmBh;rpEqsrgegI8U>W>MM+JFv zj>(~!N~O*^Hj+}|V9*$a2BRZd?lC|#OYXqrszBo9#f zzDQ{Z&;M=$;qGQg#^%Z3Frp(sfhd;y*5x`yA^(*e&%YZc)L>4puKHV8l6#9QZ zxk*lB_J(ku7n{ARqi7?L{GgaN;~s2vU>6Ud9|Sx7Ybs9MpXfeLz&X8v(5?E+KznP@ z`L2k37BMA@>c#M|iuvj==nC>TSMm7&8n1)4RZ$gu!oL z>(#*jekaY<<;T^n14SB)Ul&iMBg7Qgf-L z$C47ORv?RM3LP5v^e|cE`bOc8Q8eD~JhdRPi}*Xm{tfueURsXh-;Ngu1nBW&obUgf z$2ie;MFO#>EBXF+ZVd;_>VSOmt*@l`m6EA;lUGPY7?L_Gc zd90;m8@+A6h404qMg>$?9OHXJBgn&hbz!&aTU82uc9U1cDRZgb?p?mFU7znyyB9Yz zXm9UqzuzLz+>e3Ug)nZskn!u%PL?S%5+7cX&?(;=7}H7MDgRe%$N?WxP8GI1Y5)>H z@ebCqKao7qXdpH(tA|cDj9;R`{+^ww?GZ9batl3Iy@?@-TG3Jt;_V>zLvo85Ev?T)M@KnZVfv={2{ad`trZEmMiD8j{ySfM%L|VR z%HstKmS=e)sMcF3#3p~1z<5sBmUTump@TYVS8hKDSG7z1nS&Y*?7fX8agq_GsYTf-=1l1DyHPM6|n+_#E+=< z)Kn5+k3eJIQi!hIJH?7I1Sutd3{XqRe{gcDcJIC2dOT)9CYdOc1W!puyj1HJa!-8I#qX^TYI#IyA9Mc9 ztkY2RsM`tOkZE3gX^3gD%Y$m~hbenvODy6xA1+WsLv7~Lz_5!M*Qweb20K`3@C_}o zB7)}mE01;!{-UrniRc#LxTmme4)%UBV%CRAKkVsexk#T{Z9bDklLlkjMUYU^5(r9! znG1Y?hNECKCAt$d_IbdyP zXaZFf=0r5ehij9L{yJYgc|<1cH$i3pEhg%FE@$v$GuT7LoJQ)hBhxa$0r`u|Nm1m7 z@&ntHTD&1?<89mv76qrHttWX{oYS8+sWSHoX$&iu$dm}F63s~h z>2kGF%zm4ymzb&*Kwl^#_#E*r)5DeHoEJ@8-Ke22_>MT0XTC}{kLGL&r? zzB#X@+q$E8hgowct}UaYa{BIsa9{)3tKfQRc5QTGJ0Q>nflPL^EzjI=6|9JqFt22E zbhWhb;I1o!;w8=5Nzwa@w<}IBhYgc{uRm&cHk>G9lMak1#23?u=kb99r!yv&`Qf7q zrUppF0RwxS_(G^f;?mB!F9+>RLh_h@7z-h2bu~vV*I;V&e5J^163*37BtLJ3LB}r^ zOw>3yD#`C`KYxnNASP&z$0#uJED6Gc3B~Dr*gkY2=t13;d&eL~u&hR&$jqop-dc(}i5xCnk9{My2wTrsfl6^{JzMM+TOLyMNRxDy%yquiYb9gFd4HTVn&z z@Vk{Re%{Qxp`6U8YZ+mQ(FT$dbxBXcvIjh!oLz>G>1jqkN@?j zp7>gWMqHIvF}4*%$lZN#bs8OZJ1V5&& z)Ha!J*0}Z|cCR34V8nq+Q<6+Ok&48rA|u}#+)^%z8=|Gg&3CM2lnxM8$Z*OIwQM72 z^c`%cvh6R8P0C?*$UF%&7PE_$u`f9y`{syr$m*urEuR)s9R*hO)QS6i=N;z_V!jzoc1~>qcG^e@UkRHc)Ov$pVK_UP__Nn8M6ii z_;Eu#P@?RECXI7u>#>O!*U`s9twNIQjq4OkZ?XQtmU0%e25P{)05?2}wpeIPA4{*J z4`sYIN*{br4PVK@*_m-CUBB2}p107mO(Zf(1jDU2Or;0@St-5Sq>@BS_3T3fN}@~rJfR?3B%VS;HY2{zevr+ewZG-Az|Sj zLF;wE%bzi)TY|Y)jPE~dk-q?oZV(TDUMdW{cPRuksGuMJ#)OmONiJA?eX0JuBi}&J zV$jX^u|TCcv!0mB@$u%bmb)^1qdwjar52+|Rj!(}8&|Y1QlL@|RGz_G#@I*8KHdVHZ^vU-KJwdVPj=rPE_88Bd`AUa{$pcxWeR z-Ee&_Cg(nB55cEzxD?!{mV&IWNM9Xg#{hYe)ax#)!|WYFf7pb_Dp$oHE61=Q4U8!i|RXR&@jRk#bbs^D8~k&3?xldm9sw zR-E+A_OuFLN4n(R71me{P;qOd#JJ;$T0!F$#EvrDT3C-rXiUCvt(Au_y~;YewP;Fl z@kfDJ&&K%vCSo1BC(m@&WHhzGSKj=<$}gI`q|DoG*LaTji5MJP9C(%TF(g8t?q3LP z)KH|dUd_vuD>bk|Ye)^-uQU}Cd1D1tyvus4m`vGu_VBOqNsH0)@S&sH!nPqKqL+T7 zHAdPEgVPz@a{g{Xz;c1yQUJS+q^^&%(r2A@GZ*ooo}j_<30Hrc<-E*M898hn)$zjW z?(Q5{U0zT){X=}VOb{F?r#v$Iz9>oql!7EK!g1rMK* z62C2HJ=Yh{TfE_y52v6Thqtw(0^*5>j3Yr}sTJd)19Q>10gIB5!K9Zel<=WsmohE23|aPWgnwkjL<`C6kIX7{DrS`w z21J{dc#&ASe!f(h)*)4{!63=)1?$LF{K-5BEM5 zGV?s(#cxuJZ~T_jN}{XmRPws%ZAi0s7&c36S&vTgVW}NgNT7~CWbDTMi zNf4tGI<=kGi%W^FsK3Sx_&xGi=J1IC`vp$P`4%<^Bvs9n4FYT%KsLMdod2R^49EUS zAccJ(`+4nDAIF*Xfc|qqFg8fc07jP5iCQfdW>-o3jhvv;Uryue_#l?5(lQ{u$=!_b zAbBfqmdJQfqHLru>J_-i?%NG**CGSJ-GtoByT}_U2xZ`2j>N$03<<#_t|;ARyUGk` z)n--Qv?^W+bJ`_;-WhH!H0M(Ps-W|eMZ3MOq_mFCLMzEFnQu$|9=9io! z`@WW=%XQork%5uKaME#hr-{A*!7bwnzWr)UcDi z^E@|Eef4p*-L~{h1~kh3G5VnPJ07rKA3KXh(W_BIeaV`h=E`X@Mp_1KqzQf6)%P5+#TLhMO2A9Q*lUlgL+r7z zPFEJs{6lp>q~uJ&8)YvIz-dXMG)4@r$vv0=86Y{gaai78iL8KlQdcv?qu%=ZYvqFS zx*=+H*?c286e|Pn*DkoE;w2>`N$%r)-b<9?4C;sWuMFCU%Q;J!^Y>$?YHdm{&nCE% zWwIoG19B<7?5&1-4@NQd$n6WEL9X&>O!hkiX$?ZTEQZy?{7{OLAt`dIos!`}<(Ft> znFjbMZjtY;xpV_q|H6zE-7!GW#pK1+dhR?Tgv56~b6rWT=P7~_t*wF;c)$0ZeqYGu%w%CU)5cSy3fXYnN+rBpeuyxX{9aL)447Q4m|(q* z(6ndeHc|x|X>|qPVy&ZOF=R5;9^kNKsXa<984s+E~-?R$nx=g43&{wvcp(mnf`2 zVzcgMNZ@%a?q;+qDfN_Y0a32DN_G#=w0sI2=Gom%z~3jqhfF zr_E0$hxN%JBCTs!WN;hL1bOCjfKQN|dLgfQKQV8JM;xk&P-2fJj};8r^q=-ZSetUe z-0u81mnZL=X_zg!moO9{3&8{$0gM zZgq2ZQgwFvUVZi3G{;x3V;BoYIoOr5B}Eb#&`}?i0n0LS1|`*NC|1IYYau&@Qho&Y z!`+`jiGH!izO+^e(qR!;piU_XAoJg&-D7Bo@=IxQ^4rzE6 z^3@^N1uNQ>a>0Tb4&A$w2F%X3xCme}pcLLYF%ipJU_8B?g(T$ctf#vqG4!(0Wxej` zzc}q|uNNvwa{v=xHp^3H+^WtZ;|rjKMZR_^sS#XEu*r=?_nfDF#x9lrOccOj1fPs0 zB)!T{qr1L-GmdfFJErt$yxaMdCxo;Ium`8!=`Kaozy+KK{gl9>rO2quUQ`hapbSLD zdiN__g8{xSwfp4?=Ks}rp}6~XyQ{1nsr{7|L8;oHq@yZ$XVj@(BX0qFQcPCV6_7Aw z7F)YfM6fvAmm+5GdAZCuOuCeA9fH6^7#R(l*6z_8Zai|gk~f@+$|2>^%klD@&31$S zc<&~}0L()!FhrC`Jk1(|jS|3I>}Ns4WR94QC*HM!4SiNTknm?-3l@A=L0II7j3S3< z^6Go|H&1%tofhu|=2Y{nPEF;}6|-5dZ@#sPC2McLPO@6v-7-3@V=DE$@y|o30vG?_5Fw|j^I3V(WFO+ z4f6G82_{w0Woh#p`6Qo*kBdp3#g2l1w`T-o%p;uhmZ*hr3wxrri=o8eWOMeYwC@Cc z@$`ozNphrLR0YBQ_FF6nCw%MG6RcEz4{_Q>0#f}Z)9v8EeTBQaJQXSmgn~g3rEA^6 z^NdqelSL8p-AZZ>`1(&{h1!AN&dFh`9(eeFzq((oSz)310{|ZT|Ng2_e?Pi^we`<6 zI;e1uyks%jHJcxyC2~tqTma7_9>0}ntH9zTq@CNQa)^t8DLy?-9=qMS7TrVVFnsI7 zZZO1fr+lELTQXTuKM~|ZSIDa4dGA<kdDbQ2;WEMZ}f*&p*VVKMkuHdnrrumhH9U2 zkT+zvRv9WJ`WOoSE8o=BARfrw5H=PJ{1i4d`bnA}43MAmxed@5fbJ8zLa&EsIht>) z49`~!M#ukNw$?z{e=|J{s!BFJyZ7LR8oV0)#^5g0)-cYPv43|g z8#3fRKMeW#`S$8|)4Zzn97|jayf!HD@^BQfgb!OU-PTCn+G<05L60O1!p!rrQNUK9 zmeI>~+!mFD*9@06&a=WI@E*n&56*0;E^L}P~cdEl&?hV0d#bkM9eyT&y;-em$J zG&w^FCm(SvwfUMIim4&-fQm&wST;WH3O~R@`@Maq0tzMng+|=27tSSC#r%}7el6Ll z)vgC}s!@80>*if%Cc_$WQe0nx`73ivWpv6zRgyB{xp0EE6CpLk2(J;~I0#X~YbA zq0OQc!XGM<42*@nK0^e&UDL6;#ayf8J*$5sIxatwOaYu?Exv@X3RDOKW>a7Yr+E12 zpeGR9eg*J0^HmSQ?uniCabpS}DJXUZJ%jGq@Op}pF=%C%|vQRRveI5r~JAfoXuDxn_&i*c7lwWJTGUwInnbr-{X)71VN~;?i z#EcD&1}>r{eFx6V+db50zbH2Wk8`><5}rVD+ZH^mX)Hy+GO{I%bqS{b?(X)d+W55{W+QIcf0O#!`BcWT`eGTGh@ecWtmT+*FZ6 z)1q^_P(1P9BSM>RV+Fi@Y1sY@@jmnhtCZbVqM*krDYLKog2{1;-(G;R4^I0o;Ym1yYz=46 zz5-MESDwi#URxQip;+I!IL6fd-br3aBV+A4ACpuT93+&8y2NA#r0hr9{REPT9Vwxl zCQNWGidWx&bgYf7(DaWx8HajTCmZ- z*0^LaeGxol?y+8(F}N&PAYrk- zJD^zNXu^TRu7FOf&O}sa1v=jLTZX8h6H&1D8u4I)iLmcm8TtZ75gPya+<}Oz?EAB8 zg@JF$0aEpF9H;O1;T|fmy4@3_Na>n~kn90U-mhb17?e6E4^`21{n}-WQehCktI_x@ zJk&%$KQYP67X{ifPV5rR z^Wa33eVd^Dr+|4xE^ri~3w^gY0cBiMd97xbp9Q0iVaIoule=K z1}i;-1rcUb=vj{o`Iu7Tglcz#d79IQ;;NYsC?b{jJoan+htmgzev+*dJVXuS?y#K@ zZb+Te>%VdFs5P*euwkC_t^2pK`*%2gw~x}Y)R|C6@%Y57(4iN1lv<2T>XKO3St(r$ zWbbArBDfI5cO!TMkFcru#DZ$@W))Y_YbJ<89FGo?)^S=j%8>C_v3NcTJ&Ytg#@gQs zI?xBCovtZCyA}{8)GS1;fAE>#UpIaWZ0qFI(wl==rE8L~w;u=Uelh22^bcXcd$|XR z1ZU!T`I_|DlKmpc$4Hp>G26sr#MIxYWoh4;ME-^sSm@OzXk`FX;dSR%|4X(nA%xA= ziDBPha4gWgl@-=;V00Qoq;1Y2sIrLW_O$Ul(Yid1Fe889Xqb*tuDGUdGHD5Jt??Pa z-p}x7=FF-KSS%w7BBhe+%6WRCEp#`_{Vkiys`CDdC0{k(?qBC9Mx6Sc;k5qSA zl#nKzH%vCe69FlmVXTPPpoRIIJ0D_Q1d+)Dd00sHfV3Uq%re$cC#>2_V)ni~gGnZc zeVJRZ7H>PmDdp-j&?;ba#btivetmmO59K%+;w);wvi6alm9iwCqSm<#torI95&=2d z3jf-J#ta`K&Ag8DH0mN!c!2E~h_=~=@yj~Zh4aWGc4&ZH+eK8>EcuU=u-cqR2d{F)uVm+sdJIl&?-|Gi6b6s`I+?H3mPS5C8&&Y zs%oXm@xgo=PNvNT)*y>o|D)S}k`3$;{1sCAE(bHr$${$|8{|oNlzT|rc5(kvD;aoa zqfoqBAMOfAYJxtW7BOtleCG8?2I;Khl{zeDmXWP`SI9Z1Mkwlp-cl0@yK*8DT991r zc$qCP7?HQ#+|C~>nApb5L84NdnvpU{jGMPzKsT)$W@ORIHNnKJuTMyYPI2xJ&0^E?MPaz@>{=Bc%5<1REez`mi7Koz&X4wN4H9Fv#gbL z3e~?t$Wg~oeWmitdbTZoLCLz;US#D;)_=1z9_><};bXqUuaz3_Ax8&YC)&SLYr4Rq z8?68436h|7S6({#;IW(7ag{1Nn-Zd!H*C((QCNH$=Nb}NB-h-pSzoy+sE@PHz&qmo zsejzcHnAMoLg%65Dk;-%eHNF`Vz%$E#$Kg`uTHoB3Eb`J(PYL_&Ax+LRa}0X&bE2W zi{{cD;@Hw@VK+vZadJB>JsVqnac;ywYchqer}|5#tU&1vo6}Hm9P}>118}eCAp|++ zX#}a@83@VH6L2^0K7d&KL2x?sF5ouT-Tzk3AOAkapMO8^C3K{-+Zp3@V@k&H)Jc+k zV@J02;t|jMB1%TWHNkN>B{2=t70>u0Pqqa|ln4oiD1{ATo(LU!B!vlbGLfwj36BZC z^7EdeV-Nw;ODph#BQrpui4ghH;Hd18zv+U^7oY~=#1l8@LL9d#(ygqzbVYl2pJ&>M zEjo^cLxF%mJH$VYefY~__Z!7y<{Vu=kdKi4CcglL&7p~a&R`?XZw=KB=2?Q0z@exA zcclZX!9La*n~p|EpAX6ET>;{2=JI%S^zS~MAzgg8@&wXM~58W)&*xkvKKM18xT(jky^Fuowg|INBdZ zYv1{?3K3=|aR3s06x^UmNkyqHPW+Zu^-7UzM%%3vHqHZ=l)fMuqA~56%an(ToB=RB z56K0k6O(=CWjE8ronlEs`H}2Hb|J0FtkPTuXxsL#T&AN2nck zkbYT{XKO$h0=yKF&jGbCQ!*eNjy@W%(F|)1f$>XG<%8?j6{!Mgcm=tdaymW4 z@`XmkDFt22=2*#0&_4qGI$mIVrI$$BtMVg-E?T1N#c!ec1R}Np==@b}u&{jn(XAh% zMkr#W#D!I)Hu#zGV^VKe&olaI0-pcO+O`9cIsCi>?0fu1q2SKbgu(!N8^Z5qSNXcj z`V99E*%CAZOOJsxREYcFHk6!F0P5pe|BxMpD{u;SJi3{~OYBFH{4)-Kkqh%3XIxLT zeeli=Dbl}2 z$kYc?k6do)pC#(A$H3iS9uC@)(SsBw6~p5nAk`L|8=1Bd-PA4}nK`eaIR3A?ET1JJ z$x{_QzS32k+OXge?)UcoE-gCI8Uzr?^IJUY&@Y1NcOCyny-9UZ3Rx9-5}pV!w)$U@ zU)YNPFrQ;F$735*v{V-dZE}09HrCb~rt&X`Mw6G%^NVy_XF;Ep<4mE1i-pV0>DIN& zHRhqN@}o673!@@%?m*1#`IPZ&)X((jitkn2F1B}GH+%sGnrX1322l(U$7=~>Y9u3u zBR&fkvlE%D1i?}OMk4Zh9+!A7!3vjRHNZlAA;hsa062yjXTp>(2cyqIxfWVA4 z7b>aP+V?`CAJXe=QakQkL+&o!Of=!2sUNCKGUJ_PtqIq%%(Oq5KEteDrcdLJ zMfVd-tnY%>eJaEJKQ>cph3g`txh~0c3I(mNjo{o86Y-}kXYf2%oz7Kwmv?B3mEvJ| zZpNUcA{N3`;9^mzEcY(^J(_N@J}d8$CXD=^m7c5diEb|11#PNScB!%IG8ZA~Dssy2 zsh_pC`8CX?n=wtB#I1rr9_uh^%Oya&q9X=Ts0O|z6!(TzkPsC#H3Ak5G^c5Up~+UI zfRHbxzi>$;{MVdH)a(a^_oW?rRX1pTR%0!be{6=pFHQ0MTn*cs9_59hxAJxFgYHfu zj9&>}40#sp0&JM04hP2&IVVum^^(dT`i}MWO6{q<3uw@~C#fsdJD|OTX7-UcB0LU*An{7@ni(jG`Zf?8{gq9vQaHCM?>@94qJ?lN4?4RTU( zp(O?(-f{a!!R))1OuM^OuTEq&itXgo0PeJ~Xm4!fJ~E|*i_ZsuUEel@-JQX$0IG#a z1sv;<5wLZ8ZZDJC=r5E_n!m^O>*KbT;-_zrOU6!+1*3@lx!gZK{w(Ukt}QMS1IYkFgiAxCf#SJ+)ct_yohWRh9cu5=-I$mQIfBqmq9c3vS12D<_Ao%;c(6AEwy7 zc1Ogcz~cdm+4um%Myg>U5Ib% zO)5=RnTPD4Q9}&F0-6r#{SLXAvW{!f0=Q0BOaC&79`g-OHFC=IOdX))Y{P$gAKSv#I|mWxn%g*hPne62^5H0EW&NDx6syj` zWbWyM)xdndHMkncinEp}q!}2r&ae9XqXopM9QUBwP51D*M%)5T(pxN zYnA=knR#8)C!J7m`-j|Zbo4!>dfUg_elIocb-@!!T1ON79n*1P zURm;RfFv{1aRl_BCJdcs^XJh9R)0$R0l!D|FIvgE ziC&b42mV_4j$gO0k^{3_OVd9u{NKks+`dZxYG!DUz&p<3!t7UV1v!=wgi&a5Yz;Y_ z!4tC#kepFmT2PO6&AQ)Oxef3ug>Q_4_+6eO^61Fr13R}?b$@hu`*eVj5SE;uonus8 zRJpWbTwok{9yxI?0F6GqphR-fv&Vf}A9m1Dv(!wzkZ?Saou&B_aq(!J_!uJ=qNv|} zQ#F*NlXK98`TY{bA(UxseWd`uM}OT?9T#Q>uKR3%WfIa>=xQGNXwf7558 z4D&jpIPlaVtwe0ZZ%Sy499f}bM;ubIxu>4?c5FKXMQ;Q}@yDG!8O7It<-3Rdo&V5p zX~QJ_z_2TXlk0eg5p{J>Yrie64THSAVVHu$(e6x3YbbAP3-Qx3t^J^NcasE8Z^@&y zxwJ*;&%jj-J85AWmcIT@i;7(NyHw4RQb6Bq%j&eOXwVMY z1*S#AgjuMFFTXMdn~u+DK})+nYdDGaF_A&`E0@sGwMmsmk=7E-YRsJrt>2t+F}gIM7SA$0*x}dI4e>S>!Cc*>zN}} zXilt}AvMBynyVs>a(qbnE)`1U?bBm;b}HhGUOupZ%#z|`;=^K`6|LXZ zq?2hyObCujc`M~bup^p)O*x>#Xvb7vNdxTB>X)4hkcWT) z6r_Pcpa1|MAOHXW1pjRS06_n94*&r2@91diMF0PXf&O0@YeNq^7w7*5-PSj9djAJ; z|94HC|AZPEJ6pI~ID6>Z7+ToUx!YLhB+6P2G9ZM!25j}e0j%tBkY00b2hY`D7FV#U z_(>#joS#!$8-`0Gm#50_X0aD3x`_bGp!4)i=XLzmI#hy|6P34Aw>p`FN+=eCuAuZJ z?nXuE5g8(hRI_7O0TyxAxu_M0VKLWBfJPCZ zbQ}caXKqwCnTL$`kUG$=^C`Bw#gMThgga7$9QMuz{yFD+zuWZcA0x@**yU+zo1I>M z3apvx-eYCo=mPFo6Gu?=KnBX(%-}&4)&eUY`r%i zc5@~z72|UFoosvq{?9v*OP;g+`A;gBf07aZe@NzJ=&b+8)KTBs!s!33ob#frn#Gx# z%)ep3|D;>|pVArshjh>~e|Y*>y&YT}R!-5nS zKSF&4o(tSQFS;_P+{hhY#Mo;Hk-6q^rcfBpZ4iXTSN~X{3I|e*#+#zLtvCp)8(9}4 zx9L}h^Z%!I|K$4L?uGnc+S!=ey8Jg^!dQPO4gLez0RjM^{Xc>Kh5p};jESFx8eo74 zyA8Zm@I+PbPL;*U<#~fqYTb*pQp$Y0y}mx-2`4y7O#JGJYc&PvD)%}|s2OBSu%q6N z5V3+`#|0T3W}(M|8X0bq>@&+ef0sGVe8c!POuHd^0)$eW<)3FPSYERhrm# zupQFx=6O0Pq3IS-K(-D$wMOq@r5lBagCW9`Uw@VhPs4KzCp{ikzahoFfK{+0ymmMR zkxRx)(W_I_L@zpywPjr`Dp-I}m(a@au3LcF&4!o%PkmBY>I#Sc(Y5|Z8~4A_{(reD zCcgi_*oXe#>`~x}+#dmpZTnGIOIb2z+S;-n2?Eolr5^n7ZJfY+P;;z!EDo!}Td7Q@ zahjD>R`y^_4|%BPDUoZbfGQlw%8(N*kA&aCahI|J9ms#u|Ht@$+XMOkqHkeuV`xunZenji z>&o)qj51ta!=efc0HF16BlHLLl{AGVMu9#zA>=2Yk+n3WHhPZyBz;eW#u z#(kER^=}CW0tlZ4*t_iz(E$d~2Lbr%1N65f1F-ivZcVSqLqEHYsmIv!b0}WK@|1(o z`*6Dh=o|aV3-Z6xu>~;rYvnJv3-{KTf}K8gAJtS>)Y|%vz&`CRd8||j2aY5x7mAKL z(6K0CeUL4-{D5{RuLNimc%-ru?CF*9maCq|c{tvNosThJ$PkT@lOasS7z#4TD!+U0 z)qv~xRJmMoOu3IU1Cy#?#X z+o{H%gSP?s@6p8F0bflVJ{%!}Z$NkYk+%4%m`hW@abfVGOb+&Ms^QIH9zRFOO=F+> z5ivgWvZ{JkGtc`5vJp}PVnt_hA4*Y#0{uU->$26=2duDZrNPs|c4niT2>7A~x5jlss^prN>mgtVVySTOyr>O1tyJ zvc|B;!b#r+qP}nXKdRzW8V34^ZmGQ z^4?CWE4zEwk4`7uyH?d+%kSNMZ^t^{rBYW&X9)nk%81;!fRoXWUT2*Y-T9* zh0cmmUci~Zla1JDWnvBsSQ-afd8-7>g+$4^CrGh;G9uSH18c}naC3niquFeChdb}B zRo-t=`704yfw_1G@#Cn(OfJ@PgfYW9voxBNh(SsnBch=EZqR2)_ikcb1*x z!w?tk=M39z?^9Ef8_$O-xzg3pB{yl2ru8{#r$Y!)qa< z6GIO@465^X=9o%C!g`KHh}!qS9+T0u_N1DvTLG<#jhXVMuJ7-mujZHQtzHRX44~$K zxxs49?$}H)qI)BX-mv|43(&TB!Kc{;Gq1PD1X4N|41_?eFJ-~z@yQ1t`Sd=lS|_8YLZJTXrS&%_Gf9K*?x0vOskI% zjTqJYX#kQGm{g|z`pCw&ly(l#LQ9d@$|oag?WAfCg*Qyg3x(agz=6he^QHbT zmY^mBoCXWnh4M_*a2zqdfn)`HSvUG|2S9f^A)fF@%vJ?_n}z+{3X_n zQRu_-?~>6-_R6aszbe=PxN-_K?k-g(jWQvaD&l zE66qchaeg>k!A09YMuE6u9BME-j47)@$^ZYp!6u(ZBo1FwMAj{_QX=n?xOAJz_*Mv zmidL?3+m|zhZq4-iGnz)?&wfg13OlwV14?SrLHmQ%bQa?4ZO_XI{NJ42D;HLYXz@6 zsYB+kRt(cUdA7KA8&t<@^ZC@@K=pVh5yN^q@fN%?g`HwUw#x%R>y4kiQ)2d>QXG{H z!+>{BDrmIKZtg8uBMF_J20WOZfECU*y>d`$dQJDC^-;Ms4egYUBFZlDP74z8+AK5a z^*5?3IWWu!V|ey!Lh`{?1<*gl{HfLOGR)yJAc`GtY<};{RwUuB4+Cy#wY!VPb$!~p zci`ZG!Y_3SLW(v!0%t5#?`w5vrlQ3si}S|{-pP_yp(3ZkOI1mNsE658W`oLO2H~XZ zM_l@6owpb30aq4)#xU204L5?tG`ooj9({JZ9hr;**~?aUssN1r$b{1V)BK2~quUzX znCY~^8hjIR3!m%ZZtD#4*@p~E&AN|G?yK$SkHsd#rm(Ujv})z+N9B>oSc3EyH8?b+ z$L=uUBLac@yM)1L_y)Dr`1DWt_&36{xQ3&VfhnUCXHM^Ni3@%QJC;2j&8rX$yFs&& z5Qic!Ms&GN)&;mBzQ0nt0k&n4xBUt|Z9^uyL!S9|1DcBYSEl0yatE3jL_?AiDFKe)P%&{0onV!ki5<7T& z_ymKlRnw+pD&<%ge3!Xqu>6VaNO@}4B76Ben9u$(fT6r7ShEFdU7Am?z3C`BrkHwk z4AE%kbK`mKohZ3;V5V0*YaTWgZp~w~Laf}jW$;Ucz9l#@A{s%fk5I896yY!!OCmqh1>YdZz^~}D2H(> zE}go(o15b5p|V(Oq5#qvIdA9rEQWi?Yw z8&k7mRsWLLqhedV!Yeo>-@8dHGHlL5m-S2Uu+-?ALcR8B!K{1hGO z|J>R}o(Y4@bq&@{z1kKNbFRb}-4?NAve=@Gx2?`2iQmg*&SjI}F29>>Y_%X%>m?XA z-Kj5;F;kYxjiH{{F*^-pumiI5kl zYkzwjhH0{8^xA(3iYb~8jEBG`mdSLhbrt|_rlmt;B99#_{l9e{PfDDjkuKou-P|7v zzdv3PpXZvN?7emmiq3C`&awdRpo)U%`NWa(UC|1cNP58wX}NcA6ioXvm9<4E2JnhSp*uACqHk38;wL;fR= z1ImFkcn+7B{S60={ezDI;3ULF6n{M9{}?3r&sh!lHT1`UnhDDM0B7~FFdqhBKVw28 zaYY#bz=IqB@CyO}-hM9mo&MlCKY{1^004Iy0Dxha)uF)ia|7H^>bJ;`|2bZTJAHo~ zl%2SSBLD#N^IR|}K!A)aOaK5PPeMdc*?jv-L&q9*1?_7lJN>c7bwwX#WtE&06lWfL zL0=<3iIs^t?=NybsK|UuiK09KHW(FDbRM!KjUZxtg=)EZWs_tPdVu&mwM}6Xd2#~e zo4%-jiD(lWD?GXVZHF_4b*-<9%k|md)aA_0H7(F01ia?Yxc%8@=e7N0+iEvtGwyP{+wCUN5oL7WxofZd zgg~1hpCH(4!f@?z)BEDUqN?-uIb6-x^R{~d(1zSrwuh+arR8{1$lrUxNo9C^xfwD*eWt2tdV-@U2cl1G5>U$IaOd^sWj9C9tlDRO&G%>`=Hd7! zwS*n7C*XaUshHc70s)xTq5}alnr*ng<7+gRpPhxn`ZRbh#E$~TJg+TQmaX-?e_O|F zmXIH*B9CZ;W7O9VhJgY*P0SoGrb4H_riMO!JuarRm_Y-EdUm$Htt*gXvpCqP zzhM9)wIvV$f#}hLYR?#Jx9XnamWu(ZwG~D^3pv&~pZwE*eeC*LAD{rg^vEk~%EAMz zZ8j!D*k+dnEh7S%?9KPSdKmyS09t_#M+H)#pwsnCX9K~B00a{DOhlCp=-s#B!RKvt zyr=O7{t+ZC0$Q>>r0@PnroLLPW*e_|@PxMvxL=LtN=nO=9>H`67b`u=_|p>dZ})SJ zq|KMlY-TgZc(h;&TmmJxti)nr>A!2RN*0oOHRix{anb_Byl5P?;$`0U(^*ZSrxyh= zh%>lc0Rikk8p{iHd@R_WO#cK;kkKv#e*gY$JzZ$it7hfaZnIQi!bNFbL3rrhFtVU{ z>VA7STuUf4S0y5_=96b8=SBb6;TIa<8qnFmQ}<4O?l$R#2o(a^>M-rFLL8 zj6@&;p0cIN>ih#f)C`jeddq#7i?Z*?lJ_D7?#s=M8! ze@Vsv1H?u6LJCzUhE&rTz*2T#v@4IE%TWLRYM@Ahr?tD>scWe=W}bR7VY87CV% zGs4W_y!to1|0}TTacUJ?YooQ8?L{7hJMynEjoKJV$&x7nN8o#SaBR{d34^0O zmO_rCrYJ5|iIeS(nm#HQ_NshjE@kD1&)@g{KtfN;ugCmCvZfMrU;7Dk#zYRa8np~h zp5&5)%Nuqy)YpI}1rGx7=SK3m8xHqLlbA9nNu~yKJ6@Ky~(Gd4#xdU#Ld=`d=tz2>I56eDs{7#gha#$>^hoU<2U7k;M`FV2Oc<1=iEDKQRf*a_p#iVS@YW(`J46fFp?8T4M6d1$;7O z{Oq`61O|X&Ry!Q)#-L$f(`{hEp|n=m1DugbeC?efa*oK@Pf&up7=S-Csv)UR3FC>& zG6Z}gbW({$N{+I6$2YG3(zFylOiiH+GPq5WONl2O&Jf83Vo1C^uaNb-_*>XDbv&T4vn}!Lt%gFrlar%@&jWZ65Lvt4~}) znl_FP2k*HjXJ~-PB5g`@uLfi8ZBJ`zSu;WES~zV<6`1Q+8$!ACyU#|O7BN00r}X@( z$P}pa;qDD0Uy8p_?gsu5;7f*xz*7-0Uq+pRzZlfy-dax8tyBZ)!A3ZA&Mwpqr>qE< zMXy?XIs`&XmD!+i;R6L?0NEz4yl6~@(GYNEkP~9E3P>vcOY}>k9QB>FxUnEP`kC<7 z8sQpA5AqD?JzA1j*{adRhH0v}xhY_E_e{wj;$fibVfxDZu9Y87Cu7NZXOBxfD-=%= zGs4gobM?_C@R>k*jYAdlB^`_FF4gFS!ISAn7I}qiy;Cfe4KRLhCOro*{3f(~eQ*Qnt2 z{}W(iYiwca{@(+pGhY8^1p<%|l@+NG(hvCW=r-!ltp6$9+5BI0+wH%>+f}p?v>V7j z3zHxF-(u5$#{9>+$XVT$adWQslYX+Ieqtn|MdE=z4ACG}rBI7bBpkf}g_kybdxKho z%p-{`oKUjKTtPJqGT;=sTkQE`JJX%zCf4;N%kxhj6uyxsHvBW(AHi0Pwe> zGXJr5@tnVius7p`#rsAFY89wB7}(D>e9>&#Sj{siI->_20D21mJfQ)ywDAnofOgw4 z0UzDWlcvCc#$P=Oa@XepALGI*thYM{>g802l9XFZ(%k^Rj5~f%pfxv6z~9=+LIup; z@#s;13uz;bR0eoe4m^^NaKmf~M@DlI(gFO(1pk0w37Nzq*iSkY%ac|V`kcH1M=1f` ze9t-eoI-h#l6N2vc|0UM8MmkGl)MDYkgMX|1rRNx>Wv1WMu$MAg_Gc;=p(BgU1e7A zCOGiDqj)0~|7xvod}}mz1KVxN7rmwmbkgh|{>wEAT_MnhtXz>f`F3S#AGVCo(`h>x zRq7j8Nz2qAWWPC(WqvW~onTh>cBigtI7{uc9&!~fRNcgIgsd0mhp*-d@X(K);e4_) z(C=gxg)Xu^0y7Elt1X(1VJs=Li(x0dM16!=|7xS|% z{2=ErV8x9__jA~g`XU~aXBs>qrAx!wD7F1qZi<>$j)_(mn*8OR@8}aX zdP2^V)O`~CG$9TQ1JzXp#Oz&Gc>RC?mr=E_uAYUrmBP;DP8<{_{L5xN4%Ua)KmaJb zaJD!ND8AY=WmO0yOvu3CJr^4hZtjIO{fd0I%4Hvu3WRXN4y$q# zyGVR2-x-uw{hi>@ToQi>i~#yDq@%Z5nd3$Kix57UoM~11DYF03aYU0uA zwOPj7ohm$}2?Jt5g5bC2FRt7uYpAjU&)uIsp4Uz2X~$nvj`YlY0aIO?N96^ko@bL} zJgzdLY15~VQ)5C0?q?7ZPPR&1bLx*N(?;c9m}RTc`qRZ^a?TTUrFyjRtet{!Q&A1o?Yp#H;%**1LoMrmp)}<9Ep3T@Jurd^6Ls`B zQu*>V;mh{g9Hr~3vM2FdRMxI!tzOJD0}N{n47MLuLyln57>&l$#QjeMgL9@}x-XGL z(Wpd`TEOk`$mrSVQ3tPRZG+K2^u*4h%j3J@$@Dnd3q&}K91s@`AZs`7R|NOt_PhDm z@+_`St{l+5`WLw8RT7H!csg$3NdTgBOHdIkYa0hoOZ_-L=jLgcq1n&vJcq1>_;3^; z$NZ9!s$0F%66|8nH;_0D{YsCDwMHC0%7Bx5WUbE#>F!gknWaB?lK?rx@PWVsKMxah z#sSC31-Fq^%9|+zBC8JW8|%x%W)l*Y1PrTq33ugipe|<{zkBhso91MOfMdQ(`R-!i zg1!sEpvmLOkY->1yd5Y+Bf1w5s$4}%1@RL)GIaE1r`Rb{2BwL?o8b>3eeanQ-z(F3 z9K_32ej+stjOD?E`>3pcXZ%r()f7Zn+UudXq}QZl z{0Ov2)gMbC^v9Sk9s0*!cFNsH)Jnoz%YzWyLSOdx(1T=90ierh{6cKsw}F ze5DejDL^Y01heEJK=Y52%8W3R>SSBZ)6-`xts49Y>+1|k_40zU{SUQ8$=b6k1YX)u z7ady_ig_-9w(vE+j_*9<7W5tJJFh%iZ9*r06!~yfyWQXltg-et0jJxi@m{^?%-X5m zkzZDkXA)=9ywtvFY+xntzOK4yQiF_;G;-JY3)Q&siCAovxEh`&axF50S)4 zuzqc)Gnl*}3PyzhR@EdXKno>uAhBn+@NVECPIinlaaeXe#y8 z)WmBDB`gVbr0V4dO7kx!o){VH-WhJnD7+Yx>pO^?Xp$sK8ONQ*37NqcRJe!C z*F5+j{#n`%&nm5iWtUik&GgQ^d$eCOAEA9UElWhhfy31yZvfuHRi=K@W6z0(TsWu?J>bzL%34S(YKQnlY>LN^o92Cm2NV_<7V~4Gs%7Kl+6Ya@4fm5Bs1-8&My#j`An;9h(Ap6qB3hX+ z*+zmS?my6)s>UAQvHFFn%VDL$#w1Y&9>3OL964BW9V&v4tg1akE`;$?Wis&(H+M8b z&CSaLiz@r{K3JgbVQr+7>tO!eEVCND1K?1mLL`TJc!m@D@7X2W_czTGq9a^_bB=53 zK?a!e7SK>NXMR_mjFz}S1ofgJTT|US$=2kShg<|9MSA|ik}x*cM;~uuqSzMMuQuN5 zZDK}0N`zxiw;tFy!X`%oFH3Stg7=7a#9jhg%9w`z6pk4mQPh9&5J&Xj9WJJqGl$-e zv+L{bGEK5k2X5AGc!b1DGT5_IuoZ*UOru|xD;N{|q^UZvt83#A1!L83hP=W?g*=QC zwXR2xm~so7oXnFxY40eR27~MDzm=`}8AWX9z&TRlc;E|TZj&MNU36OFJ;zkDYzUut z>tC9>KAuq@(@7B+4LPk;t$<}#;%@N&&dJaA-pn4kWJpegHyq~z;@G!2l*Ky27}<^Cqe6#<*xEcyjt6;{Tk*H5+_V?2$=7I;Cx2 zY`vTde(IwDl|4KQofbvJom-))sWkj1n^nx+;vR5ax~w0YCGI59fEFL5_8Yoeww(KX>Bf+|#rq zTKPFGCo)5$?1nFVRkyu{@rc>A-L8HjX93AW3rpq^A5)-%PAmAj>`CfCs;}AGtr645 zL0tKvmV;N7Yhwr0mu`2g_wk@Cs>`P8>07#w7+CbsB8ew$VLBL|)0MM=^^`5pQivBa z?n_mPgX$ck&(0#A+NyLiDp!bZ$P~+6l}q|AXRFap(>O0TauvFpOsP!EvdWZ5DNB^BS{vql+MY=~5LFW#(mZ;mHBZDZycwB(AR(*=4uv+1Vo=q!7tvkj5 zCaB+JYsYlFbV1hqOKV*Xno&}eJ@Ote+Kw7)eVL@J54kQMC^VU01c3k>_G@>{A6SmO z#N5u+=jCrc(w2>-y9kI{Fc5)(-iaAB&okIiKJsWQFHvLc;{d_!NPvJgsSA}2K|6S= zfb_C#GHKXfQW>Ty-GEMn^i@wN2*jEMXsQND*?BhzzIZ9v1(B+Lo7wjhS8|tKeM(U% z_Y$Iusctq>lAPsX7zO4~QljD^VnxG*Lq7&f#y`W7$dsuCC=RfSQs-XvbL@ZPv>>}u zE7gxLvg)0hrD=>6GqjvaRp)6k!ZwnkQD)0FKJI}l8J4Vj5DD;DH@Iy5=%7JD%ZVs9 z1*t$JE=HOjxGa@geqK8_rD*&pHs^Xzqs6|RPoWq#+QcZX6NN8oN+(kK<1rcOA%R<9 zVGTzo5%lY@8q=m4P`_2}ee-gHLiDxSvFtIwk~;DM_LVSxI1g?4^T4IRBL7AStY(s2 zk7}2hO`Q1X>kbBzaLFWL} zSiFe-ZlU`wQ*h=L_Y?`2NaurH_sv{$0P}dl<6g`sAK4>_oE>4kP*K-MR(IeEql^o~nJe@Nmzd`~(Mos>H7#Tl&DJBilTTtp z8my3>L`|!S^V@x0syq&yDh_ZsOj!ny!1E)ne8OAyr*1#jX#C_*@~-CO2U@1O$(_|9 z+$h0;Yy6lz-S*-mgij`Zyofn~?wB^w%(rM%O5metC+*FQND4n3D+ps4V|G*^_~8!_ zQv$Kk%&z-(IF~;#s#rg=jI86?YrlSQT3EdS+n$6wq#$)(4D8it-~JU+en^}S55N9 z?TAJpS^*}T;*$iX?B9ghYDQ2S=D>kHqI=t8F6I2=02UOg&zBe&z)Yr^-tdd~>o1*A zhiuInKkrY^#|F91b+SHW<>5S_;Qor{AAh$~B?A3fxy!ZY2bRohn7HFr*)%HwAa4Rt zuxCgb`DRZ1;RF6cL@x&-IOULvfoUb(lMB-M#{Y+s%GA0%UG@fh*K+jT->kv?3b;94 z3_s{G!QHs@ZZwr5ccZ5iU$XwyGh&5>9`)eS<$l2DS8*W_QPn~QJsdZs-r)PT68v(CSUqW=B)ot$2CDZh<8 zVx(j5{%n%?+r%yLYsqs~!BJMG{7RG9CJn;hzQ-&$U&A?=E6B2blzgEw?RB@T zUEt}rT9}bv%5jz4kin7mYEA2th5eFkrx?zS)Tr)N@!Y^`cSG&)T|Ftbq@RCgE+onr z>9&-qziXX!@v5lltskjxS>kQAnHzoQ!tUyapt~ID=?U$L@NdjuVb7U{=Ks?`zBf2_YPEM+;5JgdzMLLrlQ872E7l=rx0y(*F; z){C3dUfZcNObuaD_V~ySIw8=(93yNpc>_Dq`M%A2lsVknFBii+p{8cSfijutzVki7 z#xqhZC|fg;G+RiQdP2{2DFE<;P@O9J)Rxx8+ospW&XF*TU==F9Nf7+k_OR1r2OY?s zv?aL_8>&t_wwoJgFuK(sLrTg8$GVZ>m|d324czQrd`>x!#g9&hI_jRrt2a6V#2zGW zLdO2S)n>X97#|udM0J%fT!BB$L3#BpAonFAcyTuRb{Sv%)5_Y`oh;L3Q{8=KY{PR^ z1KLJHPESQkPC`o_jD(SxoRE^-p(!;P5x!M6=l0+WOaG@O=IQIZcW-Uv`rdb4_IzU9 zJfJ{j)fec$<7sIBfv5dfK&{n+r3(}v03iP{(*G9ppNN``(GlIOeiS9TMzYNZ-Ufa3vYNC`14+cPADjWb< z7_fW2qq++ZaDxW)1PJh}<-UpNn|2JrH88ek z<^@`^`LD<)7?%F-GSCVCpE*mTjZ=i%ArFTug)JjVt(;y8twPs zB?3b^^RE$vnM<^rNa<4 zCaf>TK_wQh(KoGzy@~v~on~7Rgvgwnlo6uL+*uIAl07VxJ@`h-K(;RX(sAKOS;XHl z<2-`)^Jt+B4=S9c@%rVRYtsf~eD;MRtizd2wg@;FY`R}5olgKr*72zgf0ILZY$f@{ z+%gK5f~N`UBvD(4j(3eSFW5xH4Ne^YXt+C0zRD1?jlNcEq0jmUM!p%VX05=nquMsa z&VV02>6LD>KLm7Ul$2EI)UJcg+mLOeskt-ycwB$;7fgKBBYQfSdIO{tiqo4p|EbR< zYkfr+V#iH^tJcPX7u|CcMzQXv9>s$?MBkg>qb%A+3{gZV5xMVPP?9?TIF{^`0dVk#DX zLIqK4RDN=rYGk{+P+DL&CDzkY)C8s8P(BrtsB)>{7?w8qh&ze2Hm|>6J&U)>-G`AU zov?pzjb5E&k}#mP6*5EzofHtf%^iAQsl#py@eX8_6x68tmpDnu05Q@;5e6&09-zH# zC+oceJjrx};K_=a`1LLh(q=!TnO}gJPty*#ua2&OT~Dxu5D;d#TTJUCfG0*~ckrrx zb%aOd8Kn1U89R432N@mj`mh~cN%$j-^7{rlc=$@zs7Do#w)Crik}PhRFLKYa23ru$ zG6@ah(ofK4uwuBSvg$})Pmh-OBeeyt>&e9>zFmkCP9&??bD27B+2eapFbPt|JV$AI zb{)3K95u9bJT$Rd%8jIg+8jXa3GRekzFfx$c2B6Kkzrdg#@FnY>~4(ZJ6+tlyyJ%m82!~P%msIXjKmUIJ z_ymfpxt5yVN(mr#eYovpIcboI+`HeSv5YzZ+y~cX;Vo5JaIyI zy`VQBV9$Q)se}X4u9;@$nsUs4IJNck5j$hJ2xt)>%2X9|>_Fqpl3_10Aw376MTHO>3F9r5#| zNz0m`J)3nJ=*zx2+O|0bs8r$Ta0+~ z0ZfhkObqmJMgGk_*KX$dX0xpwHC+lUc-4A}UieFBjn1c94Z20R70gD6wWsLXTU|Q$ zY==}gyleUZNBd1#Y7b+?7vv*J#5gy5(1~Av-6kzZM$9whP6VvV(NUCY9~Sf_o0qE( zim#9%@b^siGE&-7r{7rNJ!RKBIeUvZ89QYd$}@THYDF$(66W13%*1G`==nEWymB?p78B?zsWd?9eJpJ2 z;$j(!^u)BkubL!^XHV!c!9mF|bX;EKjkLtp6&C7M*PGQ>zsIFuj_J_JQfou~=_4fs zzAvU1l05B=aN(nf*(X{km9ZxaitUhr>6OD@K%pYU@y{l8+hVOoy}nsH@m;Trq=27Z z^W8xCWsD(N?y7TSs()n(4b<*z%9IQt$nH(=XdroStSn%KC)Jq}!SP};6UE(MC9r6Q z>_EPUqmp}3`$>ALWh0c~zP~JJ*cSp}?92})S7dsb4&R}=oDG=`r=>+!pEC2%iuAvs z^~cqG&17WGPHH4NfquzlW~R^kCLEDl&Z^@7+CYVDFyBUHVoi|_zah87iJ@J7vz=s2 zNK$NjwP*aCvMNqlFk})0wBL>#AZgy9U_j9zz*y>RK?)Ls0sp?ModrBim`0A4$x z)ZnxEV{*Z{s_RSWCjlznV;t%}&8yg1s3PiLX;ki0*kbSkNow1>zL#U2k_d=+GmgXh z(W4`z24XC=)woNPC~?1NChc4kE|-WlXbsFepG*^Q*w_=WwQ>x7C&9&S-W%)>aIbbEF&CW2r(~S=c9wcSc$_ZEJq1u- zF|iyXRRqvRf?tZ_B)i9!(v-etuPd$HTgHK#B(aorPq~vf)Mh=F8#zV2jW%SZf{?p^ zNp<>e29CfxTNhGL9{JTBvg;~|xm*F;s>O8j zlAwiVwcb);#BIU5pBvkQ9-2$5hBSeKWWw&k%1z%huYdcv7tOuIzIvZa?;V2ZANsN* zgJT^z^qDZzqOgG3qFq*Q9_hS*Ajedw#?DcdWqOS==+j|juQw@qV>S6atIvlTsY_PV+!Q>Xr;CPw%~^3zgwL**p{X*}et@ADo}paecwDWk^ajX~C3; z0Fh57GRjFmu1(Y|3tb17mbJAe493=<97hofQe3LL+tMh;yX!k6y}PsY&mxSFFKZ#_ z2ZIaWcTX4oKMckA%P>2f%{-yxSL=K#0+%fBo+785e=`!{i+!D{)_IvxAa49QG#o(B z&zdgu%6NsAu{S$kTeX>JrupAM)27?NHb}~#g^4Iu0@{dm}PmdvqbLGH`z*QD~ z&m_rf1_0kH*CS2SxM1Qha7dWY@d;aqT6F; zV{1;jzXo^zKRTTUZxV7pdb-1L<_V9n38kD9@%^8O^Dy$+OqNi`O%@kc-BY-(JO zo#O4LAA8wox-;Ya3+0h7_5@yWP}pk=@3PIAWPshimcZEye=2!+lau?V(ENm#4deQ? zI(5S&KI(*^)ftvBsBn|RBJ;r@Gjs-dfjgQ(7|H4*C}ur-ViFKkbSArFUz7*E;Iyi| zhWlZ+=3H8uZ9BwRrouXu)Jb>(c3bu_8>xMAiGZ~;qW*^ z3FEak6nS8gGB<02WysG(ZIhb$P$g{<-HV8TS3{-t~u0aGsqd%Td zVA4M<5Tq*oMjPv{C@A?*j-BNMlhF5^1a4~5w}khklV&wFTcexQ57$HtRhFm;!8@%f zdA&%d8dcuNuH5HLUGCdmiJD0;o7PeDZ=+=mT?VJl$*7Z|jE#G6-gMfi`>Dn~mPeG~ zWqQ>-O+>URxK<6hn>UyELDOxI+VTaG(lo6{EDoG}%C zG0^SNd{$)A)g>K2InL_u5Hh57=kk(K%XJ-IXGS%+W z6TigC+Ba|Bfq530Al7skpLslwr%EWdB`5-+mMRy1Q)4>Mtx15y=9S0h7xg+8PcDYT zMa(t2eJGE`ZKu39e$T$Au%or`%}S%ce3f)($*j;B_QD%`?aOr8w#|ZHIhi&1F2gQ8 zh+%-bS_kFAQ}6BxI#Ivyjt#T`5QC%JeGRnFu4p&+tW<9eIr|tDm!{4%D&vPtCqh_DqI|fvDpYs8lxymnQL}0 z%&u5(rrxplqrr=pk$X5e8j(TP|7?@rxUG>y_~UF9J$CGIh|6Ios(#K!HXk{x`NQO9 z6A7eUBw17mdHCzIp~1_B2RQ7U!m3f#7Zbu?f^!eCoun6BSn@6sZs>UcOa5`u?Gw}w z9fZO(&U?72E|Je3ZV$>|!uO?hwyGlYy?i{NsFPr1SQs7OVPIB08!D)^{Y*u)@bKMqjnSDIIxm@$i2jp0ZU3k0xiK7oUF{$ z%Sm+agT*fPe{rqPpjJKv>4LOQuU%+7Gks5wMGi`&+p$}i< zL4}mSZI!~KOa=V8Swo}O%=zk5EGN$hVH0Gi&AYl0LCU@i&PVt4tW;O>KVVzwd|BMa z!f2^J2Un}@v{&lwsx{p9y|aIHg?ycLvgLjVRpsQd;5(Jk(abuMiwpxY3sk}`nWHr& z?-{sc=?sO^vP>nzwz%?xu}-3v8W~lVcPSrbw^nkpFAQna5d~4E_n(!?7LKVOPC|t< zc#NJpv;(|5;x`bNi`2llJapf}xFoBvZ%&3Ri9kVuX_1B~EliWjHlGyy_UW=qd1^dl zH1@)ADIA@(Fs#08Ji`v?WKnC5y+H`fDp~@LUED43UJhZd+?(0)sKClvCkarf#- zkzRD87v-gd=01=a*e+cEWev`nR(dFT)kEB<2*;uc?P#Uk2q63+< z%V;EGjGSH!C4$1NyO{Q>bK}U+Glb;}_H6we4yP2SK91 zFhLW%7Vp!}K}S;DkCv=j?CYwj!HS9VP+H9}K@pEQP7?WO(Xi;}DEa0Tn#p?T7dksC z8IL>syG=s1?Q;|Z((o9MF6?$_!Bu&iLmDIknJS?G=;#Q}_6@yyZp>6vWRma(G}@)L zh7ekO!qCPYaVyXA2KqYWZV$v?`I0A1YOh!nRMdX_xz0?z;sG-pmhGBD?nxt3Vbd8TCAQv~5)-TLReA--fj6MdRl-8ym=E!fj z2*2yLoq~1me=V?t%{yYXTf+$!Y9v?nNZ?w^gncfaskya}I@*E5-y&AuDDj z`}~Qq1MT&Ew?F-LQzpwE^IU@L4^#(>y1Ad;Y%XnQ zaR8QjvcaflXE}DDZH<^`>eNoBjYY{r_Dlj9hcm1ICHau@M{NQ>U@F{`&MX_9tbTXF zLRDxA_)h*5k5*`sXN`md>YrY7)V{DZs3C3Ja^z)K7gDeLQ=BKi0y@Lze_k%$N|b5d2EE^TF(A z!={m+wzXmsL@7!(T)>}nJT5z+`D1gMbt_3ZBtedqYR$Xp-3P3ZXP6^aca~K?-_Ki` zwW;~Cf1t)DZ1Q-_wiX0pCcY#04+=#aB;?-15t=L41S)5aOnu)~rJ!{})L}Ht`zq|3 zJiAaDg&$eBO?wb(3v%D|$m z)tXZ-xpa(I<6hQyVEWfM`xNN0Hhs2jYxG+{DbL1T9wzr)eMqPl!94^yVjAD> zQU*$H;(~El?N=%#Dy{C+VaTRZ(b%3QFsb=iHF`Aue7oSbtoIu=s@Y`u)u1=C6o+?t z78hJY5J1I$e9G2N7x zwJb(lWo{$Sc}rt_kp}K2&M}&DyKwfFA@9J1i(6?Xs`e2h7hLgj5I4t z>t!sg(+;b4cfNMX%-XKr$rH$xiX8lr7KEnLiANNjrZ%!1y6eO4SVEBaoz1*pF$5b1>%R`zMxO5AxU}3 z*CK5s8q(e_;DKe>UfG!6+>vxFll}G}cV)1O>Gx;SlPSwzb$CT6T(Y$L$JK{ki`p`q z4c?_vgYvRe=&#mttdq`d=JrYOMUWjNKJXw*eh>2Qp=EYKEbx3(j)j;4PC6dj5x(gi z7lredVrYvj`1*yTwC=@OhtjwD^m>P!B&thZ>S)+j{@#Yv0wBzmcuy2v_Or#U1 z*Ntngd3*7U=vpfI4C(flpf+?HN-`{J<0Vop^-|RGEz&oijG8XSFZuEO&>WQ=yg$XR zar|IPKoquSlV1rn8#}lENp_5-Lr8^qrooAOkcysJ{f?(HD*wct+0e)|$<2vPMF-$WhC`@2LO<3ymZ zpr#g3yMX9H6`OpxG40eBqQanW)~{?aB-zZQgZRipnrmRaWV_w;pD)H+!Ko$u;M<7Osx zr$IwMh&n%3GrHO@{lzY*!LL@DIp?26pg&QmO;9UaNft3u>=!>E&@j-jcCgWou+bK9 zvEtCM6VbptxQS?JdG96mw*g$C zxf|KK{a;{gLUV@9cb|#o(a${ie`Trvr}TfU{sRc}i&s?c{}0Lugsp#Rw*up2DG;ql z0B7%5Td>$PdrLh`>T20@{xIXzjSq5e!RUMwg;-s58+%N~d!h8f z0C}rn!1Aa@=5LDlnw27H*Zni3HXT2$@U(`NK0RcT-@udYZYbCka_?bE@Q#jxuCvzo z^rN+Sh2dZOVj43@cG^nK5ZQTYFak1b&1v}KZmH|AHi3Qq{VKkxN91T@BB zoSFO_g&2w!8FeV{HrBpd>~t1$p{uU^;ywot<)R+lfIy4l%%sOTe1k z2rl*!1(r{aB8S-a!Hv-HKKch!gVn$;p^G`DnQ1?HVK5rwg*tGKLJqJ)ut*P=9nl8> z-M4JG<;p!-p!~m2^gl$u{}cgz9?pL|HAy#tX}Ql!<_|Ok1pfb~Gc|L!GBGnSx3YEp z#994^%9p4o-_M2>b_Mg%U$5akdqHLQ%FZvXQTbJE{Ab_ViYX-MpK8ZV%Qj_3@!>Z3&Ea^7er;eu$gRyKeRN z6!T_1@DG!nK$#HYxX(h#xH@Dp;#54DDlcaF1$rV1GiHVX`8rwbjb3~a76~oCb8G=> zEs>2qU3jBvG=+88gdq|XvQfIei_QD`6kmFN6&Bw=GN_U*>3log(L8BSdJI**q*LiKP{9UJRgaohq z8h7c^{M%C>*PNL`LOEma^n$0P{uRXk?}7UAIRMu7R{w2~J~#jWyfT#ksWEc4` z=Qa9oYMclz=;Cmp8=$MclnitrIVO`( z@vp!e-uew2ZU9B777kfR!%5Jjl4%>p12Ci^HXoUgY3k6aeD5nQ)+!}mprOgpy|A69CfcRUu-HNrLty|rG$ln{ndKZ<8iguGmONhXxow-i%W8peK*DT zrM60P-rA)x=?TXTFQBn+Vi>##QI=VKfcj>!^ zyV6!qrB%n$+ylr!#_HMq!Xpg$=K;saz_F;;36AL7j;4YyQ#fUCpDQhq)xMx;FlOtE zBa`SYuQg$gdxWDxC?#f$D{o0JJ913B49T=Duk*Gh4mGWyOUzzoO}lU=U#`M2l-Lnk zhTL(%*Y_iIe#Dq!6}IiLBUKE(;r<*%X`CGmvUYnU1%TRDeIiPW2@$}$$ze){#bjpt zk)o**x9JJ6pC>=$G6|=K0rPCL@186AdzJ0es8mGNCRtsYR4|C_G6;usuJ-)|bfP=5~!M7j>Ir$R-fX*0L$7m@bnN`SZ*kN+o zzSG7%3giqeT7@Xw|kOs+;2zaVQ{%D1}=w*z*?mVF4`tn z)a+buZ_)4r<*Tg^umSKroVhVG!@cKr;PA(!2~zyLXPVO}I>z80Q#x;QRAj=O$IFPb z4i-4PaD+6H0tomc$d}O*LW|x$YPzMo??I{6^QM$uT6spJl;UA?e}n`&=fynn-pu6|KLSIJb15Sw$>TM4g!69i z$GQ@v4LdMWy?eS9cPrAU?-V6^Lhmy<4YFGoRBrDugDmt~2m)y1d8U7WykhpN{ZjZ* z6(s`5M^PsmL$__YM+Av$JtF+c_qv<)6BmGcj zNwe~&)`SZJ=+u~j64$vDdmx&4*2skE!hsKaRq6CEmsxbr@q@-|TueL6etwQkSc$#zn1G5kQv zz*D;)F}?1&a4%?pr)Gq{MZ~nED)X#xX!j23B<|K|>Uoo1Nt6KKd1M^#Hu0yt622Oj=ABB51(0zsv zf`$(r5qoOep=%DIrJm9`;L9d+= z3188Klfu5R-l4fbVf8~GwFHQF_tP%x>Zhf%x0gFUR|o8%Ro!s*x>g2SUB(K1*tmc3 z4I0-tseTwXZC%+x<-K%UNbW<=%%6_5nX~a&@Ma|XXWQDRsm1gjXb1`$JbVi)mU3*5 zUo(4vJ8v-?cLwWEEPt)0oWC5R#R=E@`qj|x0aOoX5Gd5D`4!G8ehMBYNRO_qu5|3- z(7B`QSRJsA`%KB>>mE(o9^1Ns&ic@iF4#76gp_j)+i;m;xj*KYBFkLr`(b_Si&xsC zY#_bg!TSIPOGybQ#ygnp-{E_4QCeJGWJmd;P}W-PJ4N}zQ7W75`{2D`No|gdtQ@64 zNBOc-0tP-mp5aJM3A;3NI6r>UhA9ntM-0sN6Y*c*rE&&Fl-X~sqPnu<&+uRPK2?-% zY`2_Jn}Z{mcwSF6OKT`1Jae&C$h2pd@C2?d(^Fj67RTgzAd5C`gC3e2^6g2a502}f zVF57D-AEr-y`)CZ29N;>I|k4_i95>1Oa}NnABa!W*B{X!i|4KFcl`I(wtz4|Ih#u~fdM?v9vu?kLh z&#<+K54XBXq_NJfYT6b2&l58+{`N|!q^U01N8+WDH+hZV6^7F4g{6nsm1!CzzcW2> z+!ei0YFt`fP5mjt(r&Ppb5a1n$bHE)2{7FzxI8*NIqc7Jd%~Cc+%#h*%ymzmn=m(6 zXwdQt;A>~80kcgHr+e7qFRw+ojkK%j-TDSM!q;1FL%13q1c1o02ww{GfjDx@LEQN6 zSR&86hUZ&tvLlel=Ci46W}6C0+XDRB#&ScS58gJhOvQg?w&}m!WOith`WpnggdoB~ ztdgC?A{`33F$96@4J&#WDQM)e6qb0pU_Bw!_z;Xq@3KPsNbs)0ML)iT$Mki0G`-aS z%@bZwUqy)JW#f^1NH0;ke1$3a9*ylFLv;CPGj}l+%Dzto1dM zhdX$SeUIzE&$hF6M$WdQtz2HUn3SPYa^*F7d&QiJWOt&B3r78`RIogp17nJ!&#SQZH*?)*-NbOwY#O8yKHcBM0sp6UU6R!Ri&4uV5AC+Ax2(Nv+|H32J$vo|^hG)_i>fUU6P*B|X zbuyNxqGZW63|=IOKSou+4LMle9IuhL%#H+L5Q5hFYMVNRh0@R0((m@$?b?Q?hnq~O z)$~v|@F+~l-~1TbA16lW=tpnt#r_dNo!1mmNsssMbEtiZEprqT0dK{Wem~6TzNI?d zzrrh6Ipfs6x3m!Wt|B30OEE?#RQ)$JGN1@uVmaYO9{ueeW6rTuZK{*fs6 zo-^U??TEKfE=Gj=RGIrlw8l!;LgGYKE?rm-tfPbUz00Nh6ne>#{`56iBa*P&(?~Cn z{q)puCvqrC^n5ZF&T;wAsR!i=s2RbwG;nuGL{-1i7|2?jM}D<4N9}FV4m?3FM%2n%tH5i*BccB$t42| zpG%sZ)IGV>rKEfGx2&Lm{pNgB6WUtj%&(6!wH7*%o&M|E@gE-)wfVPg5A=7$v5Im^ zKNQ$UObVy*1YjQ@?A|9?12zZ=o^KBgj(WGII-XdeKLAVJ+r8D5JKfN&En(HIXq_K8 zCai6t%W4knkG!fL!TL4K+8aVp?3^)Pq<_xrF$U0-7jxQ(>@K2fYU5W4f2;cNB>T*# ze$5xy@+% zFC~YPA2%Ymmsr88xGOUhYiS_P-|&m6NzGSIHnq~rVZCK^+7p>?|IB2^dXk049OgZq z%1gAPHv-spBOkHc8iQNbW_@HRB>KDDYN7gV55A8s=pd=5QUK`z|4I>bLaJ$^8k=n@ zL=4Mx9k>PeuMY^KyxP5_nmqer{&e0LP?951)4HcqOXT0m>O;QUP)QX0&Yawe-ugbQ zQ_auv#~3Gzw2kVIXRZ38nTqRPxO3j5h#CN6&_u)l#+&5$HdfLJ?M?*u6ixf#lb|64 zH;+93Zc*3o;{(7R+!J|%7D81Iz&;P;hMe5(t06oO%z>~TzB)3%90ZFr0)pS!E+7T+ zF3$?mu)@D1e(&IgJ{Fvj%L}*v zV+?UTC^{2M>Q$QsGRNL^-x{4%O5n-axd`x#T)sh-P+1jk<+4(`z3VvI&B>Ur3h*97 zO+Zl+N>aFIxQ2X5e6+WlKSux1oJN*rJm!kc4+jk_sj-f}h$Kgm+_)h1pFq7W8#dx- zH0;7%alH{A%lfQPJmZH@g2tBH>T^TcrWEs91CsO;hyc1*VQ1mPk)-$Mq|v#wf?G;{ z5^vGyTTU}N4^F1Ks&9_nW>IIJ??ZkVLN!cjrBlj7Bmw7e)1XT_|7$k^-7TbtIu$OI z+siLq240_TByB7gE0r-b)2J4LiLbUL3ArYDS7F`>-2H+WvVb4Ak!RJr6}r=VFN3^^ zhCOzn{7g}Sm`|NVOGZ!2VB_w|JPk-UUqR!|1nhuL(JP|kZayWy?yugzriWsmh-WI# z(>1&Py}^M`&-V6ozn+aez#snz(%*}&e_)$}I5z9+_`ydrb>E-P=|97ILb%3CLM`}F zH_j2eapbmA?04VeOZh5TT~^jqSN44O(zfwQP`+^Q{I69{o77YDoZq=?z?-E0q`};^ z5%P5WJl zQwY{TbZ0CmL3K?vc#_%E8W|ZScMIk=LD$5-o_r1e>pbYgeh@*_Jx=HBVX=eQ|H?gg zGT!EHvHGiLw|%CXqu0-o$Hjtz3}2u8er*$0x`xFnCZ@V0+_h?M@@ebIX;%8sQc{!A zv98@>_80d~!c!!emY{z@1k&~2&qo;R2yCjv@(meTFrvJI>KclA^_j4=?rv?}9jik$ zv|eU34m978bBeznyk@@#vXW`4)C?0k?k{?`9BH?9u0M8e!z=G*1#Lw*UkC`jXS;DA zKkqYAaWM=*E%~Cf24atDbqfSKL&p$bFC8TdBPE?VYFqn?W%utkfuwk$euZ5%2nZUg z?cKI91x?eQCwb$Z>T(~?B5If#`~;HjoX;CwOs`$P2HIrQK+pE@{A%Gvjs^H&PN&Vf zMgEiK+zRORH-NVH^b3^sU~MivBPyOfw;HEm|L)U)qS_JuJu2Sf{N&Y?%Gp|Z>4#ja z71XDbDud{4hUCQwzoZqH>fVyS&>#U-?Jv3al8SQ3=An-)L6gU@YJP-NzB z7B0<4-p{I#1d+sAg6BTaRY0%0Ttda{Gcj9dN2BD>7V5Y zXI%GYR7W|hvA$b>Cg!fRB9@j_fIt!Fw^b0ro^`qdY3auvfzJU5Pr+KKTF8zzB5HMR z+U!hG-K0>?KnLi6p8g1Mp4YEspP3@Xb}yk$9aSd;wtRg2A5I(p`}7*x|C(MiGcx|P z0^s@Y6Ko`j5!ivW5D-=75D=vQ7ybV^#pZ|Tt3LSf(GHT~jvK!HDkaelSpXkbC+qoT zkU*>f9*>HQ;sRBXyOYqJ+H`3{F$%|2^bMOi-mpGwSXs4_Sz9}J5C==4sp+z#dBvOeK_4^DvQs>oMzWl@@GxX9xsBg+@Der zD~jG9za>OZBL)&-?UrU85#m>&$Xp@HWJ1VzZa}sJ>xpve#nWD! zUC^mcbO&OfH)VY#$4X+4NBm2IK|aIXI%`(o--8w}l;{Acq(unSBNxm25WG)4OD#bo zCo_Q7WR7<6juQqFN??SzCm*GXNp>OAI@T0$Q(&+SANjMz=bbtBR1#O!)Vkjy(VIUVyFjjKQr)fZQQq`rEhxVbiqcvD@|P_H(QFW^D=V z1IXe2L-i1K#nxdv80;ao8QyR+(d&B@g?tL4ybsVg+=`!RB|6ihUJ1Uvi#`bR4IbCE zcT>5Xh{9L5W#**evqRdlax}{%ZeJApi9;V*MIB~*CT^Z_>AD*AGZ-50M~!OuFNHza z#L+(fj6YhjCoDGUeNIRBFZ)dO0#(#C6za(hmu1b^?Idix6IEP=%kBZ?T18n#bnF?C z$T6LN^cIW5U=A@7f0-|*q@-v@!ww@g_M0(_O_^r$QL>tB-V0b97Bm-)bl}|*f0NfW zmyYkVoZ_7RmN`*1sHJ_*!Fx%kXYIax$tjQxt5f$AZAs732x*GXy|Lf0X_ZZCj8g#7 z?2lP;l2KDS+67kg7=s5N(og9cyZXe#%xsp%%??-oz(WCB1&z$nj^z|9oG8PPbr^HF z0Sg@5{-P)&|DHZux~4-`E>!rp3VoX8p&~RJY>bP@&4^JmiAZYyj#rWGg&zb>z!iQ$(j5#Uq3(=(a3MsrQ)cK zYmzMcXy_J{@M2p#;jxM?L*<8yNOU_%W0Y`*n5}duZfjnzyKfco!rW}X>mj7Tmw-&m4;G#S}w+1@WWuqW7BI|c=#o2CTPC@+jMSj{DaY_ zJH;+kzEE>}M`bm|}b zQq%1Y<2^Md;}0`8Se+p~;yhb2zl@}uXG{Jaa1Xd8(GB^lg`k{;)d72>`V2hYNnP=%LY26J{Y|ZzL9T-x9xt9 zns=vs_@MVm=4ueU8`OcMr`lYAg{lD}kv<~F9VAi<7UE8R*UH(LER}zOZ}4vMrx_dL zkx#2;cVDoukt1LDbb1usT{SYusUp>({gtb@PEnalG2ZCL6Zz_|LNydd4sK#ULC{p1 z&AxgG_gfDb$xTIh(?YNF>K)b;BE-G3ATf;kj=1+bsd+kewY*brV#z!|d0b#|hi< z97O7Wxj^bq*G1}&7{?!i(i~zVnw?}La^mX$%5Q@g_N~SYPf352jm8|h|EuPYPgN^h zl%&C@;*l?`{<@VtDzGWr=u0?3SiPnPN0eb>q!Ck$5K@2s8Qu`pr3v0IGeG}W^DDNf zz(XTE#9OlduUW`QCclWy@%sLavjr`{hoO&T;DseNu}6vQnc$(gr5Js|0ra0+a3Pu0 zS9V22Gh8hW$z1W*4n29B%!w&1ZY>h4k!t!>jRH&AuYu9q_ZY)X+Hs!ITYaq_(Uhl=Taeiczm|V0lL6(pL*hZD*$abKk7|lRaMzy} zZj9=?6nD2~rcT289-F_jO8fPyv6RzRDl~QvvyL;NcNEn@21m@W(XEx0jJSTjjhLAx z)(kO&p5~;C9u9W<2o&U z#wPaUdS0Kodb$#`aNf0B+f~LjI2pc6!(c~Obp4T1^p-Svoj)yHP>J>IxBo$cT3c!9 z%7_@FYTc50GY$<1GZAbhz58))CuacRS10Vp7cr@QTokH=Bj6f@qE2>N6sVN{SWPQF zd-YQ`mq?a0Xu>E#n1M#%*Qovhvb;Kp2O~lZhaVRtvD$3-0V6 zeSWqTgc-IK1>BI4Mah}S6U-U2XOBF2PgcDl5nPgvWfw`kf8oX`=_paOmMemkT}XHU z(g&D@;RUa=F6(NzJHe;6Kg2vuZqej)F8jhmr!1~+$fZI2&&am$z~|kBkwW4JJMk8T zhp4A=dC^T|4_L48`(0vhn9Xpru1eD`)KSmclpBasid2l)BJR0!?Q0)mhZSpj>{ulzC z=aD%SMzwle@-#jP;$K1Phqn;wV z9L%r2;ye7r&94>~{$3Gj3cjm|b?JVl_r4p)e5voj6$pMiw|U}D-m_JOz=Oeq@Wf?5 z#O@7-fZmo8q3R88++yifhLq}645aH7)qQ`2Ac4h##DEBP?dz8KoxUud6i2!&zT9(* zGW2~LXV2VF*{f77D$_Q=(CHgyi>VL7ns^8=?y_{z^XM+kn)u&NlhU@-^NaKL)TT-F zkIZ}&Ctc`l&KWDC96Ug}uiNHgqVi)MLh4=3xO2Cv+?GxlqlKKorUVd2qc&gYF ziSl&)#a048{6&!xl$#DbjsU**vnvDa>@ELk&Dj-~>Fb@_oNvNy7IjXzSR!yEp<7@1 zL$GXx@PmZqeWHara_fh`ZKcE#d#hNdq&~2Ue4xp4-!Tf90>9OilD4h;4U?vURubM^ z!{y>g&6LBzN7<&rWUZ30Q)tslo&$uu@`CAl$DszqwYs)ghyHXwIKP2Q9&RB?FR>Vh z{J<|V&nSnVzwLJ_5X4ds4H002tVS_lA=eIYd5#3RU830pnB(B*n7%omv5OK5yhSj(dY3FSpAL=158$ ztYSNTRw!{B4El-nG8u;sZccOvb)=+-a|;y#HF8_t&Un?rDbd30|8n>hcD>+EHMPbM zU1;KA>Nj|3>%G2shBSg~2();QNtWO1{-CClJPcyT@ng7NfPmT!l0 z^-3Gl%PbC&iW?@#iO~;erd3lX0!sw;Hia0@Vs~s))=n{Llk)}^InaCa_V()ILo5Ao zuQo3IDGfI^Y*zxT7Qv^d<5R4axUb?;q-%M?T^fD??`$IGg$T!W)R|>Uq`DdtQs+}0 zHKgFCcArex;H!_~E36MfUs^&A=lj0p@m<~G%xvZ&7kby9x7fq#+U$=QKYo?+N)@vW zm4>ianDz7-YtbD$oGpIPiw3xfd_dJJQO`AY0`^!>;DvRO<{FJ_552D$Mo!C*!W{BT z!=$4UPP`{Q%Ffae^{P8LJ{2e@4LVP^DexelOH+vM0doeC!mH(Hy`h<2lRL1s#yP}z$W1)a1;E^ z)Z{87LFW?uqRd&UhH#>uRrI|+;xDcOFoBJP|4$II>-Rn-6MK;V;e9eIu#*o=@5%M{ zTgEEi$tc&c5DuqI>geSMWj{r7HDkLd%;P!m)0us9PDv#`N9ba#jL`b2$wg(L@pVRb z!P4wZ`+z8yLU$*7Z}0Dq!f>pvol<_EmMiQ7`H0DPy5#qhtms$ThlBL^S3Y3^8JwB~ zrV6=T?Bo|_hqXDsie!%yRMU39rdyTVg!zm0KqG(WqgG1<3KRx|{Ri~=RDPDG2`eq} z7iPY&f#9*|428jm&wt?~N)Lk2^1YL&C9oCdOHxNxE>l3*jkO~HMc+l6b2PTQN{6#M z6n0MYw)^bx0ZYCxog|eXrPJC1;Ld)%_ zJTXW|Gj=Oy;)b3rUj++Wxo4{*d5yD&4(7+0*QK?JJqFji_;^PmfdSo(Dxt?O-?(9` zxqmvFc!RIHr_W~Nw~1@3Hf=K@e8@(E=RDVQG*hLj)6HO_+>8BROh<6GMD&q=JqbG3 zzbzl_kyNCPyEL<11VG8AS_ZrocuRFx`vG?k5G$vsSTk@-;P-r0biE_RGSR;|+uB2? zR*@jvm|lCM+~R)i#xE_WHF5wo1uK}aq|B8|&+!GNr1Eow*3)JoH8~cpDXS9Qz%}fq z*{?%PEP*3=w-6*XfA2zNk6Npgl?x>aU*&Y7GmkM?`z0L{9krcN&BYN`>qy`sHd2?$ zJM5^wyK+RuUNcmjiuIpr0cGwf`%+X!th711tSMWq>dY=3C96Bk9WW(d9`#R`|0y)T z>#$Q_H?R0FZ2sW#VVZqK6G~<4O?=A;ij^Z;xgNC778V5{P+D2WJWgGg%Mg?PoQ_so zlBTX8bS(qSR^7)a>I4)3jk~%i4!)y(e3F1Zlw&-HH7cVbcuL zNI-Dk#PxbO$LQ_cgjxC(cVfh9Yk68T3TNYe_n|y7sYq**&To4{rKSu10;uh{v;B@9 zd;AIw#1191j+i6Dp4DvQh^676e$2^!?^AyL4K&ty@ueGuCAO=4bAsxio~oXX*cO+m zDF(u4)+RUj)fCaS@C=PDg{F7y0)f1v@m|F6$POBAgFo8EK%pa8Kk7xc)a@I!18M)L zV&|Z64BLmKB#l~6cIC7aPfPYj{qAgg(;fvU_RU|oV!o?5it~oC1q_nPh3#k9XQN{E zr(=Rbc5UcvkQ*)^7=ZQey^&yQUim^^*u&W=uL`5FL-oEmHV}Z@qFzjzjp=0Xr{YCpKC}^- zKKh7?Y~c?MFM$NoZtBEU#p23Q_l}C$uh}1%6D;lIGyL#TYBMkNo_j3$E>`w0c0t3; z#;`W-Sv054vxdZJxN`sM5tVqBOp6tYW5)#Wba8Rc>r0S;2;0Sm@J(Jg*`SXnw@ME2 z8CkNr5`M|$)rv3ke%4zQn4z3!U`kDBq@pI_Uaz5))%s`vz>_Dm|ytp z6yaVaf0`{H6}2OaSn##zIQjZ-h3)v);_zLu?$Z@()>s)SCwzIlA6-4Hxq;_MjESi% zBl^_)>^L#98Z!UNe=gPrjm9o&oKVhw%M;~TJVfdq1{B0B`80Nd-UVk;8$&iqN6i=e zGa4s4SaHBeI5X5`)>piZMcd#zJ$KZ@;7N1~uk#+R6tYL(=RqF>jc{+GMSxU3>=-VVDt<6&es~7)gnmeg{iC+nZxfsDGoi% zotm#ZHJV#86~ad?kxu%yY8U1w8=ZsrwfCKTlPKK5X^LBs2F^E23wJmyKbtOLn^fOU zUW5G+EyB5$PXpA_vNaJ;jp4Mh(~T9%#twT;0&}M9fCiPZq>??&KIvIomo@jb`vWfY zjW-n;GTo)=1&j}r_i#*1IO^sun$h%i9Cl<|q(H1kRr4)-18u#+f2flYXcW?3=D#H^ zRDRy#sGyQKMf$LxbwEw9zdZV-w**)I+3F*os=EaM=PwVR7w|$G7*_sLM9Hm|3kdvE z8Z0$-2#nFIb*{G$h)EfY7?uw4`XmFFN6T%WmY%?RQ(`9N{QhDFmdIYsEK&3B$NaQX z?!d^56!Mv7tVq?Ie>Uwo_vO%uA{f`2A3>0a4p*wb-%-mZu2fRFNThEYM50&~3^`s3 zOv{%5kh0IXbW%Mj777Vqyf-57LLDG&UxzR^pS)`d(>?rq`}HAa-9g3$t@=NV<}kk|CLl+(^)fg$oAtX-C%>R-c_BpO1iiI&2;^NAV zO(QKP^Ag6O*l==i#1QJqBg}KG+)NvSk4}-o+4C!M!eZsGdf-1;*|XvNhtK6gFN5gW zLaBOnz}ey|buvG~X@-?iFLe6hQDlwp z4@OXO$>fgy_b$zx@|J=AfQW$B^upkG=kpSQwHQv9LO!9r#zw_?pv;p2S#=Y^ z82q0?=>8L3;dDEbE^UB;aM+-Y2eiw4Lmk$cniB0R?MA*Dr zv!onslpzZC9CYVhci@h0w1uKoGiy6lD8Olm{!{&zf$4wB)@2((*u^pjc`e+ z6X4N?p$05*;&NuubS$old&=>#yy>mp&oPyRFC(mHJ?QOHjv4sI!qWCRRV^C7<-?pU$C7et|d*uTmK= z7L=!Fd>beIkG)Xosnk$rOMEeaTWB;G@hs=6&&M$hUsw0*C46UEE`IE7X1`zYqgqZr$ZB9lLo4KhEm725wTLg0oR(rCrm6i%sTb z6zAn~)daGOQ94AjHRI%1LJ)&>q@04=Em^{JBI}nM146q4OyAPNlrx)zbF7bJ?`c;R zeaccci-7<9y)!opz4>K6@?uZE65aFqNlng6m7XAFQv&=XQ|WqNc%X*;#I$LOiW}ys z<+B^+$>pz7i`})f$%?4OI@D8e#{W?_+zV@2Cl}*rb!evGjH)&=agC}LGBGC=!+y%- z@61lR{cerDW0~}*D4BNY~xmaYkd)i&=&au3U>_r9*EEj$@1%+VjF53X`3?-c?Rhj$&qLqh6vIZ z=^1XDY#TZd?wVwqxEJ!#;R7-N`W(6oz6`nxWf|HNyAJW1wpXclJdmK56k-jMwc&l{ z$fI`+Vj4OJ#ummF()P<6#xJq$8zd@p3M2_s67(1ZOCYo% zToMFRAVnbj_pdT0AHgxLua-+A7LG^Wuus(%1cRMF%yg8`(H*_qvvW>cxTRhey@jqk z+(yR*I=xe#3cEUbY+yhEJ*R<+2nFk?9X~Y#pP(B(*quK%n}fRH<{o2fuvs33MZ}l> zIB#Qq9xI~osrC-6@YgN^&)H!;#zhDoh+4A)<&K}~P(Fb?5Edkt+A1(zh@Oayq$k=c zlViQp^-nx8zh9dmfkj*Ak3N#G=+c9?gM}2i%)wB4!LX0|+LbNRrz67fh-tR8)F-AXgDUl~}7Hfm=7Dcbu-zah? zz8U+4sV~YOgirsza}!}86{egjJVdPDybskhcnj4G(5#r|W1MnW({l2!oQ}Bj+07~| zy~-*(`h8cBQ*&1!%ylFwr04I{B>*k}pUA6BH7PlDX=S!2b8+Q1&@xzt#Tj^{zv+nS zD*^OI0JqI22b_LqTOG#l&i4f<4)>$uCqPC056)ZQT{}#>*yaW;Yiat_Ef=%~oK=%X z5&9jv#)N^A{Z`i^xc0>obbnE)yya`~uCWM^&#OHV-&)F96@KA0dGf&?-*rt?9N)cO zqJQHW#GmyYKm;jpjI`WrS+K1jG0}>pvogLzpRZyf9*l z>O;z=`u!_tUG8BGz5hnA0*x$`6fd+qTiA0XjvkSsl6yg5|k$QhMv=n;M{nLOll0{0&hpH3_;7cvaT4 zZDeNQR;FWW#>qsmtASSvcM1~qm9Z0xu#zq4*R|#5os5XV+W6waR|18}|4XP}O<$Ot zJ_4M)Bsa~7g`3KZ%^P8i+2~wiF`>Y*deMy)p}ZX(mXN92CGN{x@}!1Re2v|?ap;(? zNTy{Q`o!mHQr~xSeuof3wPOFPf!>tCO;aA{PK-W1oRL4BQdhbZ*6{n_R z*TNvckdc}DMk#f2N@oJ)&a)*P@CL*GwQI!} z-R5MrmewvS@gY}B)pSn4Rvu=$V~$CIJ|xn1|L&qLxuc5OJZS3BdBTbvfo9W;j*0t@ zrV&v{#Z=ASHJ5&q;77Qp}lhD3YrY zq?Z&#a1|1(D#lp{sbdypkS%;Er;*_jt$n;9{@>&Ol5iQmU8WbFS9yK)^u3%w z^8d9GKX8_im;l_Ui~{)n_t%Hl)+%1XZJMFi46}qd#BAVf;FsPnk5{~qT7hejI*>rP zH}pC}M+7zxg4vC^f!6+icDp*dI7;3itFq^zB{KLX@xj(5L8_kO!A;!GnFTWw&T~CZ zQraHIq0J2AS_LcdL5~6JU(3#tKT8GU>}`WVQ20=2wHa$<9n z5(?%N6?PDvgm`YwjWhV2oUK>YO`t&ZGNZ;lNIZJ(MvC(Ps1&2GXPMzv!% zLsgbV)w4uz1~W;-y^}pzL}3%bwYBYtM-t*W|FxT#TNJlnwG!RfmZd%-0U=w-7_+|V zNF;3#qqEsm42dPRUt9B(Ljd^hZCoGR-8`~rv+W_IKDzn?gM_}&CmhpA0pLoHp)56Q zj0vqz{FaT4)TlYQNu@65%4E)7mMrv&_nZuKZuj?2RnVwDst=y!`Op$_OoZ78Tpu=dJ^1(D%v8?0!5=@> z^T+#rD(1KTt6jn~yGltqh3&EQ z*1CZqRCpISI>!sLsJZ^x=mOc#JXf6;=@kyrF!y8B~3r z(EvR9G2NKCGA-I5XacuwG9Uxq)yLrc^@ooC@}7zg2ZC!LUkJ;@kqbT^Qr4))n&3{| z!g3q}oH>{RD(Am+(EWdveFaohTl+qZgn%I3El4*A454%=h#)B--Q5h`DJ3D@Azca% zNH@|cAl+TVF#Lzl>%HoC@BRP2%{prjYu@L1pS{o7vG(k<-}mhE|F+rh_QmMiw_{xe z`2OoHTKC0THtlWJ;8tzmTN$jzVA%1w2f_)a@Km(=_uoh6%|~;{iMRG2)vqFm^qQ8y z7e!5kU&^*POF##uiIeX}V&C!#` z<1m39yA)i29O$5qX*n~SGv}i2NNlAyk5xk@2bGH_<9OU_^~_#69-x5q`wtBja7VNj1R@U?j-Td4CE0M|si1q|vlyRS$1`J?ao969XO ztCRCN{6vdZ?`o-=V-z(#@?_*^4y04nyxf*UcMWqz_H%$Z+T|tSN|Dkfu)FwPIv$%I z26Vy~DBsY8uw{`>+BxY1t@_voC6~G~37&O8jbE_UBLbp=b2c;dB)pukakx5HDY+yi zSEXT5mN1u-B;5MmEqS7D1w-*0gc1GmcWx+>Lg)9U=%$cg&aK4C4)hw~w{M%-uAtDZ zSRlIvZj>MLWcJ6fMJpe;rxS`}cKa=pItO2oI>VNg-yDgF*~1P^wr%NV_4bYLOMlS{ zs`Dh*u6@OcLze_8T_ikQ<0?N<2=9i&_Zy;iN4{CsogSr|dYqw3g|DI-KD3Mj!Ozw^ zYgp`MDl0A2s>}D>?Ir0xZ4{2o>;#Q4hI=P1;ymo&%~ows6AM=-fJE2wgnFBm5#70? za>1rXi2Is@_vtJP7&%xPVL>L3$aI*fZf+7?NzHEyuG;*PVVd0)!mDEFQ;LUJrLk(p zj7qZ&!JT0i6p2*Hlksx#(M{bzJx$PM=b?WwMaPHyIGN|sM98p=D6Z+5hi6qd(rZxL zt~AO`H*=O+#iLvXkLp=N8>E{j!6H=MGE~!&B8ET(>v6M7S$yo%krlbkla1HR!)MUf zy_-*Zb9=iYQe`Ky@eKLZ+Hy&$oOhJ+Qwjw#6u#IQ8mI*FE}L+z(sa(`qHjgZf84nL z8h))ZNDOYB3xrwksg!n(P&Hcl3O)lVRlvpl5MhMn^8_9965`?28hRVV2$cFLoaioH z+nd_0)SmpZQPJi$0}c}^W0I%LsUJ2Si18Fgk@DRUqG|2fLHwvChdD?m-S}ppp*+F{x zaAJHx1afGRdSy*lpY8@Ue|oSm(d@lc5Ovc4+l}6FbdLIN8yJ5w7PQ$ojR6Gj9z}0I zQU{tWVT%f1Uu8h$6Cfu;dB@EY?`IY!5=FtErzl6Ek8Z~2%fA9Apas}Nz}l6Z@@8kE zUAK_gf*GNAv!WTZr3~EX_f$_v5)RIMr17*0r1E$&$*8o&T9?yWXy3lS%*U-;`+VkS zgx(l=F75c4*NP7$m1<&oWUJ$b3Q}4lyShWsRxyLcsF4@|M#no_@((yoPKgluz-iRk zP_9{U%{})SRPTLmBfI&GZ_(>yvfrpH;=Z{gNs`?_By@il9=cdDm z-C4BQG{Hev^!BDcwB1>~6f48x(y@}Xl+svtT@eJIyP^v^wwtZI8YW&D&ICTjdgnwS zNHiZzhQJa+=Jy&$&=HDbzY(Cnf@7M~&04`HF^H&miF_7PHQDZ^dS(#6R2+Mfp+>da z@xs>7`G$$v(4z6s7>J!v=`w#Y3iRnEGP1_#oqygb&mUwABuwDsn!mvP0!rw8yQ&*t z&z(Ri)rh%z_qkNzN0L<`=4H}%q=XIEM$bF5_f8+It6r8ouo0Veh#5zqa(hjxf z?hWYGsP(|>mDJ1D_CI>D1xR?7;DLIY(YyV0FB_^#toG4G^`;0y*E>H3jG3&vo8mW> zqTF;b7`!NFLYgvRU4x?MKUbHN&-it7Bwwbeqyz}JHP$@?)(rv+F_*0+xv$Wz-Y=0) zUAS{;Ql&7R2 zx$qnr@A>>;I48$YBs&IaD68uw28#vsybfUWq9$5*+Xiq7d(BZ#4>W&3I%LzEI6!yo zF^i)5XqFl9EIzVFPCjVl&HI|S35jFiNLi=4SJFw;~rIEvHk^8&t4X zA+(L;`cz!D1SlhY!#P8S^`4SCb~FfR$3@}aV&2iFuHK)<>{e^ch>V_n|Do4HqbS*OOH>myGVoSJbttoq~oZ>BhShOKe&Q}6ULq0Lfx$Cm6 zc&q*1jA00QesXYeLA;em{pwcB%`o$XBtD|qa<95+pK>S*KuzoGdp*&YTHfZb-Qwyz zbG$EItWA4UY5J5$6Ky8g7o2IuZ?p_AfUrz2Wa%an=^DrsbTf%}ax=>b0i|c&d^ETK ziiqDVge(CIA!%=+!3U%!Q+~ipZPu8>GIPZH8yHJ*0-`+ZE$uw57x4rKhshKW<%rLA z%MKmuhn*%Sv+$wSlzAbjNw@hLVYIggeyBYS)A&~x|{ zkO-YYI%#X-5wO8w+)vIIIFd1bI!zILuoRwSH&;cmQ%Q z5HD*)*GzHMcnrCuyu(95aah1@On?+<>eT(BgjFCxtI*3)l^O((L4y)tpAxewZDh9^hjjXGXfG(YV!>~KB0=Hzs~% z9_=+E(6ULW^n90>@6sE#YB7-=m!o`~^?u0``V z){JDImTJ`49xPTnvWcFC^Oa5s-BfeJhp6UK%jZvfVX zQIpr-+UjKxiVGu4@AFEnZ(E{TP*KMlS0@;cew<8k+|aB$*)APaRAI<#TyPxA3ETHnyB&daiaePGegZ zYx{vN(*gxRwp_8*I3|S1PcBl2h*uxaFK`Kif{6H1F_Vj=ma!0LY1`*hSVF{wZ6td~ z71-%nQ)8>_J$m~(>sE4&;c$c6bnu96hqjjZg6woN@qA{pgO7vlT)n%{4UYy_4jW#p zav{@T4GkFG?JO_H-bI|_b{8-q3SQq)!t6Xp9NK-kq|dUwMAFv4c(_Bps5{wK8*DcV z$M4Dc>Fc#mN#lJ=7ZO_=-7uR4qQy?!mY4b|nl6H(?@?^8*t?<$iETTxLbv^mSXyO| zWn0iR=Zl8h1Wu4f7x|f5lmA_jN>8cL;j`h zEU?nlg#K0ZXZbB$);f~i_(E<+LOc!=fTF@VTZ{FT!ZYVheGqZzF8t1eSD=DmFQ#5# zi+eEM3FQu-UgSQ&;35313ooZfD(wAVI?f%6mUI~$53&lQ$@@kM*dEllk1(fBzFeFd zlxnJEdJQr6q6j<28W+pS>+m{!u$+6G__cZ^OX49#L1s@(a?{G9)00+Lfx8!@VcD2B zPo62Yid-5#Ax0L(oU=z<5q(mG67})nK+CAU(p)6h0Y$w29!56ioN)ewj*7P$ND!)n zyARsF*`W5eU}s`FOc2NW#<7b9HPWG8h%Y*|lnHeDVk7ROc;D~bKwIIkmhvT~9<2U^ zl~>3PG|DdG~B_HnY5JF~bRoKQfDAF*R25Y9CPv8atvuq{KA-0-^2JMi#qmk9LQBv(^+J7gS8GWjx;WV z-r%ZdRclz<3Wm#(Xk&zjrv>H>q69x39)7CPU}`68<_*mbM9w>ARI8tyoq5eZ*oULdW#OTW!k*Jbd|f zQ6?Lt^yQ-n+fuMdLe?$hG1pbYV)kBdSk{X3-O{p^*Um}2SR3!MQj{Oxi;i0n$~Z<& zw=mE?!%NvFK(Kc1(BhV;ctrc;!3trs2K-0UGe3rxb4VcXPzs`c{CVdjJyYB^b?17# z-bP{3Xq|(r!1Y3SiMTF!CwZ=Gef&yv5(IcZ#hLq?C}3!a`7#}D6hN3Tcv<6G%CMdR z5PB>~GKYppTY^%MZuD@)i3Y2SU&Te`LJMz2;On7Q;OnS1yXfbcg8cX-hHB;U8!GjmyFE zBTDcw-y0`qI;_!$WWm>yCPuH7(U&hwBu{ogzE{sKsdCH}K}ArghX1JdEMBBXct!P_ z4a(~v#-t3|vBelH2TB}i5O1&10x>bK0E3>}w9M_VRJ|U>ttMQ8x2O8MKy7MLpUr-`F*6y7|&6 zQ053pUY3Dx{v{0G?OBL_EZpev@%-1?%>+{{-5wqsT!joA9LcYyzb)VFYTtFdua@{8 zB1UrOU62n-t857xijl;65=Ulk9Ey;&G)-uCl)yVV7pD=Wf=8n|p_vW-0d`Dr9IZ|+ zU-Zu_qW0|8D;{mw8S6N%Bl%`#e;)M9Y-46dB=?rQ=sTG7uo?H5FE9Qmt4TbRE+Skw z_o4pl_1EU}<`4U7lS9hu(`$^3^maA5w&xD_qLzEnc-1PZxRg+VHp>ilw7$wlTV`g; zZ&J2G$foaUL*A&B=BH6-2U~6J(YlVCqhmerl#7&OPu?)P*Ia7O%ga#0RLh-UNfv9d z`6w+VA6N5O`b+3lFb2M^e0bbg{FVrkJ8k0<;Wvu`i+ImK zicj6a8$%aFM;^=F(VelVZw&fom%AT*>&}R#1*s-RuY$Spp=LDawqbJuPnM8r0AgE7 z!03a=(8(SoMy;jtdzaXEqRgs31D>q(6$;BQso%Q{N4go-F;AOk3QJ2ZKClRd6cmNc z*#>_;$8|fpLzZeH@qwfkG@d&zNk{bVF_bv=9LHlTR9o2=lh-^`TIPChcKncu=FBF& zG?AU|(5y#o_J(eZ5|#EVPLR5@6dovI+8o4I(0OL@sItp8^>ca7S)4Qf*D`At##qul zm1TB1yFGqp;Z0*}_{#OCQ6ybbkX0G74bs|lnVAKnKeonF9#EI9b|CvLtXYfc7H!&lxJ6&d`f{Tphz6&gBO=F6ZLJGdZ&)v1 z*RBaoS#)T&Txfs8Ytj?b59~URdm&!*w8w+oFZdj=b8mhCV$iz1(kQ3rP%^o@c%9&< z=lJo}&}K<-X_3b3_hnVB&&vDe?+jd&G-WTk9AdT7u;8X4P@vVgKmL02%A$Jld>q{u zZa-Y6Qt+b))ln4XEV&|}?xSmcupqPFu5Tc#UxrJA*CMIOJ%qavdB;swi+RYFXb+4B zwHUx|^$Tkjn6^$5V)xfRrVdotIeAl(>^poQ^&$|*3PQwu$#T(35#EKE^|-}2OOPr= zJKQi9?%A=uF9B%w;fDsF4Hurv*cRX({HMtJN1g*`i4674_Yi0VcHni}?+SP{nCxJO zS#f@#p+2>(r_aaF3CDwf6)Z{PUKyk$0k%U`@q56DGS4p|BLH{UWlh78VwWCbJ|-9& z!{q>_%PtU_#8rv#(w#wOWIu`_fpypl*xvUZ>oTr2`)oMQd9cg+4Fm{@G)VReD81ay z!|hGBUe#S;ev_{j@yQUkUl$+6FmbOj-qHFwaIG`<$x98B`<9z&Rh_vONud=>_ajFi zCff_7(L`1(#rusCD^-rZDj}<_1YE39Dmgo|0hdorbfK#lT>z-tba1({{Eb%!J9KHJ z4^_9SQS|bJQ9fT`LsJ#1J1YsiI-49S7w{C!+im$&L$y!YY$vnEzsM*5z~K z3S}H+31u9h_GG+vt(c7hPWdHO=FW+f< za^9^QdI`;Okb|zXrvp=I`Q{}pbI+ov&y;DMM-8aF4fM+cO!d4`+ulO^A{6luO`L6YuI? z66MPXmV|H}hOXGr7t=sl{)2^bz{U9r8VTvsDCmdQ9cS$bg zNMcB8(~gWV@R{{!xh~{Ggd@Y-$>c?7O}b?8XiW^~K6g*sRY$}Ya2_Q@q%~7$w{=g8 z?isJ_ynQ*;?G)ijOH0|;t!KEB9O21L3rdXzb#xbS9Z^UPMireCU6Mz5V$&*{te_HI zvPM8~Xem3o{Ug#u3a*G7V`H(ojzYB^(Gup|0FZ$JU(ozhiNV8JrXvrL#oPIsOhi43AxL)&I03Tszw*|RmK#*|C{0hReg*@z^%~H+=L3_@|CZ5Y?XyjFosA+Y1+4LLt-$7pZ6lUz{D8lWW zzqaU#ApfC|9$7?f1paAx;vf>eScR;=+_HV!dl@*{s~4M~l3a`twUQdZ1`6ktUGz*; z_T!xg5mV1tPyO8!PRux%dZQvNmCPVq8z(KB1j25}nwKx51^On`jx2B-0Vd>?V6Vd$ zgtab_Y|Hf%u@h(Mx#RowSSJR-K>av2q=o1AwOkNK!a}PA8e)A0;4AV&1$=rN*Gp-0 z4o9*N(=c`KwU+1~RJFO9eR2I@+JuJr^$-o6qHA$CL+sG;i)&8yVVz#oVza~nA1reU zJ`5rR#I{~hx0aY3tSQT|cne~F74S28b@1MpfdJH;MB}<|!t5#n%RxN~EZ!x=O=?Kx zfvv~4-x{ElM=TN(H>LHre{;D|zSlImjNc>@rr?Ql0Ob&^yl56Xj3S+i2m^6nTeB1_ zmeXCtWmNmsxe^^3HN6gV@x&JNs4qG;(0!~IYbHvwx9fg6vUX9(yr<7i8kKa? zU&9%4K&jKBaZ+NCwYOggJs>OrFBf5;ok%x|N&%ni5Sc>*4%y4;&QwU1@QW-PT)hQE z91K_>jC_-r>{CH-xXqJ?} z^o)7A=KQpgdR9vhwr@9M@NPl#@@C~MM!N-jlW1w8dr9uRu^Hv&_*|)k8sA4lqTPoW z?P{CPL_8eRo5Zv&z3HZ0_@D^Sc7eV#H`Q&2Add7K6GN~b#_n76gV(NG1g6^>rqqNi zZN)aLq>9Lw$PA_*R5J95?1g^}Lp{g#@g+B0`Ouu@WK?zL`~((j-M=_%k7Vq{f!O@3Cy(QwlqTPusEJZ{ zr;gqXTugy)A_!g5OH`bJmwa5@_r>g*%SVqmOm8p^v*e^w5gZ1t^*?;bva_oZn^P@Y zkV)z9g1tJ#nE(jk#%Uu(JY@(!HSQxmLy()-8y~UWVXrU@#=p8NEZ?jY9V$3oWrA2K zjDf*Ro^{8??_&|4Ai{8DtDA{|>s;T7I!gv<zqp(h7(z?J7DujJ~{=6)v>UL&i4<3$;?HJ0_Uy~&pyUsozu>6mP9NU)=FPHO;GsHJWKV)%*JtQ zKDO%Yt0Wx*Kt*>lw52chuEMlciyWS?L9n}T-Zf&eP1?-|(}bW;Bt5j)?=z3?YH%8S zjy7pvt2#N=_si_X7CZlfcnHH~Fb($e#{l~h(-7aWJaJPm0E1lW5%J`sswG+W`Dau*Yopmq6{ zK-}#_a*000=bzR*^c-~-Bli=eH07mD;joF?MkGGC3B9?el%0FKZ+28j+Bs4q6?`0T z5*N3=T_%6Ziw~y92ZNctE)h!g-&l|uDf+)GkFyem*8(io726Jgg$oyyzL3O5KFHR^ z63`^T3{3x&o~~TRPhQN1+?$=<7rs-@nkT2skLugG`b*2Pmzxn>#ap%`gVl3Bd$989DiZCJ zE%LU~FV!whyKK0h=?k;O98@hLTzM?H3Kxe3$B}{VoelZ!Dz<20yIRz)2O>+sJ$acg z%KpkW;J9CK7~2mDCR#_8c&ro)l0f8jjt{<0;l}N}YKh!VQfk>IZs5H3vlF`G%4!07 znf4SYM>2KHdXnV#X=#psw9C~J?%I7gDFdEDh(bCjtP8D$JN?G^Y_W-p9L4E+oufQc z#J$baYXXtjFnzdeW$i29ReCnr(F#W?Jwrji_pZT%fFacZU$BQ{)^HHJMAk0VEYb

7du(9gU)7j#8JCNeK>rvk+Sn*1B7R*Lmuk zsrpJdPePavz82046?~4IIX7TmJ;%b|_eXYfERjK4Fcdm!QrOpX+ z{2(4`osgd;vZC+geyyhbz{@yU)B;QX3FR!C*V@Nm9$_if3}}9B@^do93k3T`2rn|b z%>B*k4e_I8;_EUNhk&5Dw8e zw-Ed%iHn2)P;n73@_@AaFlOz-MQ!71c}7J}ckiw8hJl1mK;1nsOBPUi1AqtClJG#g z4j85l(4}&uBQCGU5lR?Vkyyw3@b)QTmQ~6*^+w-9XVaU{5^+Th!&5D&NCjWkdBNdf z^5MP4g89Vc6klgeE%6}m{M~&=ikIAxZi?AcxEHMv#7zh>3meD0?g2jK%Rx3&`U@Z2Xz9AHj1<4Q;%=ub<; zsp}e@uw=2nKfr8{#(kMAA^yz2XS{{*I4YUGsmNztzAr3|`||rrVP@Ojv}Je+z8->= zt|z{XsJhg>u>Ev?u&|P$xVJB4%iBAXi3SF5UCpsddd{eWrl|ycWHzt?z*WaEE0H{0`4IZ)ye^hzEpJJIj!9n#K$Eq6dfp!KPz~A!jUxW`Q(`GlXAxAjZuia z8N5feZ}_0}1#u)sObN_tC|;M^UI@G5{6R(kdi)&agtEG-yo#k42`Yq~vAst5m^IHS z<*YWN`9fZ)rz5`LGFc_%+ze84*u`)1o)gRiR5d4)xIv@AIM2{k+~z&AxY{SqRtA_z ztlP+;CSNFqWZke3UZRAS@+-l4SX=HUZbb;Pe}kh^Z~DM)1)yeEAFP? zF~~~l(OuPOo{N}k77*Lc9G=U=hW7oG;p|<|q~PjxyY0>J`AN5nd<}F97I;pO-uXEI zLQa^i3|e?o{3WNMx!t>1dEx3|YRUU@tBgb)60Z-UER0|g$&LN-jo|f#qovv#;@D?i z;CXbNMuHf!$qk_R%%pd6;8yg=Nrp27N$}JotVV(3p<|fT`(0qdz5?exuU+iu8OSB* zpCd1z!d3|__1$co9RF)E5%$fW!55HWpRJ6no&MDb`_{t!`(guKT@vm?I#sBM_0$E^1nhjIb}8)VS!bi!JNaEqW?^}zKJj* zaqHLiHfFCC^{vf}jT{_r1FZZ`fQG!T-|r6x=MxVHce~#GBjx(~@WR0vTIxGE7&)++ z>)ZbhyfsAl!}_-5-xChpuDDa<_dqcJhWN|XEh703#2;L_{=#(r;k)QRB>c(bpzo+>Vq~ue zThaeJ!ds3XwSe{~;cc0?o4ynNry>7dB1}uLN*m1F26pRi0|fm@xxU&z!)~$vSe68y z^6YjP&=ST${(}IP=lZHP|K$2V9REWp{(6dTOQG`V52{~#n%~RQQCP;Kb{7s#6L!)3 zq9yR}3Cs-jEcKnN4NYNTe{8Kye&@TT_))FD3L@$MMbMAF>~{iMFlB8HtW~AMu3rTy z{yo9}An5*|1-z{xj`3dv{n`2buBenHjAa(qoo&IcUmv~K|G@A+NW%X`lF!DklKxRs zy%~2C5(OL_1MH&vlj8Ofs{JR5|3TERZTt!a{y*WN{^<07ub$rni~UfO>&t-p3-CMs z|JN4(YE-xPNa4=U6hDt7zsu?oPO=AzoNtc=O@m8L)^xK`krp(B4B(+{55|5j{Q9{ z)DLv7FUNmjfBT{IcdA?H58<~{lJDtOhCaogGX5N#e@Fj*g6wYpufYF7!0im?d%C?1 z8nDslA4ct4qaXL~ui4Bk2nYlH?XdVW5cbZz2Ca2HhI}@b@ct^e^x~jTb+I ze|^vptp4=;kNxP+=-Zj__jIe9>nHU83I1#K8p7cJ&|%*C_)*;3S@QRE>oe?6&`*8R ze?1$w_CN5y_6bce{NHs(KO=5u(BIRo$3+<8pZkMbyC0rz=hNTQEe_rKKe&Hvz_*q^ qkiTl=gCYN}z5R^%wJJ5gBfd8iWLPXsI5;-gpDV0E`NF<}gZqE&q*san literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..db8a639156f204113346a870f578ffd2f26275cb GIT binary patch literal 79059 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 literal 0 HcmV?d00001 diff --git a/TSG 800/assets/iconSat.png b/TSG 800/assets/iconSat.png new file mode 100644 index 0000000000000000000000000000000000000000..2e9dee021150ac5b26f5b4a4308230a478e23277 GIT binary patch literal 2131 zcmb7Ec{J2*8~%+Mvsq@wzLs^eRb*i~$LI0Tt1ZV9?IE{{tL= z!o)!c(VZn40K~<_#lYe)2>9PGKq3x>zyLT#MpjNrK^1HqU%1wtNnp5{hcJRYfJAv z`|N5VkHzIl+Mg|@>{~~R?pDy<)y>edNx_dr9e>hNu4L59-S< zvIEDxUSS0cbZ6e_tQs`%nuJE#LUO~cmu)!8+-k*$`=&ngK6gGo?2K0-H%)DwM|uZ7 zgy*XV9Y93J4SM^2pReQl~z&^GF-^&-UI^?0@Mfg+n_H8b?e6Mu zj_En4mjuKz1u=uL9J{Gi=-Fe^3AZPGxZL<_!IHC~yD2j7{D6kzIk_4zal}i8yml03 zqmLbIGkjT&%3pA*?aTKM-|qDKtBvE#oj&f1$cVfZ$`mW=lOGk=?_sayI59h08Hh|m zaNB0bO7EijM9W@*%6xVEN%Ibm43LUBEkygP14n7BJC=qq2*q2_(VyUGmj}|j60fd% zooSLX)B0%Xg~vGR=#bMI>R6=nejM+|1~*WIKA{+jB2$!v%kS1d^Q zMmA!%jJDatWmog%s?Iytd&Q{Xd9i3@YL@!3PJ4l*<$YP;(d%iWF73Eghzse8Ot=N& zCsQ~4W)ZB!_e6#IQro%nr|U8vFOINQCfi0(1jNRLFr)E-xMA)2-Us=E#|jl+`8nSR z8I{@_%VT+ZmdF@f#)g1^ek(f5njC^!umpcBTOceJ=&8_>S8eiKLT<%VtCDQ@dA)XV zT6D-bnZDbz=$Z8kn0x;OqsOC!FI4-YTfFi z1`w}XlD7V84J%gup0PoB$c3N2$KSj|WJGX$((CDWe#?0GcVFql#`))2Z$sa{Et%hs z!V7^}RZ4_kyNo*VsgXVDP_7bhD|@^pCP~Re$0EV}tnr!a64J5BqOJb1y83IE#aP0W zH~q_WmemhlqAZBW?@cm)M}?U9d`}tK(`!0!h#Tu6Y^L4rPS?V5o?I7i+)PjDR1~c9 zb*$65Pl`dt{sYmU_I%$6+z!w;#?>$ut{WXRnDv>wY%v&OL5V)Hx1e$*i)fWkY7T(q!>AlG$olZvNRuo0}$HE-@yj3aQs);&kRk{Z*noOMFWaq#e!wB= zLUs%TEqPka=$jaKfQHh|oI()dn^hzBmg?z7&UnMD*kpKy-3^<2=kl + + + + 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 From 183d0311fe27f82696b71b305d127e84544d6d3b Mon Sep 17 00:00:00 2001 From: Gertec Developer Date: Tue, 1 Sep 2020 16:32:00 -0300 Subject: [PATCH 5/6] Atualizado projeto SAT --- .../android/app/src/main/res/layout/telajava.xml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 GPOS 700/android/app/src/main/res/layout/telajava.xml diff --git a/GPOS 700/android/app/src/main/res/layout/telajava.xml b/GPOS 700/android/app/src/main/res/layout/telajava.xml deleted file mode 100644 index 29419bb..0000000 --- a/GPOS 700/android/app/src/main/res/layout/telajava.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - From 68985348edef8e46eb0f7a758cc87dce6229703d Mon Sep 17 00:00:00 2001 From: Gertec Developer Date: Tue, 15 Sep 2020 18:33:22 -0300 Subject: [PATCH 6/6] =?UTF-8?q?Adicionado=20tratamento=20de=20NFC=20antes?= =?UTF-8?q?=20da=20impress=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/example/flutter_gertec/GertecPrinter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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; }