diff --git a/FormCredentials.html b/FormCredentials.html index 5881f4a..e4d1d7b 100644 --- a/FormCredentials.html +++ b/FormCredentials.html @@ -11,11 +11,11 @@
-
-

Ambiente

@@ -53,9 +53,7 @@ -
-
-
+
@@ -77,6 +75,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/FormPayBoleto.html b/FormPayBoleto.html new file mode 100644 index 0000000..ffb5f97 --- /dev/null +++ b/FormPayBoleto.html @@ -0,0 +1,174 @@ + + + + + + + + + + + + + +
+
+
+

Entre com o arquivo da chave privada.

+
+
+ + +
+
+
+
+
+
+

Digite sua senha

+ +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/FormSelectTeam.html b/FormSelectTeam.html index 0660723..cd186c8 100644 --- a/FormSelectTeam.html +++ b/FormSelectTeam.html @@ -11,29 +11,29 @@ -
-
-
-
-
- -
- -
-
-
-
- - -
- -
-
-
+
+
+
+
+ +
+ +
+
+
+
+
+ + +
+ +
diff --git a/FormSendTransaction.html b/FormSendTransaction.html new file mode 100644 index 0000000..2b835b0 --- /dev/null +++ b/FormSendTransaction.html @@ -0,0 +1,221 @@ + + + + + + + + + + + + + +
+
+
+
+

ID do numérico do Workspace de destino

+ +
+ +
+

Valor a ser transferido

+
+
+ R$ +
+ +
+
+
+

Entre com o arquivo da chave privada.

+
+
+ + +
+
+
+
+

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

+ +
+ + +
+
+
+

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

+ +
+
+

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

+ +
+
+

Digite sua senha

+ +
+ +
+
+ +
+ +
+
+ + +
+ + + + \ No newline at end of file diff --git a/FormSendTransfer.html b/FormSendTransfer.html new file mode 100644 index 0000000..953ef94 --- /dev/null +++ b/FormSendTransfer.html @@ -0,0 +1,187 @@ + + + + + + + + + + + + + +
+
+
+

ExternalId - Identificador único para a transação

+ +
+
+
+
+

Descrição da transação

+ +
+
+
+
+

Entre com o arquivo da chave privada.

+
+
+ + +
+
+
+
+
+
+

Digite sua senha

