From ec79c7fc58c7b92b939c29f10fec847ba878dca3 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 25 Aug 2020 17:52:10 -0300 Subject: [PATCH 01/27] Start Send Transfer development --- FormSendOrder.html | 50 ++++++++++++++++++++++++++++++++++++++++++++++ sdkSendTransfer.js | 6 ++++++ utilsNavigation.js | 3 +++ 3 files changed, 59 insertions(+) create mode 100644 FormSendOrder.html create mode 100644 sdkSendTransfer.js diff --git a/FormSendOrder.html b/FormSendOrder.html new file mode 100644 index 0000000..2bacb93 --- /dev/null +++ b/FormSendOrder.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + +
+
+
+

Entre com o arquivo da chave privada.

+ +
+
+

Digite sua senha

+ +
+
+ +
+
+
+ + + + \ No newline at end of file diff --git a/sdkSendTransfer.js b/sdkSendTransfer.js new file mode 100644 index 0000000..2484756 --- /dev/null +++ b/sdkSendTransfer.js @@ -0,0 +1,6 @@ +function sendTransferDialog() +{ + var html = HtmlService.createHtmlOutputFromFile('FormSendOrder'); + SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp. + .showModalDialog(html, 'Envio de Transferência sem Aprovação'); +} \ No newline at end of file diff --git a/utilsNavigation.js b/utilsNavigation.js index 152ea0a..3097be6 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -26,3 +26,6 @@ function goHomeSheet() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Principal')); } +function goSendTransferSheet() { + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência sem Aprovação')) +} \ No newline at end of file From cf05a43b57da86146ba0a283ab058078d09a9536 Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 26 Aug 2020 08:36:01 -0300 Subject: [PATCH 02/27] Fixing wrong password bug --- FormCredentials.html | 4 +++- FormSelectTeam.html | 4 +++- FormSendOrder.html | 42 ++++++++++++++++++++++++++++++++++---- FormViewCharge.html | 4 +++- FormViewChargePayment.html | 4 +++- FormViewStatement.html | 4 +++- FormViewTransfer.html | 4 +++- apiAuth.js | 12 +++++++++++ apiUser.js | 2 +- 9 files changed, 69 insertions(+), 11 deletions(-) diff --git a/FormCredentials.html b/FormCredentials.html index 5881f4a..320a18d 100644 --- a/FormCredentials.html +++ b/FormCredentials.html @@ -11,7 +11,9 @@
diff --git a/FormSelectTeam.html b/FormSelectTeam.html index 0660723..8d25c78 100644 --- a/FormSelectTeam.html +++ b/FormSelectTeam.html @@ -11,7 +11,9 @@
diff --git a/FormSendOrder.html b/FormSendOrder.html index 2bacb93..f25d2bf 100644 --- a/FormSendOrder.html +++ b/FormSendOrder.html @@ -11,7 +11,9 @@
@@ -21,17 +23,33 @@

Digite sua senha

- +

+
+ +
- +
+
+
+

ExternalId - Identificador único para a transação

+ +

Descrição da transação

+ +
+
+

Entre com o arquivo da chave privada.