+ +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file 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/FormViewCharge.html b/FormViewCharge.html index bbc96e2..0701b81 100644 --- a/FormViewCharge.html +++ b/FormViewCharge.html @@ -11,40 +11,39 @@
-
-
-
-
- - - - -
-
- - -
-
- - -
- -
-
-
-
+
+
+ + + + +
+
+ + +
+
+ + +
+ +
+
+ diff --git a/FormViewChargeEvent.html b/FormViewChargeEvent.html new file mode 100644 index 0000000..5efc833 --- /dev/null +++ b/FormViewChargeEvent.html @@ -0,0 +1,153 @@ + + + + + + + + + + + + +
+
+
Consulta por Data do Evento
+
+ + +
+ + +
+
+
+
Consulta por Evento
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+ +
+
+ +
+ + + + \ No newline at end of file diff --git a/FormViewChargePayment.html b/FormViewChargePayment.html index cef510f..c975e8c 100644 --- a/FormViewChargePayment.html +++ b/FormViewChargePayment.html @@ -11,39 +11,37 @@
-
-
-
-
- - - - -
-
- - -
-
- - -
- -
+
+
+ + + +
-
+
+ + +
+
+ + +
+ +
diff --git a/FormViewStatement.html b/FormViewStatement.html index 720f41a..1168ce9 100644 --- a/FormViewStatement.html +++ b/FormViewStatement.html @@ -11,28 +11,27 @@
-
-
-
-
- - - - -
-
- - -
- -
+
+
+ + +
+ + +
+
+ + +
+ -
+
diff --git a/FormViewTransfer.html b/FormViewTransfer.html index cdf7cc2..8042bc3 100644 --- a/FormViewTransfer.html +++ b/FormViewTransfer.html @@ -11,37 +11,35 @@
-
-
-
-
- - - - -
-
- - -
-
- - -
- -
+
+
+ + + +
-
+
+ + +
+
+ + +
+ +
diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 0000000..63e0f46 --- /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 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 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). + +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 diff --git a/apiAuth.js b/apiAuth.js index 0f76e78..99cd397 100644 --- a/apiAuth.js +++ b/apiAuth.js @@ -33,6 +33,18 @@ function getUserInputCredential(email, workspace, password, environment) { SaveCredentials(workspace, email, environment, accessToken, memberName, workspaceId); } +function verifyPassword(password) { + let user = new getDefaultUser(); + + payload = { + workspace: user.workspace, + email: user.email, + password: password, + platform: "api" + } + fetch("/auth/access-token", method = 'POST', payload, null, "v1", user.environment); +} + function SaveCredentials(workspace, email, environment, accessToken, membername, workspaceId) { let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Credentials'); sheet.getRange(1,2,8,1).clearContent(); @@ -47,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/apiUser.js b/apiUser.js index 1c8e104..5d54747 100644 --- a/apiUser.js +++ b/apiUser.js @@ -6,4 +6,4 @@ function getDefaultUser() { this.accessToken = sheet.getRange(4, 2).getValue(); this.name = sheet.getRange(5, 2).getValue(); this.workspaceId = sheet.getRange(6, 2).getValue(); -} +} \ No newline at end of file diff --git a/appsscript.json b/appsscript.json index 133c092..c00a426 100644 --- a/appsscript.json +++ b/appsscript.json @@ -1,6 +1,11 @@ { "timeZone": "America/Argentina/Buenos_Aires", "dependencies": { + "libraries": [{ + "userSymbol": "ecdsags", + "libraryId": "1jF-69QLp4biqnV6cg-mvzHIPBloc8MlZG1aBIZ05x6_FZVBojDTsvyLv", + "version": "1" + }] }, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8" diff --git a/sdkCreateBoleto.js b/sdkCreateBoleto.js new file mode 100644 index 0000000..c15c47a --- /dev/null +++ b/sdkCreateBoleto.js @@ -0,0 +1,109 @@ + +function createBoleto() +{ + let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Emissão de Boletos'); + let boletos = []; + + formatHeader(sheet); + + for(let i=11; i<=sheet.getLastRow(); i++) { + + let descriptions = []; + for(let j=0; j<3; j++) + { + 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(columnAmount + 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) + }; + + let dueDate = sheet.getRange('C' + i.toString()).getValue(); + if(dueDate.length > 0) + { + boleto["dueDate"] = formatDateToISO(dueDate); + } + let fine = new String(sheet.getRange('D' + i.toString()).getValue()); + if(fine.length > 0) + { + boleto["fine"] = parseFloat(fine); + } + let interest = new String(sheet.getRange('E' + i.toString()).getValue()); + if(interest.length > 0) + { + boleto["interest"] = parseFloat(interest); + } + let overdueLimit = new String(sheet.getRange('F' + i.toString()).getValue()); + if(overdueLimit.length > 0) + { + boleto["overdueLimit"] = parseInt(overdueLimit); + } + let discount = new String(sheet.getRange('G' + i.toString()).getValue()); + if(discount.length > 0) + { + boleto["discount"] = 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.length > 0) + { + boleto["tags"] = tags; + } + + boletos.push(boleto); + } + + let payload = { + charges: boletos + }; + + try{ + fetch("/charge", method = 'POST', payload, null); + Browser.msgBox("Boletos Emitidos"); + } catch(e) + { + let message = "Boletos não emitidos. "; + 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/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/sdkDigitalSignature.js b/sdkDigitalSignature.js new file mode 100644 index 0000000..5671faf --- /dev/null +++ b/sdkDigitalSignature.js @@ -0,0 +1,38 @@ + +function openKeysUrl( ){ + 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( 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/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/sdkPayBoleto.js b/sdkPayBoleto.js new file mode 100644 index 0000000..ec5714d --- /dev/null +++ b/sdkPayBoleto.js @@ -0,0 +1,49 @@ +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 = []; + + formatHeader(sheet); + + for(let i=11; i<=sheet.getLastRow(); i++) { + let paymentItem = { + taxId: sheet.getRange('B' + i.toString()).getValue(), + scheduled: formatDateToISO(sheet.getRange('C' + i.toString()).getValue()), + 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 diff --git a/sdkSendTransaction.js b/sdkSendTransaction.js new file mode 100644 index 0000000..6cd0ff8 --- /dev/null +++ b/sdkSendTransaction.js @@ -0,0 +1,29 @@ +function sendTransactionDialog() { + var html = HtmlService.createHtmlOutputFromFile('FormSendTransaction').setWidth(1000).setHeight(450); + SpreadsheetApp.getUi() + .showModalDialog(html, 'Envio de Transferência Interna'); +} + +function executeTransaction(password, privateKeyPem, receiverId, amount, description, externalId, tags) +{ + verifyPassword(password); + sendTransaction(privateKeyPem, receiverId, amount, description, externalId, tags); +} + +function sendTransaction(privateKeyPem, receiverId, amount, description, externalId, tags) +{ + + let transaction = { + receiverId: receiverId, + amount: parseInt(100*amount, 10), + description: description, + externalId: externalId, + tags: tags.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/sdkSendTransfer.js b/sdkSendTransfer.js new file mode 100644 index 0000000..b4f02e4 --- /dev/null +++ b/sdkSendTransfer.js @@ -0,0 +1,46 @@ +function sendTransferDialog() { + var html = HtmlService.createHtmlOutputFromFile('FormSendTransfer').setHeight(500); + SpreadsheetApp.getUi() + .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 + } + + json = JSON.parse(fetch("/transfer", method = 'POST', payload, null, 'v1', null, privateKeyPem).content); +} \ 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..417a4c5 --- /dev/null +++ b/sdkViewChargeEvent.js @@ -0,0 +1,144 @@ +function selectChargeEventDialog() +{ + let html = HtmlService.createHtmlOutputFromFile('FormViewChargeEvent').setHeight(400); + 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; + + 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 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 b50a66f..214011a 100644 --- a/utilsBase.js +++ b/utilsBase.js @@ -11,9 +11,17 @@ 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)"], + '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"], + '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"], + 'Cadastro de Clientes': ["Nome", "CPF/CNPJ", "E-Mail", "Telefone", "Logradouro", "Complemento", "Bairro", "Cidade", "Estado", "CEP", "Tags"] }[sheet.getName()]; } @@ -29,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); @@ -52,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); } } @@ -81,6 +91,17 @@ function clearSheet(sheet){ } } + +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 152ea0a..6747738 100644 --- a/utilsNavigation.js +++ b/utilsNavigation.js @@ -26,3 +26,46 @@ function goHomeSheet() { SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Principal')); } +function goSendTransferSheet() { + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência sem Aprovação')) +} + +function goPayBoletos() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pagamento de Boletos')); +} + +function goViewCustomers() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Consulta de Clientes')); +} + +function goCreateBoleto() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Emissão de Boletos')); +} + +function goTransaction() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transferência Interna')); +} + +function goViewChargeEvent() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Histórico de Boletos Emitidos')); +} + +function goCreateCustomers() +{ + SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Cadastro de Clientes')); +} + +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 diff --git a/utilsRequest.js b/utilsRequest.js index 3a31c6e..d915f11 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,22 @@ 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', + 'User-Agent': 'GoogleSheets-SDK-0.3.1', '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; + } + } + + let response = UrlFetchApp.fetch(url, options); let content = response.getContentText(); let status = response.getResponseCode(); @@ -131,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