@@ -33,7 +42,7 @@ Loading...
-
+
@@ -63,26 +72,44 @@ reader.readAsText(event.target.files[0]); } +function showMessage(message) +{ + $("#alert").show(); + var alertMessage = document.getElementById("alert-message"); + alertMessage.innerHTML = message; + window.scrollTo(0,0); +} + function send() { let password = document.getElementById("password").value; - console.log(privateKey); + let externalId = document.getElementById("externalId").value; + let description = document.getElementById("description").value; + let tags = null; + if(privateKey === "") + { + let message = "Por favor, insira um arquivo válido."; + showMessage(message); + privateKey = ""; + return; + } + startLoading(); google.script.run.withSuccessHandler(onSuccess) .withFailureHandler(onFailure) - .verifyPassword(password); + .executeTransfer(password, privateKey, description, externalId, tags); } function onSuccess() { stopLoading(); + privateKey = ""; } function onFailure(error) { console.log("Deu erro"); + console.log(error); stopLoading(); let message = JSON.parse(error["message"])["message"]; - $("#alert").show(); - var alertMessage = document.getElementById("alert-message"); - alertMessage.innerHTML = message; + showMessage(message); } function init() diff --git a/sdkSendTransfer.js b/sdkSendTransfer.js index 61970d3..5185b07 100644 --- a/sdkSendTransfer.js +++ b/sdkSendTransfer.js @@ -1,5 +1,53 @@ function sendTransferDialog() { - var html = HtmlService.createHtmlOutputFromFile('FormSendOrder'); + var html = HtmlService.createHtmlOutputFromFile('FormSendTransfer'); SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp. .showModalDialog(html, 'Envio de Transferência sem Aprovação'); +} + +function executeTransfer(password, privateKeyPem, description, externalId, tags) +{ + //verifyPassword(password); + sendTransfer(privateKeyPem, description, externalId, tags); +} + +function sendTransfer(privateKeyPem, description, externalId, tags) +{ + + let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência sem Aprovação'); + let transfers = []; + + formatHeader(sheet); + + for(let i=11; i<=sheet.getLastRow(); i++) { + transfers.push({ + name: sheet.getRange('A' + i.toString()).getValue(), + taxId: sheet.getRange('B' + i.toString()).getValue(), + amount: parseInt(100*sheet.getRange('C' + i.toString()).getValue(), 10), + bankCode: sheet.getRange('D' + i.toString()).getValue(), + branchCode: sheet.getRange('E' + i.toString()).getValue(), + accountNumber: sheet.getRange('F' + i.toString()).getValue(), + tags: sheet.getRange('G' + i.toString()).getValue().split(","), + description: sheet.getRange('H' + i.toString()).getValue() + }); + } + + let transaction = { + externalId: externalId, + description: description, + tags: tags + } + + let payload = { + transaction: transaction, + transfers: transfers + } + + let payloadString = JSON.stringify(payload); + + let signature = ecdsags.easySign(payloadString, privateKeyPem); + const headers = { + "Digital-Signature": signature + } + + json = JSON.parse(fetch("/v1/transfer", method = 'POST', body = payload, headers = headers).content); } \ No newline at end of file diff --git a/utilsBase.js b/utilsBase.js index b50a66f..1799e20 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -11,6 +11,7 @@ function getHeaderColumns(sheet){ return { 'Extrato': ["Data", "Tipo de transação", "Valor", "Saldo Final", "Descrição", "Id Transação", "Tarifa", "Tags"], 'Transferência com Aprovação': ["Nome", "CPF/CNPJ", "Valor", "Código do Banco", "Agência", "Conta", "Tags", "Descrição"], + 'Transferência sem Aprovação': ["Nome", "CPF/CPNJ", "Valor", "Código do Banco", "Agência", "Conta", "Tags", "Descrição"], 'Consulta de Boleto': ["Data de Emissão", "Nome", "CPF/CNPJ", "Status", "Valor", "Vencimento", "Linha digitável", "Id Boleto", "Tarifa", "Tags", "Link PDF"], 'Consulta de Pagamento Boleto': ["Data de Criação", "Id Pagamento", "Valor", "Status", "Data de Agendamento", "Linha Digitável", "Descrição", "Tags"], 'Consulta de Transferência': ["Data de Criação", "Id Transferência", "Valor", "Status", "Nome", "CPF/CNPJ", "Código do Banco", "Agência", "Número da Conta", "Ids de Transação (Saída, Estorno)"], From e7fc131092e4a27cceaa0287e0f8093a056e15c0 Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 31 Aug 2020 15:00:08 -0300 Subject: [PATCH 05/27] Add privateKey check before sending transfers --- FormSendTransfer.html | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/FormSendTransfer.html b/FormSendTransfer.html index 1b9319b..070f5cc 100644 --- a/FormSendTransfer.html +++ b/FormSendTransfer.html @@ -90,13 +90,23 @@ let message = "Por favor, insira um arquivo válido."; showMessage(message); privateKey = ""; + document.getElementById("file-input").value = ""; return; } + else{ + try { + ecdsags.PrivateKey.fromPem(privateKey); + startLoading(); + google.script.run.withSuccessHandler(onSuccess) + .withFailureHandler(onFailure) + .executeTransfer(password, privateKey, description, externalId, tags); + } catch(e){ + let message = "Chave privada inválida. Por favor, tente outra"; + showMessage(message); + privateKey = ""; + } + } - startLoading(); - google.script.run.withSuccessHandler(onSuccess) - .withFailureHandler(onFailure) - .executeTransfer(password, privateKey, description, externalId, tags); } function onSuccess() { From f475ed2dd6c5e491785eabeb3d37072a72fa6142 Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 31 Aug 2020 15:52:55 -0300 Subject: [PATCH 06/27] Add check privateKey before sending transfer --- FormSendTransfer.html | 33 ++++++++++++++++++++------------- utilsBase.js | 6 ++++++ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/FormSendTransfer.html b/FormSendTransfer.html index 070f5cc..1fafa78 100644 --- a/FormSendTransfer.html +++ b/FormSendTransfer.html @@ -94,19 +94,25 @@ return; } else{ - try { - ecdsags.PrivateKey.fromPem(privateKey); - startLoading(); + google.script.run.withSuccessHandler(pkCheckSuccess(password, privateKey, description, externalId, tags)) + .withFailureHandler(pkCheckFailure) + .checkPrivateKey(privateKey); + } + +} + +function pkCheckSuccess(password, privateKey, description, externalId, tags) +{ + startLoading(); google.script.run.withSuccessHandler(onSuccess) .withFailureHandler(onFailure) .executeTransfer(password, privateKey, description, externalId, tags); - } catch(e){ - let message = "Chave privada inválida. Por favor, tente outra"; - showMessage(message); - privateKey = ""; - } - } +} +function pkCheckFailure() +{ + let message = "Chave privada inválida. Por favor, tente outra."; + showMessage(message); } function onSuccess() { @@ -115,11 +121,12 @@ } function onFailure(error) { - console.log("Deu erro"); - console.log(error); stopLoading(); - let message = JSON.parse(error["message"])["message"]; - showMessage(message); + if(error.constructor == Object) + { + let message = JSON.parse(error["message"])["message"]; + showMessage(message); + } } function init() diff --git a/utilsBase.js b/utilsBase.js index 1799e20..1c52739 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -82,6 +82,12 @@ function clearSheet(sheet){ } } + +function checkPrivateKey(key) +{ + ecdsags.PrivateKey.fromPem(key); +} + // //function onOpen(e) { // signOut(false); From d7d5bce7df7af3215f4c2aba2f75a2eb866f3cc0 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 1 Sep 2020 14:18:50 -0300 Subject: [PATCH 07/27] Sketch transfer --- FormCredentials.html | 1 + FormSendTransfer.html | 8 +++++++- sdkSendTransfer.js | 9 +-------- utilsRequest.js | 18 ++++++++++++++---- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/FormCredentials.html b/FormCredentials.html index 320a18d..f5db2c7 100644 --- a/FormCredentials.html +++ b/FormCredentials.html @@ -79,6 +79,7 @@ function onFailure(error) { stopLoading(); + console.log(error); let message = JSON.parse(error["message"])["message"]; $("#alert").show(); var alertMessage = document.getElementById("alert-message"); diff --git a/FormSendTransfer.html b/FormSendTransfer.html index 1fafa78..c66042b 100644 --- a/FormSendTransfer.html +++ b/FormSendTransfer.html @@ -122,11 +122,17 @@ function onFailure(error) { stopLoading(); + if(error.constructor == Object) { - let message = JSON.parse(error["message"])["message"]; + let message = JSON.parse(error)["message"]; showMessage(message); } + else + { + console.log(error); + console.log(error.message); + } } function init() diff --git a/sdkSendTransfer.js b/sdkSendTransfer.js index 5185b07..4d2497e 100644 --- a/sdkSendTransfer.js +++ b/sdkSendTransfer.js @@ -42,12 +42,5 @@ function sendTransfer(privateKeyPem, description, externalId, tags) transfers: transfers } - let payloadString = JSON.stringify(payload); - - let signature = ecdsags.easySign(payloadString, privateKeyPem); - const headers = { - "Digital-Signature": signature - } - - json = JSON.parse(fetch("/v1/transfer", method = 'POST', body = payload, headers = headers).content); + json = JSON.parse(fetch("/transfer", method = 'POST', payload, null, 'v1', null, privateKeyPem).content); } \ No newline at end of file diff --git a/utilsRequest.js b/utilsRequest.js index 3a31c6e..ca18c99 100644 --- a/utilsRequest.js +++ b/utilsRequest.js @@ -11,7 +11,9 @@ function getHostname(environment, version = "v1"){ }[environment.toLowerCase()]; } -function fetch(path, method='GET', payload=null, query=null, version='v1', environment=null) { + + +function fetch(path, method='GET', payload=null, query=null, version='v1', environment=null, privateKeyPem=null) { let user = new getDefaultUser(); if (!user.accessToken && (path != "/auth/access-token")) { throw JSON.stringify({"message": "Erro de autenticação! Por favor, faça login novamente."}); @@ -36,15 +38,23 @@ function fetch(path, method='GET', payload=null, query=null, version='v1', envir } url += queryString; } - if (payload && (method === 'POST' || method === 'PUT' || method === 'PATCH')) { - options['payload'] = JSON.stringify(payload); - } options['headers'] = { 'Access-Token': user.accessToken, 'User-Agent': 'GoogleSheets-SDK-0.1.0', 'Accept-Language': 'pt-BR', 'Content-Type': 'application/json' }; + if (payload && (method === 'POST' || method === 'PUT' || method === 'PATCH')) { + options['payload'] = JSON.stringify(payload); + if(privateKeyPem != null) + { + let signature = ecdsags.easySign(options['payload'], privateKeyPem); + options['headers']['Digital-Signature'] = signature; + //throw new Error(user.accessToken); + } + } + + let response = UrlFetchApp.fetch(url, options); let content = response.getContentText(); let status = response.getResponseCode(); From 8886f3ef6c4d6a4de1426f52aaa89bdf1d74242f Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 1 Sep 2020 14:57:08 -0300 Subject: [PATCH 08/27] Finish transfer --- FormSendTransfer.html | 63 +++++++++++++++++++++++++------------------ sdkSendTransfer.js | 2 +- utilsRequest.js | 1 - 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/FormSendTransfer.html b/FormSendTransfer.html index c66042b..cf9a8f9 100644 --- a/FormSendTransfer.html +++ b/FormSendTransfer.html @@ -16,33 +16,42 @@
-
-
+
+

ExternalId - Identificador único para a transação

- + +
+
+
+

Descrição da transação

- +
-

-
-
-

Entre com o arquivo da chave privada.

- -
-
-

Digite sua senha

- -
-
- +
+
+

Entre com o arquivo da chave privada.

+
+
+ + +
+
+
+
+
+
+

Digite sua senha

+ +
+
-
- +
+
+ -
+
@@ -66,6 +75,8 @@ function loadPrivateKey(event) { let reader = new FileReader(); + let fullPath = document.getElementById("file-input").value; + document.getElementById("file-input-label").innerHTML = fullPath.split(/(\\|\/)/g).pop(); reader.onload = function(event) { privateKey = event.target.result; }; @@ -90,6 +101,7 @@ let message = "Por favor, insira um arquivo válido."; showMessage(message); privateKey = ""; + document.getElementById("file-input-label").innerHTML = "Insira um arquivo"; document.getElementById("file-input").value = ""; return; } @@ -123,13 +135,12 @@ function onFailure(error) { stopLoading(); - if(error.constructor == Object) + try { - let message = JSON.parse(error)["message"]; + let message = JSON.parse(error.message)["message"]; showMessage(message); - } - else - { + } catch(e) { + //console.log(e.message); console.log(error); console.log(error.message); } diff --git a/sdkSendTransfer.js b/sdkSendTransfer.js index 4d2497e..1d5ec8b 100644 --- a/sdkSendTransfer.js +++ b/sdkSendTransfer.js @@ -6,7 +6,7 @@ function sendTransferDialog() { function executeTransfer(password, privateKeyPem, description, externalId, tags) { - //verifyPassword(password); + verifyPassword(password); sendTransfer(privateKeyPem, description, externalId, tags); } diff --git a/utilsRequest.js b/utilsRequest.js index ca18c99..fe57a23 100644 --- a/utilsRequest.js +++ b/utilsRequest.js @@ -50,7 +50,6 @@ function fetch(path, method='GET', payload=null, query=null, version='v1', envir { let signature = ecdsags.easySign(options['payload'], privateKeyPem); options['headers']['Digital-Signature'] = signature; - //throw new Error(user.accessToken); } } From eaa42237fa37b04e1b1b1cd695d1a0ec5716d0ce Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 2 Sep 2020 06:56:40 -0300 Subject: [PATCH 09/27] Start Boleto payment implementation --- FormPayBoleto.html | 161 ++++++++++++++++++++++++++++++++++++++++++ FormSendTransfer.html | 19 +++++ sdkPayBoleto.js | 33 +++++++++ sdkSendTransfer.js | 2 +- utilsNavigation.js | 5 ++ 5 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 FormPayBoleto.html create mode 100644 sdkPayBoleto.js diff --git a/FormPayBoleto.html b/FormPayBoleto.html new file mode 100644 index 0000000..262b49a --- /dev/null +++ b/FormPayBoleto.html @@ -0,0 +1,161 @@ + + + + + + + + + + + + + +
+
+
+

Entre com o arquivo da chave privada.

+
+
+ + +
+
+
+
+
+
+

Digite sua senha

+ +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/FormSendTransfer.html b/FormSendTransfer.html index cf9a8f9..a8fea7d 100644 --- a/FormSendTransfer.html +++ b/FormSendTransfer.html @@ -15,6 +15,12 @@
+
@@ -73,6 +79,10 @@ $("#alert").hide(); } +function hideSuccessAlert(){ + $("#alert-success").hide(); +} + function loadPrivateKey(event) { let reader = new FileReader(); let fullPath = document.getElementById("file-input").value; @@ -85,6 +95,8 @@ function showMessage(message) { + hideAlert(); + hideSuccessAlert(); $("#alert").show(); var alertMessage = document.getElementById("alert-message"); alertMessage.innerHTML = message; @@ -130,6 +142,12 @@ function onSuccess() { stopLoading(); privateKey = ""; + hideAlert(); + hideSuccessAlert(); + $("#alert-success").show(); + var alertMessage = document.getElementById("alert-success-message"); + alertMessage.innerHTML = "Transferências enviadas com sucesso!"; + window.scrollTo(0,0); } function onFailure(error) { @@ -149,6 +167,7 @@ function init() { hideAlert(); + hideSuccessAlert(); document.getElementById('file-input').addEventListener('change', loadPrivateKey, false); } diff --git a/sdkPayBoleto.js b/sdkPayBoleto.js new file mode 100644 index 0000000..1552d18 --- /dev/null +++ b/sdkPayBoleto.js @@ -0,0 +1,33 @@ +function payBoletosDialog() { + var html = HtmlService.createHtmlOutputFromFile('FormPayBoleto'); + SpreadsheetApp.getUi() + .showModalDialog(html, 'Pagamento de Boletos'); +} + +function executeBoletoPayment(password, privateKeyPem) +{ + verifyPassword(password); + sendPayments(privateKeyPem); +} + +function sendPayments(privateKeyPem) +{ + let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pagamento de Boletos'); + let payments = []; + + for(let i=11; i<=sheet.getLastRow(); i++) { + payments.push({ + line: sheet.getRange('A' + i.toString()).getValue(), + taxId: sheet.getRange('B' + i.toString()).getValue(), + scheduled: sheet.getRange('C' + i.toString()).getValue(), + description: sheet.getRange('D' + i.toString()).getValue(), + tags: sheet.getRange('E' + i.toString()).getValue().split(",") + }); + } + + let payload = { + payments: payments + } + + json = JSON.parse(fetch("/charge-payment", method = 'POST', payload, null, 'v1', null, privateKeyPem).content); +} \ No newline at end of file diff --git a/sdkSendTransfer.js b/sdkSendTransfer.js index 1d5ec8b..e0c07a9 100644 --- a/sdkSendTransfer.js +++ b/sdkSendTransfer.js @@ -1,6 +1,6 @@ function sendTransferDialog() { var html = HtmlService.createHtmlOutputFromFile('FormSendTransfer'); - SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp. + SpreadsheetApp.getUi() .showModalDialog(html, 'Envio de Transferência sem Aprovação'); } diff --git a/utilsNavigation.js b/utilsNavigation.js index 3097be6..b40c124 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -28,4 +28,9 @@ function goHomeSheet() { function goSendTransferSheet() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência sem Aprovação')) +} + +function goPayBoletos() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pagamento de Boletos')); } \ No newline at end of file From cd5dee7b24e91621fbc9c8d2435d15dde8bc5623 Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 2 Sep 2020 12:43:39 -0300 Subject: [PATCH 10/27] Finish PayBoleto --- FormPayBoleto.html | 15 ++++++++++++++- FormSendTransfer.html | 15 ++++++++++++++- sdkPayBoleto.js | 26 ++++++++++++++++++++------ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/FormPayBoleto.html b/FormPayBoleto.html index 262b49a..ffb5f97 100644 --- a/FormPayBoleto.html +++ b/FormPayBoleto.html @@ -142,8 +142,21 @@ try { - let message = JSON.parse(error.message)["message"]; + let parsed = JSON.parse(error.message); + let message = parsed["message"]; + if("errors" in parsed) + { + for(let suberror of parsed["errors"]) { + let suberrorMessage = suberror["message"]; + let splitMessage = suberrorMessage.split(":"); + splitMessage[0] = splitMessage[0].replace("Element ", ""); + splitMessage[0] = "Linha " + (11 - (-splitMessage[0])); + let newMessage = splitMessage.join(":"); + message += "
" + newMessage; + } + } showMessage(message); + } catch(e) { //console.log(e.message); console.log(error); diff --git a/FormSendTransfer.html b/FormSendTransfer.html index a8fea7d..953ef94 100644 --- a/FormSendTransfer.html +++ b/FormSendTransfer.html @@ -155,8 +155,21 @@ try { - let message = JSON.parse(error.message)["message"]; + let parsed = JSON.parse(error.message); + let message = parsed["message"]; + if("errors" in parsed) + { + for(let suberror of parsed["errors"]) { + let suberrorMessage = suberror["message"]; + let splitMessage = suberrorMessage.split(":"); + splitMessage[0] = splitMessage[0].replace("Element ", ""); + splitMessage[0] = "Linha " + (11 - (-splitMessage[0])); + let newMessage = splitMessage.join(":"); + message += "
" + newMessage; + } + } showMessage(message); + } catch(e) { //console.log(e.message); console.log(error); diff --git a/sdkPayBoleto.js b/sdkPayBoleto.js index 1552d18..d8eb90a 100644 --- a/sdkPayBoleto.js +++ b/sdkPayBoleto.js @@ -6,7 +6,7 @@ function payBoletosDialog() { function executeBoletoPayment(password, privateKeyPem) { - verifyPassword(password); + //verifyPassword(password); sendPayments(privateKeyPem); } @@ -16,18 +16,32 @@ function sendPayments(privateKeyPem) let payments = []; for(let i=11; i<=sheet.getLastRow(); i++) { - payments.push({ - line: sheet.getRange('A' + i.toString()).getValue(), + let paymentItem = { taxId: sheet.getRange('B' + i.toString()).getValue(), - scheduled: sheet.getRange('C' + i.toString()).getValue(), + scheduled: sheet.getRange('C' + i.toString()).getValue().replace(/(\d{2})\/(\d{2})\/(\d{4})*/, '$3-$2-$1'), description: sheet.getRange('D' + i.toString()).getValue(), tags: sheet.getRange('E' + i.toString()).getValue().split(",") - }); + }; + + let barCodeOrLine = sheet.getRange('A' + i.toString()).getValue(); + barCodeOrLine = barCodeOrLine.replace(/[^0-9]/g, ''); + if(barCodeOrLine.length > 44) + { + paymentItem["line"] = barCodeOrLine; + } + else + { + paymentItem["barCode"] = barCodeOrLine; + } + + payments.push(paymentItem); } let payload = { payments: payments - } + }; + + //throw new Error(JSON.stringify(payload)); json = JSON.parse(fetch("/charge-payment", method = 'POST', payload, null, 'v1', null, privateKeyPem).content); } \ No newline at end of file From 6ac4038193daf6817f989c6ecc496ab85101915f Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 2 Sep 2020 14:03:55 -0300 Subject: [PATCH 11/27] Implement fetch customers --- sdkPayBoleto.js | 4 +++- sdkViewCustomers.js | 42 ++++++++++++++++++++++++++++++++++++++++++ utilsBase.js | 2 ++ utilsNavigation.js | 5 +++++ 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 sdkViewCustomers.js diff --git a/sdkPayBoleto.js b/sdkPayBoleto.js index d8eb90a..7c223a9 100644 --- a/sdkPayBoleto.js +++ b/sdkPayBoleto.js @@ -6,7 +6,7 @@ function payBoletosDialog() { function executeBoletoPayment(password, privateKeyPem) { - //verifyPassword(password); + verifyPassword(password); sendPayments(privateKeyPem); } @@ -15,6 +15,8 @@ function sendPayments(privateKeyPem) let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pagamento de Boletos'); let payments = []; + formatHeader(sheet); + for(let i=11; i<=sheet.getLastRow(); i++) { let paymentItem = { taxId: sheet.getRange('B' + i.toString()).getValue(), diff --git a/sdkViewCustomers.js b/sdkViewCustomers.js new file mode 100644 index 0000000..d11b773 --- /dev/null +++ b/sdkViewCustomers.js @@ -0,0 +1,42 @@ + +function fetchCustomers() +{ + let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Consulta de Clientes'); + let i = 10; + let cursor = ""; + let query = {}; + + clearSheet(sheet); + formatHeader(sheet); + + let zeroElements = true; + do { + query["cursor"] = cursor; + json = JSON.parse(fetch("/charge/customer", method = 'GET', null, query).content); + let customers = json["customers"]; + cursor = json["cursor"]; + for(let element of customers) + { + zeroElements = false; + i++; + sheet.getRange('A' + i.toString()).setValue(element["id"]); + sheet.getRange('B' + i.toString()).setValue(element["name"]); + sheet.getRange('C' + i.toString()).setValue(element["taxId"]); + sheet.getRange('D' + i.toString()).setValue(element["email"]); + sheet.getRange('E' + i.toString()).setValue(element["phone"]); + + let address = element["address"]; + sheet.getRange('F' + i.toString()).setValue(address["streetLine1"]); + sheet.getRange('G' + i.toString()).setValue(address["streetLine2"]); + sheet.getRange('H' + i.toString()).setValue(address["district"]); + sheet.getRange('I' + i.toString()).setValue(address["city"]); + sheet.getRange('J' + i.toString()).setValue(address["stateCode"]); + sheet.getRange('K' + i.toString()).setValue(address["zipCode"]); + + sheet.getRange('L' + i.toString()).setValue(element["tags"].join(", ")); + } + } while(cursor); + if(zeroElements) { + Browser.msgBox("Nenhum cliente cadastrado."); + } +} \ No newline at end of file diff --git a/utilsBase.js b/utilsBase.js index 1c52739..f28eee6 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -15,6 +15,8 @@ function getHeaderColumns(sheet){ 'Consulta de Boleto': ["Data de Emissão", "Nome", "CPF/CNPJ", "Status", "Valor", "Vencimento", "Linha digitável", "Id Boleto", "Tarifa", "Tags", "Link PDF"], 'Consulta de Pagamento Boleto': ["Data de Criação", "Id Pagamento", "Valor", "Status", "Data de Agendamento", "Linha Digitável", "Descrição", "Tags"], 'Consulta de Transferência': ["Data de Criação", "Id Transferência", "Valor", "Status", "Nome", "CPF/CNPJ", "Código do Banco", "Agência", "Número da Conta", "Ids de Transação (Saída, Estorno)"], + 'Pagamento de Boletos': ["Linha Digitável ou Código de Barras", "CPF/CPNJ do Beneficiário", "Data de Agendamento", "Descrição", "Tags"], + 'Consulta de Clientes': ["Id do Cliente", "Nome", "CPF/CNPJ", "E-Mail", "Telefone", "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP", "Tags"] }[sheet.getName()]; } diff --git a/utilsNavigation.js b/utilsNavigation.js index b40c124..9fd3bde 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -33,4 +33,9 @@ function goSendTransferSheet() { function goPayBoletos() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pagamento de Boletos')); +} + +function goViewCustomers() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Consulta de Clientes')); } \ No newline at end of file From aa4bcdcc4b22461e9d9a27ae69bab9b4153d2356 Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 2 Sep 2020 15:15:51 -0300 Subject: [PATCH 12/27] Start implementing createBoleto --- sdkCreateBoleto.js | 22 ++++++++++++++++++++++ sdkPayBoleto.js | 2 +- utilsBase.js | 8 +++++++- utilsNavigation.js | 5 +++++ 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 sdkCreateBoleto.js diff --git a/sdkCreateBoleto.js b/sdkCreateBoleto.js new file mode 100644 index 0000000..44fd1da --- /dev/null +++ b/sdkCreateBoleto.js @@ -0,0 +1,22 @@ + +function createBoleto() +{ + let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Emissão de Boletos'); + let boletos = []; + + formatHeader(sheet); + + for(let i=11; i<=sheet.getLastRow(); i++) { + let boleto = { + customerId: sheet.getRange('A' + i.toString()).getValue(), + amount: parseInt(100*sheet.getRange('B' + i.toString()).getValue(), 10), + dueDate: formatDateToISO(sheet.getRange('C' + i.toString()).getValue()), + fine: parseFloat(sheet.getRange('D' + i.toString().getValue())), + interest: parseFloat(sheet.getRange('E' + i.toString()).getValue()), + overdueLimit: parseInt(sheet.getRange('F' + i.toString()).getValue()), + discount: parseFloat(sheet.getRange('G' + i.toString()).getValue()), + discountDate: formatDateToISO(sheet.getRange('H' + i.toString()).getValue()), + + } + } +} \ No newline at end of file diff --git a/sdkPayBoleto.js b/sdkPayBoleto.js index 7c223a9..ec5714d 100644 --- a/sdkPayBoleto.js +++ b/sdkPayBoleto.js @@ -20,7 +20,7 @@ function sendPayments(privateKeyPem) for(let i=11; i<=sheet.getLastRow(); i++) { let paymentItem = { taxId: sheet.getRange('B' + i.toString()).getValue(), - scheduled: sheet.getRange('C' + i.toString()).getValue().replace(/(\d{2})\/(\d{2})\/(\d{4})*/, '$3-$2-$1'), + scheduled: formatDateToISO(sheet.getRange('C' + i.toString()).getValue()), description: sheet.getRange('D' + i.toString()).getValue(), tags: sheet.getRange('E' + i.toString()).getValue().split(",") }; diff --git a/utilsBase.js b/utilsBase.js index f28eee6..decc99e 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -16,7 +16,8 @@ function getHeaderColumns(sheet){ 'Consulta de Pagamento Boleto': ["Data de Criação", "Id Pagamento", "Valor", "Status", "Data de Agendamento", "Linha Digitável", "Descrição", "Tags"], 'Consulta de Transferência': ["Data de Criação", "Id Transferência", "Valor", "Status", "Nome", "CPF/CNPJ", "Código do Banco", "Agência", "Número da Conta", "Ids de Transação (Saída, Estorno)"], 'Pagamento de Boletos': ["Linha Digitável ou Código de Barras", "CPF/CPNJ do Beneficiário", "Data de Agendamento", "Descrição", "Tags"], - 'Consulta de Clientes': ["Id do Cliente", "Nome", "CPF/CNPJ", "E-Mail", "Telefone", "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP", "Tags"] + 'Consulta de Clientes': ["Id do Cliente", "Nome", "CPF/CNPJ", "E-Mail", "Telefone", "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP", "Tags"], + 'Emissão de Boletos': ["Id do Cliente", "Valor", "Data de Vencimento", "Multa", "Juros ao Mês", "Dias para Baixa Automática", "Desconto", "Data Limite do Desconto", "Descrição 1", "Valor 1", "Descrição 2", "Valor 2", "Descrição 3", "Valor 3"] }[sheet.getName()]; } @@ -90,6 +91,11 @@ function checkPrivateKey(key) ecdsags.PrivateKey.fromPem(key); } +function formatDateToISO(stringDate) +{ + return stringDate.replace(/(\d{2})\/(\d{2})\/(\d{4})*/, '$3-$2-$1'); +} + // //function onOpen(e) { // signOut(false); diff --git a/utilsNavigation.js b/utilsNavigation.js index 9fd3bde..ebf9e8d 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -38,4 +38,9 @@ function goPayBoletos() function goViewCustomers() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Consulta de Clientes')); +} + +function goCreateBoleto() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Emissão de Boletos')); } \ No newline at end of file From f942d4642712b2b55d19c83766618a416c6d6d5b Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 3 Sep 2020 16:24:02 -0300 Subject: [PATCH 13/27] Continue implementation of createBoleto --- sdkCreateBoleto.js | 78 +++++++++++++++++++++++++++++++++++++++++----- utilsBase.js | 2 +- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/sdkCreateBoleto.js b/sdkCreateBoleto.js index 44fd1da..4cde863 100644 --- a/sdkCreateBoleto.js +++ b/sdkCreateBoleto.js @@ -7,16 +7,78 @@ function createBoleto() formatHeader(sheet); for(let i=11; i<=sheet.getLastRow(); i++) { + + let descriptions = []; + for(let j=0; j<3; j++) + { + let column = String.fromCharCode(73 + j); + let text = sheet.getRange(column + i.toString()).getValue(); + if(text.lenght > 0) + { + let description = { + text: text, + amount: parseInt(sheet.getRange(column + i.toString()).getValue()) + }; + descriptions.push(description); + } + } + let boleto = { customerId: sheet.getRange('A' + i.toString()).getValue(), - amount: parseInt(100*sheet.getRange('B' + i.toString()).getValue(), 10), - dueDate: formatDateToISO(sheet.getRange('C' + i.toString()).getValue()), - fine: parseFloat(sheet.getRange('D' + i.toString().getValue())), - interest: parseFloat(sheet.getRange('E' + i.toString()).getValue()), - overdueLimit: parseInt(sheet.getRange('F' + i.toString()).getValue()), - discount: parseFloat(sheet.getRange('G' + i.toString()).getValue()), - discountDate: formatDateToISO(sheet.getRange('H' + i.toString()).getValue()), - + amount: parseInt(100*sheet.getRange('B' + i.toString()).getValue(), 10) + }; + + let dueDate = sheet.getRange('C' + i.toString()).getValue(); + if(dueDate.length > 0) + { + boleto["dueDate"] = formatDateToISO(dueDate); + } + let fine = sheet.getRange('D' + i.toString()).getValue(); + if(fine.length > 0) + { + boleto["fine"] = parseFloat(fine); + } + let interest = sheet.getRange('E' + i.toString()).getValue(); + if(interest.length > 0) + { + boleto["interest"] = parseFloat(interest); + } + let overdueLimit = sheet.getRange('F' + i.toString()).getValue(); + if(overdueLimit.length > 0) + { + boleto["overdueLimit"] = parseInt(overdueLimit); + } + let discount = sheet.getRange('G' + i.toString()).getValue(); + if(discount.length > 0) + { + boleto["dicount"] = parseFloat(discount); } + let discountDate = sheet.getRange('H' + i.toString()).getValue(); + if(discountDate.length > 0) + { + boleto["discountDate"] = formatDateToISO(discountDate); + } + + + if(descriptions.length > 0) + { + boleto["descriptions"] = descriptions; + } + let tags = sheet.getRange('O' + i.toString()).getValue().split(","); + if(tags.lenght > 0) + { + boleto["tags"] = tags; + } + + boletos.push(boleto); } + + let payload = { + charges: boletos + }; + + Browser.msgBox(JSON.stringify(payload)); + //throw new Error(payload); + + //json = JSON.parse(fetch("/charge", method = 'POST', payload, null).content); } \ No newline at end of file diff --git a/utilsBase.js b/utilsBase.js index decc99e..46828f1 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -17,7 +17,7 @@ function getHeaderColumns(sheet){ 'Consulta de Transferência': ["Data de Criação", "Id Transferência", "Valor", "Status", "Nome", "CPF/CNPJ", "Código do Banco", "Agência", "Número da Conta", "Ids de Transação (Saída, Estorno)"], 'Pagamento de Boletos': ["Linha Digitável ou Código de Barras", "CPF/CPNJ do Beneficiário", "Data de Agendamento", "Descrição", "Tags"], 'Consulta de Clientes': ["Id do Cliente", "Nome", "CPF/CNPJ", "E-Mail", "Telefone", "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP", "Tags"], - 'Emissão de Boletos': ["Id do Cliente", "Valor", "Data de Vencimento", "Multa", "Juros ao Mês", "Dias para Baixa Automática", "Desconto", "Data Limite do Desconto", "Descrição 1", "Valor 1", "Descrição 2", "Valor 2", "Descrição 3", "Valor 3"] + 'Emissão de Boletos': ["Id do Cliente", "Valor", "Data de Vencimento", "Multa", "Juros ao Mês", "Dias para Baixa Automática", "Desconto", "Data Limite do Desconto", "Descrição 1", "Valor 1", "Descrição 2", "Valor 2", "Descrição 3", "Valor 3", "Tags"] }[sheet.getName()]; } From 469ae6e7e10044fa3e1b9d0acbf3bd8d9e796a66 Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 4 Sep 2020 06:32:49 -0300 Subject: [PATCH 14/27] Implement CreateBoleto --- sdkCreateBoleto.js | 47 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/sdkCreateBoleto.js b/sdkCreateBoleto.js index 4cde863..e127d1b 100644 --- a/sdkCreateBoleto.js +++ b/sdkCreateBoleto.js @@ -11,13 +11,14 @@ function createBoleto() let descriptions = []; for(let j=0; j<3; j++) { - let column = String.fromCharCode(73 + j); - let text = sheet.getRange(column + i.toString()).getValue(); - if(text.lenght > 0) + let columnText = String.fromCharCode(73 + 2*j); + let text = sheet.getRange(columnText + i.toString()).getValue(); + if(text.length > 0) { + let columnAmount = String.fromCharCode(73 + 2*j + 1); let description = { text: text, - amount: parseInt(sheet.getRange(column + i.toString()).getValue()) + amount: parseInt(sheet.getRange(columnAmount + i.toString()).getValue()) }; descriptions.push(description); } @@ -33,25 +34,25 @@ function createBoleto() { boleto["dueDate"] = formatDateToISO(dueDate); } - let fine = sheet.getRange('D' + i.toString()).getValue(); + let fine = new String(sheet.getRange('D' + i.toString()).getValue()); if(fine.length > 0) { boleto["fine"] = parseFloat(fine); } - let interest = sheet.getRange('E' + i.toString()).getValue(); + let interest = new String(sheet.getRange('E' + i.toString()).getValue()); if(interest.length > 0) { boleto["interest"] = parseFloat(interest); } - let overdueLimit = sheet.getRange('F' + i.toString()).getValue(); + let overdueLimit = new String(sheet.getRange('F' + i.toString()).getValue()); if(overdueLimit.length > 0) { boleto["overdueLimit"] = parseInt(overdueLimit); } - let discount = sheet.getRange('G' + i.toString()).getValue(); + let discount = new String(sheet.getRange('G' + i.toString()).getValue()); if(discount.length > 0) { - boleto["dicount"] = parseFloat(discount); + boleto["discount"] = parseFloat(discount); } let discountDate = sheet.getRange('H' + i.toString()).getValue(); if(discountDate.length > 0) @@ -65,7 +66,7 @@ function createBoleto() boleto["descriptions"] = descriptions; } let tags = sheet.getRange('O' + i.toString()).getValue().split(","); - if(tags.lenght > 0) + if(tags.length > 0) { boleto["tags"] = tags; } @@ -76,9 +77,27 @@ function createBoleto() let payload = { charges: boletos }; - - Browser.msgBox(JSON.stringify(payload)); - //throw new Error(payload); - //json = JSON.parse(fetch("/charge", method = 'POST', payload, null).content); + try{ + fetch("/charge", method = 'POST', payload, null); + Browser.msgBox("Boletos Emitidos"); + } catch(e) + { + let message = "Boletos não emitidos. "; + let parsed = JSON.parse(e); + message += parsed["message"]; + if("errors" in parsed) + { + for(let suberror of parsed["errors"]) + { + let suberrorMessage = suberror["message"]; + let splitMessage = suberrorMessage.split(":"); + splitMessage[0] = splitMessage[0].replace("Element ", ""); + splitMessage[0] = "Linha " + (10 - (-splitMessage[0])); + let newMessage = splitMessage.join(":"); + message += "\n" + newMessage; + } + } + Browser.msgBox(message); + } } \ No newline at end of file From 3e69a690d49cc68fb3ba5543901a77b32ed933dc Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 4 Sep 2020 09:39:11 -0300 Subject: [PATCH 15/27] Start implementation of SendTransaction --- FormSendTransaction.html | 217 +++++++++++++++++++++++++++++++++++++++ sdkSendTransaction.js | 29 ++++++ utilsBase.js | 3 +- utilsNavigation.js | 5 + 4 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 FormSendTransaction.html create mode 100644 sdkSendTransaction.js diff --git a/FormSendTransaction.html b/FormSendTransaction.html new file mode 100644 index 0000000..c19c296 --- /dev/null +++ b/FormSendTransaction.html @@ -0,0 +1,217 @@ + + + + + + + + + + + + + +
+
+
+

ID do numérico do Workspace de destino

+ +
+
+
+

Valor a ser transferido

+
+
+ R$ +
+ +
+
+
+
+

Descrição para a transferência (mínimo de dez caracteres)

+ +
+
+
+
+

Identificador único (utilizado para evitar transferências duplicadas)

+ +
+
+
+
+

Tags opcionais para a transferências (separadas por vírgula)

+ +
+
+
+
+

Entre com o arquivo da chave privada.

+
+
+ + +
+
+
+
+
+
+

Digite sua senha

+ +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/sdkSendTransaction.js b/sdkSendTransaction.js new file mode 100644 index 0000000..c44142e --- /dev/null +++ b/sdkSendTransaction.js @@ -0,0 +1,29 @@ +function sendTransactionDialog() { + var html = HtmlService.createHtmlOutputFromFile('FormSendTransaction'); + SpreadsheetApp.getUi() + .showModalDialog(html, 'Envio de Transferência Interna'); +} + +function executeTransaction(password, privateKeyPem) +{ + verifyPassword(password); +} + +function sendTransaction(privateKeyPem) +{ + let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência Interna'); + + formatHeader(sheet); + + for(let i=11; i<=sheet.getLastRow(); i++) { + let transaction = { + receiverId: sheet.getRange('A' + i.toString()).getValue(), + amount: parseInt(100*sheet.getRange('B' + i.toString()).getValue(), 10), + description: sheet.getRange('C' + i.toString()).getValue(), + externalId: sheet.getRange('D' + i.toString()).getValue(), + tags: sheet.getRange('E' + i.toString()).getValue().split(",") + }; + + } + +} \ No newline at end of file diff --git a/utilsBase.js b/utilsBase.js index 46828f1..b368a9f 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -17,7 +17,8 @@ function getHeaderColumns(sheet){ 'Consulta de Transferência': ["Data de Criação", "Id Transferência", "Valor", "Status", "Nome", "CPF/CNPJ", "Código do Banco", "Agência", "Número da Conta", "Ids de Transação (Saída, Estorno)"], 'Pagamento de Boletos': ["Linha Digitável ou Código de Barras", "CPF/CPNJ do Beneficiário", "Data de Agendamento", "Descrição", "Tags"], 'Consulta de Clientes': ["Id do Cliente", "Nome", "CPF/CNPJ", "E-Mail", "Telefone", "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP", "Tags"], - 'Emissão de Boletos': ["Id do Cliente", "Valor", "Data de Vencimento", "Multa", "Juros ao Mês", "Dias para Baixa Automática", "Desconto", "Data Limite do Desconto", "Descrição 1", "Valor 1", "Descrição 2", "Valor 2", "Descrição 3", "Valor 3", "Tags"] + 'Emissão de Boletos': ["Id do Cliente", "Valor", "Data de Vencimento", "Multa", "Juros ao Mês", "Dias para Baixa Automática", "Desconto", "Data Limite do Desconto", "Descrição 1", "Valor 1", "Descrição 2", "Valor 2", "Descrição 3", "Valor 3", "Tags"], + 'Transferência Interna': ["Id do Recebedor", "Valor", "Descrição", "Identificador externo único", "Tags"] }[sheet.getName()]; } diff --git a/utilsNavigation.js b/utilsNavigation.js index ebf9e8d..d297bd5 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -43,4 +43,9 @@ function goViewCustomers() function goCreateBoleto() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Emissão de Boletos')); +} + +function goTransaction() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência Interna')); } \ No newline at end of file From 9653ed5fa1f6a1a28d685f6ba64eb54cb23ac9a9 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 8 Sep 2020 16:04:59 -0300 Subject: [PATCH 16/27] Finish sdkSendTransfer --- FormSendTransaction.html | 22 +++++++++++++--------- sdkSendTransaction.js | 30 +++++++++++++++--------------- utilsRequest.js | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/FormSendTransaction.html b/FormSendTransaction.html index c19c296..756cb15 100644 --- a/FormSendTransaction.html +++ b/FormSendTransaction.html @@ -136,8 +136,12 @@ function send() { let receiverId = document.getElementById("receiverId").value; - + let amount = document.getElementById("amount").value; + let description = document.getElementById("description").value; + let externalId = document.getElementById("externalId").value; + let tags = document.getElementById("tags").value; let password = document.getElementById("password").value; + if(privateKey === "") { let message = "Por favor, insira um arquivo válido."; @@ -148,19 +152,19 @@ return; } else{ - // google.script.run.withSuccessHandler(pkCheckSuccess(password, privateKey, description, externalId, tags)) - // .withFailureHandler(pkCheckFailure) - // .checkPrivateKey(privateKey); + google.script.run.withSuccessHandler(pkCheckSuccess(password, privateKey, receiverId, amount, description, externalId, tags)) + .withFailureHandler(pkCheckFailure) + .checkPrivateKey(privateKey); } } -function pkCheckSuccess(password, privateKey, description, externalId, tags) +function pkCheckSuccess(password, privateKey, receiverId, amount, description, externalId, tags) { - // startLoading(); - // google.script.run.withSuccessHandler(onSuccess) - // .withFailureHandler(onFailure) - // .executeTransfer(password, privateKey, description, externalId, tags); + startLoading(); + google.script.run.withSuccessHandler(onSuccess) + .withFailureHandler(onFailure) + .executeTransaction(password, privateKey, receiverId, amount, description, externalId, tags); } function pkCheckFailure() diff --git a/sdkSendTransaction.js b/sdkSendTransaction.js index c44142e..681cec2 100644 --- a/sdkSendTransaction.js +++ b/sdkSendTransaction.js @@ -4,26 +4,26 @@ function sendTransactionDialog() { .showModalDialog(html, 'Envio de Transferência Interna'); } -function executeTransaction(password, privateKeyPem) +function executeTransaction(password, privateKeyPem, receiverId, amount, description, externalId, tags) { verifyPassword(password); + sendTransaction(privateKeyPem, receiverId, amount, description, externalId, tags); } -function sendTransaction(privateKeyPem) +function sendTransaction(privateKeyPem, receiverId, amount, description, externalId, tags) { - let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência Interna'); + + let transaction = { + receiverId: receiverId, + amount: parseInt(100*amount, 10), + description: description, + externalId: externalId, + tags: tags.split(",") + }; - formatHeader(sheet); - - for(let i=11; i<=sheet.getLastRow(); i++) { - let transaction = { - receiverId: sheet.getRange('A' + i.toString()).getValue(), - amount: parseInt(100*sheet.getRange('B' + i.toString()).getValue(), 10), - description: sheet.getRange('C' + i.toString()).getValue(), - externalId: sheet.getRange('D' + i.toString()).getValue(), - tags: sheet.getRange('E' + i.toString()).getValue().split(",") - }; - - } + let payload = { + transaction: transaction + }; + json = JSON.parse(fetch("/bank/transaction", method = 'POST', payload, null, 'v1', null, privateKeyPem).content); } \ No newline at end of file diff --git a/utilsRequest.js b/utilsRequest.js index fe57a23..c6683fe 100644 --- a/utilsRequest.js +++ b/utilsRequest.js @@ -40,7 +40,7 @@ function fetch(path, method='GET', payload=null, query=null, version='v1', envir } options['headers'] = { 'Access-Token': user.accessToken, - 'User-Agent': 'GoogleSheets-SDK-0.1.0', + 'User-Agent': 'GoogleSheets-SDK-0.3.1', 'Accept-Language': 'pt-BR', 'Content-Type': 'application/json' }; From 95e3b0c988776db930eb619eeaa14adfe502e693 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 8 Sep 2020 18:25:05 -0300 Subject: [PATCH 17/27] Start implementation of sdkViewChargeEvent --- FormViewChargeEvent.html | 128 +++++++++++++++++++++++++++++++++++++++ sdkViewCharge.js | 2 +- sdkViewChargeEvent.js | 22 +++++++ utilsBase.js | 4 +- utilsNavigation.js | 5 ++ 5 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 FormViewChargeEvent.html create mode 100644 sdkViewChargeEvent.js diff --git a/FormViewChargeEvent.html b/FormViewChargeEvent.html new file mode 100644 index 0000000..272835e --- /dev/null +++ b/FormViewChargeEvent.html @@ -0,0 +1,128 @@ + + + + + + + + + + + + +
+
+
Consulta por Data do Evento
+
+ + +
+ + +
+
+
+
Consulta por Evento
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+ +
+
+ +
+ + + + \ No newline at end of file diff --git a/sdkViewCharge.js b/sdkViewCharge.js index acf1e45..f8e363e 100644 --- a/sdkViewCharge.js +++ b/sdkViewCharge.js @@ -5,7 +5,7 @@ function ViewCharge(after, before, status) { let cursor = ""; let query = {}; if (after){ - query["after"] = after + query["after"] = after; } if (before){ query["before"] = before; diff --git a/sdkViewChargeEvent.js b/sdkViewChargeEvent.js new file mode 100644 index 0000000..a81fba4 --- /dev/null +++ b/sdkViewChargeEvent.js @@ -0,0 +1,22 @@ +function selectChargeEventDialog() +{ + let html = HtmlService.createHtmlOutputFromFile('FormViewChargeEvent'); + SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp. + .showModalDialog(html, 'Histórico de Boletos Emitidos') +} + +function viewChargeEvents(after, before, eventOption) +{ + let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Histórico de Boletos Emitidos'); + let i = 10; + let cursor = ""; + let query = {}; + if(after) { + query["after"] = after; + } + if(before) { + query["before"] = before; + } + + query["events"] = eventOption; +} \ No newline at end of file diff --git a/utilsBase.js b/utilsBase.js index b368a9f..0a037bd 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -18,7 +18,9 @@ function getHeaderColumns(sheet){ 'Pagamento de Boletos': ["Linha Digitável ou Código de Barras", "CPF/CPNJ do Beneficiário", "Data de Agendamento", "Descrição", "Tags"], 'Consulta de Clientes': ["Id do Cliente", "Nome", "CPF/CNPJ", "E-Mail", "Telefone", "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP", "Tags"], 'Emissão de Boletos': ["Id do Cliente", "Valor", "Data de Vencimento", "Multa", "Juros ao Mês", "Dias para Baixa Automática", "Desconto", "Data Limite do Desconto", "Descrição 1", "Valor 1", "Descrição 2", "Valor 2", "Descrição 3", "Valor 3", "Tags"], - 'Transferência Interna': ["Id do Recebedor", "Valor", "Descrição", "Identificador externo único", "Tags"] + 'Transferência Interna': ["Id do Recebedor", "Valor", "Descrição", "Identificador externo único", "Tags"], + 'Histórico de Boletos Emitidos': ["Data do Evento", "Evento", "Nome", "CPF/CPNJ", "Valor", "Valor de Emissão", "Desconto", "Multa", "Juros", "Data de Emissão", "Vencimento", "Linha Digitável", "Id do Boleto", "Tarifa", "Tags", "Link PDF", + "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP"] }[sheet.getName()]; } diff --git a/utilsNavigation.js b/utilsNavigation.js index d297bd5..01e00f4 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -48,4 +48,9 @@ function goCreateBoleto() function goTransaction() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência Interna')); +} + +function goViewChargeEvent() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Histórico de Boletos Emitidos')); } \ No newline at end of file From e8fa8044b4227f3d1afb03faf8e8ce4a32538d3e Mon Sep 17 00:00:00 2001 From: LucasSte Date: Wed, 9 Sep 2020 18:07:26 -0300 Subject: [PATCH 18/27] Implement ViewChargeEvent --- FormViewChargeEvent.html | 43 +++++++++++--- sdkViewChargeEvent.js | 122 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 9 deletions(-) diff --git a/FormViewChargeEvent.html b/FormViewChargeEvent.html index 272835e..5881958 100644 --- a/FormViewChargeEvent.html +++ b/FormViewChargeEvent.html @@ -78,6 +78,15 @@
Consulta por Evento
function hideAlert() { $("#alert").hide(); } + + function showMessage(message) +{ + hideAlert(); + $("#alert").show(); + var alertMessage = document.getElementById("alert-message"); + alertMessage.innerHTML = message; + window.scrollTo(0,0); +} function onSuccess() { stopLoading(); @@ -85,12 +94,28 @@
Consulta por Evento
} function onFailure(error) { - stopLoading(); - let message = JSON.parse(error["message"])["message"]; - $("#alert").show(); - - var alertMessage = document.getElementById("alert-message"); - alertMessage.innerHTML = message + stopLoading(); + try{ + let parsed = JSON.parse(error.message); + let message = parsed["message"]; + if("errors" in parsed) + { + for(let suberror of parsed["errors"]) { + let suberrorMessage = suberror["message"]; + let splitMessage = suberrorMessage.split(":"); + splitMessage[0] = splitMessage[0].replace("Element ", ""); + splitMessage[0] = "Linha " + (11 - (-splitMessage[0])); + let newMessage = splitMessage.join(":"); + message += "
" + newMessage; + } + } + showMessage(message); + + } catch(e) { + //console.log(e.message); + console.log(error); + console.log(error.message); + } } function save() { @@ -109,9 +134,9 @@
Consulta por Evento
} startLoading(); - // google.script.run.withSuccessHandler(onSuccess) - // .withFailureHandler(onFailure) - // .ViewCharge(startDate, endDate, status); + google.script.run.withSuccessHandler(onSuccess) + .withFailureHandler(onFailure) + .viewChargeEvents(startDate, endDate, option); } function startLoading() { diff --git a/sdkViewChargeEvent.js b/sdkViewChargeEvent.js index a81fba4..c25ae73 100644 --- a/sdkViewChargeEvent.js +++ b/sdkViewChargeEvent.js @@ -19,4 +19,126 @@ function viewChargeEvents(after, before, eventOption) } query["events"] = eventOption; + + clearSheet(sheet); + formatHeader(sheet); + + let user = new getDefaultUser(); + let hostname = getHostname(user.environment.toLowerCase(), "v1"); + let zeroLogs = true; + do { + query["cursor"] = cursor; + json = JSON.parse(fetch("/charge/log", method = 'GET', null, query).content); + elementsList = json["logs"]; + cursor = json["cursor"]; + + let idsList = []; + let chargeIdLineAmountDict = {}; + for(let log of elementsList) + { + zeroLogs = false; + i +=1; + let charge = log["charge"]; + let pdfLink = '=HYPERLINK("' + hostname + "/charge/" + charge["id"] + '/pdf", "PDF")'; + let tags = charge["tags"]; + idsList.push(charge["id"]); + chargeIdLineAmountDict[charge["id"]] = [i, parseInt(charge["amount"])]; + sheet.getRange('A' + i.toString()).setValue(formatToLocalDatetime(log["created"])); + sheet.getRange('B' + i.toString()).setValue(eventEntoPt(log["event"])); + sheet.getRange('C' + i.toString()).setValue(charge["name"]); + sheet.getRange('D' + i.toString()).setValue(charge["taxId"]); + sheet.getRange('E' + i.toString()).setValue(stringToCurrency(charge["amount"])); + + sheet.getRange('J' + i.toString()).setValue(formatToLocalDatetime(charge["issueDate"])); + sheet.getRange('K' + i.toString()).setValue(formatToLocalDatetime(charge["dueDate"])); + sheet.getRange('L' + i.toString()).setValue(charge["barCode"]); + sheet.getRange('M' + i.toString()).setValue(charge["id"]); + sheet.getRange('N' + i.toString()).setValue(parseInt(charge["fee"]) / 100.0); + sheet.getRange('O' + i.toString()).setValue(tags.join(",")); + sheet.getRange('P' + i.toString()).setValue(pdfLink); + sheet.getRange('Q' + i.toString()).setValue(charge["streetLine1"]); + sheet.getRange('R' + i.toString()).setValue(charge["streetLine2"]); + sheet.getRange('S' + i.toString()).setValue(charge["district"]); + sheet.getRange('T' + i.toString()).setValue(charge["city"]); + sheet.getRange('U' + i.toString()).setValue(charge["stateCode"]); + sheet.getRange('V' + i.toString()).setValue(charge["zipCode"]); + } + if(idsList.length > 0) + { + getCreatedLogs(idsList, chargeIdLineAmountDict, sheet); + } + + } while(cursor); + if(zeroLogs) { + Browser.msgBox("Nenhum boleto encontrado para os critérios pesquisados."); + } +} + +function getCreatedLogs(idsList, chargeIdLineAmountDict, sheet) +{ + let cursor = ""; + let query = {}; + + query["events"] = "register"; + query["chargeIds"] = idsList.join(","); + + + do { + query["cursor"] = cursor; + json = JSON.parse(fetch("/charge/log", method='GET', null, query).content); + elementsList = json["logs"]; + cursor = json["cursor"]; + + for(let log of elementsList) + { + let charge = log["charge"]; + + let line = chargeIdLineAmountDict[charge["id"]][0]; + let amount = chargeIdLineAmountDict[charge["id"]][1] / 100.0; + let nominalAmount = parseInt(charge["amount"]) / 100.0; + let deltaAmount = amount - nominalAmount; + sheet.getRange('F' + line.toString()).setValue(nominalAmount); + + if(deltaAmount < 0) { + sheet.getRange('G' + line.toString()).setValue(deltaAmount); + } + else if(deltaAmount > 0) { + let fine = parseInt(charge["fine"]) * nominalAmount; + let interest = amount - fine - nominalAmount; + sheet.getRange('H' + line.toString()).setValue(fine); + sheet.getRange('I' + line.toString()).setValue(interest); + } + } + + } while(cursor); + +} + +function eventEntoPt(event) +{ + switch(event) + { + case "paid": + return "pago"; + case "bank": + return "creditado"; + case "register": + return "criado (pendente de registro)"; + case "registered": + return "registrado"; + case "overdue": + return "vencido"; + case "cancel": + return "em cancelamento"; + case "canceled": + return "cancelado"; + case "failed": + return "falha"; + case "unknown": + return "desconhecido"; + case "update": + return "em atualização"; + case "updated": + return "atualizado"; + } } \ No newline at end of file From 99940c74db1b48fe0524eb25c4de9ef4f01cffed Mon Sep 17 00:00:00 2001 From: LucasSte Date: Wed, 9 Sep 2020 19:19:15 -0300 Subject: [PATCH 19/27] Implement createCustomers --- sdkCreateBoleto.js | 8 ++++- sdkCreateCustomers.js | 68 +++++++++++++++++++++++++++++++++++++++++++ utilsBase.js | 3 +- utilsNavigation.js | 5 ++++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 sdkCreateCustomers.js diff --git a/sdkCreateBoleto.js b/sdkCreateBoleto.js index e127d1b..c15c47a 100644 --- a/sdkCreateBoleto.js +++ b/sdkCreateBoleto.js @@ -85,7 +85,13 @@ function createBoleto() { let message = "Boletos não emitidos. "; let parsed = JSON.parse(e); - message += parsed["message"]; + let message2 = parsed["message"]; + if(message2.includes("Element")) { + let splitMessage = message2.split(":"); + splitMessage[0] = splitMessage[0].replace("Element ", ""); + splitMessage[0] = "Linha " + (10 - (-splitMessage[0])); + message += splitMessage.join(":"); + } if("errors" in parsed) { for(let suberror of parsed["errors"]) diff --git a/sdkCreateCustomers.js b/sdkCreateCustomers.js new file mode 100644 index 0000000..3d9df26 --- /dev/null +++ b/sdkCreateCustomers.js @@ -0,0 +1,68 @@ + +function createCustomers() +{ + let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Cadastro de Clientes'); + let customers = []; + + formatHeader(sheet); + + for(let i=11; i<=sheet.getLastRow(); i++){ + + let address = { + streetLine1: sheet.getRange('E' + i.toString()).getValue(), + streetLine2: sheet.getRange('F' + i.toString()).getValue(), + district: sheet.getRange('G' + i.toString()).getValue(), + city: sheet.getRange('H' + i.toString()).getValue(), + stateCode: sheet.getRange('I' + i.toString()).getValue(), + zipCode: sheet.getRange('J' + i.toString()).getValue() + }; + + let tags = sheet.getRange('K' + i.toString()).getValue().split(","); + + let customer = { + name: sheet.getRange('A' + i.toString()).getValue(), + taxId: sheet.getRange('B' + i.toString()).getValue(), + email: sheet.getRange('C' + i.toString()).getValue(), + phone: sheet.getRange('D' + i.toString()).getValue(), + tags: tags, + address: address + }; + + customers.push(customer); + } + + let payload = { + customers: customers + }; + + try { + fetch("/charge/customer", method = 'POST', payload, null); + Browser.msgBox("Clientes cadastrados com sucesso!"); + } catch(e) { + let message = "Clientes não cadastrados. "; + let parsed = JSON.parse(e); + let message2 = parsed["message"]; + if(message2.includes("Element")) { + let splitMessage = message2.split(":"); + splitMessage[0] = splitMessage[0].replace("Element ", ""); + splitMessage[0] = "Linha " + (10 - (-splitMessage[0])); + message += splitMessage.join(":"); + } + + if("errors" in parsed) + { + for(let suberror of parsed["errors"]) + { + let suberrorMessage = suberror["message"]; + let splitMessage = suberrorMessage.split(":"); + splitMessage[0] = splitMessage[0].replace("Element ", ""); + splitMessage[0] = "Linha " + (10 - (-splitMessage[0])); + let newMessage = splitMessage.join(":"); + message += "\n" + newMessage; + } + } + Browser.msgBox(message); + + } + +} \ No newline at end of file diff --git a/utilsBase.js b/utilsBase.js index 0a037bd..f580f52 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -20,7 +20,8 @@ function getHeaderColumns(sheet){ 'Emissão de Boletos': ["Id do Cliente", "Valor", "Data de Vencimento", "Multa", "Juros ao Mês", "Dias para Baixa Automática", "Desconto", "Data Limite do Desconto", "Descrição 1", "Valor 1", "Descrição 2", "Valor 2", "Descrição 3", "Valor 3", "Tags"], 'Transferência Interna': ["Id do Recebedor", "Valor", "Descrição", "Identificador externo único", "Tags"], 'Histórico de Boletos Emitidos': ["Data do Evento", "Evento", "Nome", "CPF/CPNJ", "Valor", "Valor de Emissão", "Desconto", "Multa", "Juros", "Data de Emissão", "Vencimento", "Linha Digitável", "Id do Boleto", "Tarifa", "Tags", "Link PDF", - "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP"] + "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP"], + 'Cadastro de Clientes': ["Nome", "CPF/CNPJ", "E-Mail", "Telefone", "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP", "Tags"] }[sheet.getName()]; } diff --git a/utilsNavigation.js b/utilsNavigation.js index 01e00f4..b7a7863 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -53,4 +53,9 @@ function goTransaction() function goViewChargeEvent() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Histórico de Boletos Emitidos')); +} + +function goCreateCustomers() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Cadastro de Clientes')); } \ No newline at end of file From 11eccc07165e8ce718e627df54a12947fcdd9d74 Mon Sep 17 00:00:00 2001 From: LucasSte Date: Thu, 10 Sep 2020 19:09:27 -0300 Subject: [PATCH 20/27] Implement getBalance and center spinner position --- FormViewChargeEvent.html | 14 +++++++------- sdkGetBalance.js | 18 ++++++++++++++++++ utilsBase.js | 2 ++ 3 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 sdkGetBalance.js diff --git a/FormViewChargeEvent.html b/FormViewChargeEvent.html index 5881958..5efc833 100644 --- a/FormViewChargeEvent.html +++ b/FormViewChargeEvent.html @@ -54,14 +54,14 @@
Consulta por Evento

-
+
- -
- -
+ +
+ +
diff --git a/sdkGetBalance.js b/sdkGetBalance.js new file mode 100644 index 0000000..3686a35 --- /dev/null +++ b/sdkGetBalance.js @@ -0,0 +1,18 @@ + +function getBalance() { + let user = new getDefaultUser(); + try{ + let jsonData = JSON.parse(fetch("/bank/account/" + user.workspaceId, method = 'GET', null).content); + let balance = parseInt(jsonData["account"]["balance"]) / 100.0; + for(sheet of SpreadsheetApp.getActiveSpreadsheet().getSheets()) { + if(sheet.getSheetName().toLowerCase() != "credentials") { + sheet.getRange("A7").setValue("Saldo: R$ " + Number(balance).toLocaleString("PT")); + } + } + } + catch(e) + { + Browser.msgBox(e); + } + +} \ No newline at end of file diff --git a/utilsBase.js b/utilsBase.js index f580f52..214011a 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -37,6 +37,7 @@ function formatHeader(sheet) { function SetAllGreetings(){ user = new getDefaultUser(); + getBalance(); for (sheet of SpreadsheetApp.getActiveSpreadsheet().getSheets()) { if (sheet.getSheetName().toLowerCase() != "credentials") { DisplayGreeting(user, sheet); @@ -60,6 +61,7 @@ function clearGreeting(sheet) { sheet.getRange("A4").setValue(null); sheet.getRange("A5").setValue(null); sheet.getRange("A6").setValue(null); + sheet.getRange("A7").setValue(null); } } From 729ae894cda4b1a0d68bb042a2321060c1af8b7d Mon Sep 17 00:00:00 2001 From: LucasSte Date: Thu, 10 Sep 2020 19:23:46 -0300 Subject: [PATCH 21/27] Add DigitalSignature tab to Navigation --- utilsNavigation.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utilsNavigation.js b/utilsNavigation.js index b7a7863..b716ab4 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -58,4 +58,9 @@ function goViewChargeEvent() function goCreateCustomers() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Cadastro de Clientes')); +} + +function goDigitalSignature() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Assinatura Digital')); } \ No newline at end of file From b3d84da5d8d1a413f9ebe44ea5074c65b6eee159 Mon Sep 17 00:00:00 2001 From: LucasSte Date: Fri, 11 Sep 2020 09:35:51 -0300 Subject: [PATCH 22/27] Refactor front end --- FormCredentials.html | 6 +-- FormSelectTeam.html | 40 +++++++------- FormSendTransaction.html | 104 ++++++++++++++++++------------------- FormViewCharge.html | 59 ++++++++++----------- FormViewChargePayment.html | 54 +++++++++---------- FormViewStatement.html | 33 ++++++------ FormViewTransfer.html | 50 ++++++++---------- apiAuth.js | 2 +- sdkDigitalSignature.js | 19 +++++++ sdkSendTransaction.js | 2 +- sdkSendTransfer.js | 2 +- sdkViewChargeEvent.js | 2 +- 12 files changed, 186 insertions(+), 187 deletions(-) create mode 100644 sdkDigitalSignature.js diff --git a/FormCredentials.html b/FormCredentials.html index f5db2c7..e4d1d7b 100644 --- a/FormCredentials.html +++ b/FormCredentials.html @@ -16,8 +16,6 @@
-
-

Ambiente

@@ -55,9 +53,7 @@ -
-
-
+
diff --git a/FormSelectTeam.html b/FormSelectTeam.html index 8d25c78..cd186c8 100644 --- a/FormSelectTeam.html +++ b/FormSelectTeam.html @@ -15,27 +15,25 @@
-
-
-
-
-
- -
- -
-
-
-
- - -
- -
-
-
+
+
+
+
+ +
+ +
+
+
+
+
+ + +
+ +
diff --git a/FormSendTransaction.html b/FormSendTransaction.html index 756cb15..2b835b0 100644 --- a/FormSendTransaction.html +++ b/FormSendTransaction.html @@ -22,63 +22,63 @@
-
-
-

ID do numérico do Workspace de destino

- -
-
-
-

Valor a ser transferido

-
-
- R$ +
+
+
+

ID do numérico do Workspace de destino

+
- -
-
-
-
-

Descrição para a transferência (mínimo de dez caracteres)

- -
-
-
-
-

Identificador único (utilizado para evitar transferências duplicadas)

- -
-
-
-
-

Tags opcionais para a transferências (separadas por vírgula)

- + +
+

Valor a ser transferido

+
+
+ R$ +
+ +
+
+
+

Entre com o arquivo da chave privada.

+
+
+ + +
+
+
+
+

Identificador único (utilizado para evitar transferências duplicadas)

+ +
+ +
-
-
-
-

Entre com o arquivo da chave privada.

-
-
- - +
+
+

Descrição para a transferência (mínimo de dez caracteres)

+ +
+
+

Tags opcionais para a transferências (separadas por vírgula)

+
-
-
-
-
-
-

Digite sua senha

- -
- +
+

Digite sua senha

+ +
+ +
+
+ +
+
-
- -
+ +
diff --git a/FormViewCharge.html b/FormViewCharge.html index 10217dd..0701b81 100644 --- a/FormViewCharge.html +++ b/FormViewCharge.html @@ -16,37 +16,34 @@
-
-
-
-
- - - - -
-
- - -
-
- - -
- -
-
-
-
+
+
+ + + + +
+
+ + +
+
+ + +
+ +
+
+ diff --git a/FormViewChargePayment.html b/FormViewChargePayment.html index 4547e62..c975e8c 100644 --- a/FormViewChargePayment.html +++ b/FormViewChargePayment.html @@ -16,36 +16,32 @@
-
-
-
-
- - - - -
-
- - -
-
- - -
- -
+
+
+ + + +
-
+
+ + +
+
+ + +
+ +
diff --git a/FormViewStatement.html b/FormViewStatement.html index 7523564..1168ce9 100644 --- a/FormViewStatement.html +++ b/FormViewStatement.html @@ -16,25 +16,22 @@
-
-
-
-
- - - - -
-
- - -
- -
+
+
+ + +
+ + +
+
+ + +
+ -
+
diff --git a/FormViewTransfer.html b/FormViewTransfer.html index 9d3f5da..8042bc3 100644 --- a/FormViewTransfer.html +++ b/FormViewTransfer.html @@ -16,34 +16,30 @@
-
-
-
-
- - - - -
-
- - -
-
- - -
- -
+
+
+ + + +
-
+
+ + +
+
+ + +
+ +
diff --git a/apiAuth.js b/apiAuth.js index 7857bee..99cd397 100644 --- a/apiAuth.js +++ b/apiAuth.js @@ -59,7 +59,7 @@ function SaveCredentials(workspace, email, environment, accessToken, membername, } function signInDialog() { - var html = HtmlService.createHtmlOutputFromFile('FormCredentials'); + var html = HtmlService.createHtmlOutputFromFile('FormCredentials').setHeight(400); SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp. .showModalDialog(html, 'Dados de Acesso'); } diff --git a/sdkDigitalSignature.js b/sdkDigitalSignature.js new file mode 100644 index 0000000..b332d2b --- /dev/null +++ b/sdkDigitalSignature.js @@ -0,0 +1,19 @@ + +function openUrl( ){ + let url = "https://starkbank.com/br/faq/how-to-create-ecdsa-keys"; + var html = HtmlService.createHtmlOutput('' + +'Failed to open automatically. Click here to proceed.' + +'' + +'') + .setWidth( 90 ).setHeight( 1 ); + SpreadsheetApp.getUi().showModalDialog( html, "Abrindo ..." ); +} \ No newline at end of file diff --git a/sdkSendTransaction.js b/sdkSendTransaction.js index 681cec2..6cd0ff8 100644 --- a/sdkSendTransaction.js +++ b/sdkSendTransaction.js @@ -1,5 +1,5 @@ function sendTransactionDialog() { - var html = HtmlService.createHtmlOutputFromFile('FormSendTransaction'); + var html = HtmlService.createHtmlOutputFromFile('FormSendTransaction').setWidth(1000).setHeight(450); SpreadsheetApp.getUi() .showModalDialog(html, 'Envio de Transferência Interna'); } diff --git a/sdkSendTransfer.js b/sdkSendTransfer.js index e0c07a9..b4f02e4 100644 --- a/sdkSendTransfer.js +++ b/sdkSendTransfer.js @@ -1,5 +1,5 @@ function sendTransferDialog() { - var html = HtmlService.createHtmlOutputFromFile('FormSendTransfer'); + var html = HtmlService.createHtmlOutputFromFile('FormSendTransfer').setHeight(500); SpreadsheetApp.getUi() .showModalDialog(html, 'Envio de Transferência sem Aprovação'); } diff --git a/sdkViewChargeEvent.js b/sdkViewChargeEvent.js index c25ae73..417a4c5 100644 --- a/sdkViewChargeEvent.js +++ b/sdkViewChargeEvent.js @@ -1,6 +1,6 @@ function selectChargeEventDialog() { - let html = HtmlService.createHtmlOutputFromFile('FormViewChargeEvent'); + let html = HtmlService.createHtmlOutputFromFile('FormViewChargeEvent').setHeight(400); SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp. .showModalDialog(html, 'Histórico de Boletos Emitidos') } From 6c2337c775b542da749fd3ced71ff407a622896b Mon Sep 17 00:00:00 2001 From: LucasSte Date: Fri, 11 Sep 2020 12:30:55 -0300 Subject: [PATCH 23/27] Implement digital signature tab --- FormSetPrivateKey.html | 180 +++++++++++++++++++++++++++++++++++++++++ sdkDigitalSignature.js | 25 +++++- utilsRequest.js | 41 ++++++++++ 3 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 FormSetPrivateKey.html diff --git a/FormSetPrivateKey.html b/FormSetPrivateKey.html new file mode 100644 index 0000000..63871cc --- /dev/null +++ b/FormSetPrivateKey.html @@ -0,0 +1,180 @@ + + + + + + + + + + + + + +
+
+
+

Entre com o arquivo da chave pública.

+
+
+ + +
+
+
+
+
+

Token recebido no e-mail

+
+ +
+ +
+
+
+
+
+

Digite sua senha

+ +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/sdkDigitalSignature.js b/sdkDigitalSignature.js index b332d2b..5671faf 100644 --- a/sdkDigitalSignature.js +++ b/sdkDigitalSignature.js @@ -1,5 +1,5 @@ -function openUrl( ){ +function openKeysUrl( ){ let url = "https://starkbank.com/br/faq/how-to-create-ecdsa-keys"; var html = HtmlService.createHtmlOutput('' +'') - .setWidth( 90 ).setHeight( 1 ); - SpreadsheetApp.getUi().showModalDialog( html, "Abrindo ..." ); + .setWidth( 100 ).setHeight( 1 ); + SpreadsheetApp.getUi().showModalDialog( html, "Abrindo. Verifique o bloqueio de pop-up do navegador." ); +} + +function setPublicKeyDialog() +{ + let html = HtmlService.createHtmlOutputFromFile('FormSetPrivateKey').setHeight(400); + SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp. + .showModalDialog(html, 'Cadastro de chave pública'); +} + +function getEmailToken() +{ + json = JSON.parse(fetch("/auth/public-key/token", method = 'POST', null, null).content); + return; +} + +function registerPublicKey(password, token, publicKeyPem) +{ + verifyPassword(password); + sendPublicKey(token, publicKeyPem); } \ No newline at end of file diff --git a/utilsRequest.js b/utilsRequest.js index c6683fe..d915f11 100644 --- a/utilsRequest.js +++ b/utilsRequest.js @@ -140,4 +140,45 @@ function fetchMath(){ throw e; } return new Response(status, content); +} + +function sendPublicKey(token, publicKeyPem) +{ + let user = new getDefaultUser(); + let environment = user.environment.toLowerCase(); + let hostname = getHostname(environment, "v1"); + let url = hostname + "/auth/public-key"; + + let options = { + 'method': 'post', + 'muteHttpExceptions': true + }; + options['headers'] = { + 'Access-Token': user.accessToken, + 'User-Agent': 'GoogleSheets-SDK-0.3.1', + 'Accept-Language': 'pt-BR', + }; + + let pkFile = Utilities.newBlob(publicKeyPem, 'text/plain', 'publicKey.pem'); + let formData = { + 'workspaceId': user.workspaceId, + 'token': token, + 'publicKey': pkFile + }; + + options['payload'] = formData; + + let response = UrlFetchApp.fetch(url, options); + let content = response.getContentText(); + let status = response.getResponseCode(); + switch (status) { + case 200: + return new Response(status, content); + case 400: + case 404: + case 500: + throw JSON.stringify(JSON.parse(content)["error"]); + default: + throw e; + } } \ No newline at end of file From 7a9e1477aaa2409117a14b46a0c6ff73d668cff1 Mon Sep 17 00:00:00 2001 From: LucasSte Date: Mon, 14 Sep 2020 08:42:01 -0300 Subject: [PATCH 24/27] Add goHelp funcation to navigationUtils --- utilsNavigation.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utilsNavigation.js b/utilsNavigation.js index b716ab4..6747738 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -63,4 +63,9 @@ function goCreateCustomers() function goDigitalSignature() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Assinatura Digital')); +} + +function goHelp() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Ajuda')); } \ No newline at end of file From a3e3d36e52cf3c65ffcbe28ba5616d7096723048 Mon Sep 17 00:00:00 2001 From: LucasSte Date: Mon, 14 Sep 2020 09:02:04 -0300 Subject: [PATCH 25/27] Add MAINTAINERS.md --- MAINTAINERS.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 MAINTAINERS.md diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 0000000..d6a23d2 --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,16 @@ +To synchronize the Google AppScript with your computer, you use Google Clasp. It dependns on Node, whose version should be newer than 10.0. To install clasp, type the following command on terminal. +``` +npm install -g @google/clasp +``` + +If the installation is successful, login to your GSuite account, using ```clasp login```. + +Every Google AppScript has an ID, which is saved on ```.clasp.json```. This ID is associated with a Google AppScript, with which the whole code is sychronized. Creating a new Google Sheet will generate another ID and will not sync to the current code, unless the ID is updated on ```.clasp.json```. + +The file ```appscript.json``` saves the dependecies for the code. The only current dependency is the [ecdsa-gs](https://github.com/starkbank/ecdsa-google-sheets). + +These are some basic useful commands for clasp: + +* ```clasp clone ``` clones the script from the GSuit to your computer, like ```git clone```. +* ```clasp pull``` fetches all the files from the script on the GSuit, overwriting your local files. +* ```clasp push``` pushed your local files to the GSuit repository, overwriting the latter. \ No newline at end of file From 0cd761c42adba46f824e39072aca395887782180 Mon Sep 17 00:00:00 2001 From: LucasSte Date: Mon, 14 Sep 2020 09:03:22 -0300 Subject: [PATCH 26/27] Fix typo on MAINTAINERS.md --- MAINTAINERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index d6a23d2..aec884e 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -3,7 +3,7 @@ To synchronize the Google AppScript with your computer, you use Google Clasp. It npm install -g @google/clasp ``` -If the installation is successful, login to your GSuite account, using ```clasp login```. +If the installation was successful, login to your GSuite account, using ```clasp login```. Every Google AppScript has an ID, which is saved on ```.clasp.json```. This ID is associated with a Google AppScript, with which the whole code is sychronized. Creating a new Google Sheet will generate another ID and will not sync to the current code, unless the ID is updated on ```.clasp.json```. From 8ebb5bb6aefe3053134c06bfb1b013b4f94d9347 Mon Sep 17 00:00:00 2001 From: LucasSte Date: Mon, 14 Sep 2020 09:10:37 -0300 Subject: [PATCH 27/27] Fix typo on MAINTAINERS.md --- MAINTAINERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index aec884e..63e0f46 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -5,7 +5,7 @@ npm install -g @google/clasp If the installation was successful, login to your GSuite account, using ```clasp login```. -Every Google AppScript has an ID, which is saved on ```.clasp.json```. This ID is associated with a Google AppScript, with which the whole code is sychronized. Creating a new Google Sheet will generate another ID and will not sync to the current code, unless the ID is updated on ```.clasp.json```. +Every Google AppScript has an ID, which is saved on ```.clasp.json```. This ID is associated with a Google AppScript, with which the whole code is sychronized. Creating a new Google Sheet will generate another ID and will not sync with the current code, unless the ID is updated on ```.clasp.json```. The file ```appscript.json``` saves the dependecies for the code. The only current dependency is the [ecdsa-gs](https://github.com/starkbank/ecdsa-google-sheets).