Skip to content

Commit

Permalink
feat: Parse Pix transactions
Browse files Browse the repository at this point in the history
Based on #223
Closes: #223 #213
  • Loading branch information
andreroggeri committed Jun 4, 2021
1 parent 85cb39b commit faf1550
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 10 deletions.
11 changes: 8 additions & 3 deletions pynubank/nubank.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import calendar
import datetime
import re
import uuid
from typing import Tuple

Expand All @@ -10,6 +9,7 @@
from pynubank.utils.discovery import Discovery
from pynubank.utils.graphql import prepare_request_body
from pynubank.utils.http import HttpClient
from pynubank.utils.parsing import parse_float, parse_pix_transaction

PAYMENT_EVENT_TYPES = (
'TransferOutEvent',
Expand All @@ -20,7 +20,11 @@
'DebitPurchaseReversalEvent',
'BillPaymentEvent',
'DebitWithdrawalFeeEvent',
'DebitWithdrawalEvent'
'DebitWithdrawalEvent',
'PixTransferOutEvent',
'PixTransferInEvent',
'PixTransferOutReversalEvent',
'PixTransferFailedEvent',
)


Expand Down Expand Up @@ -157,6 +161,7 @@ def get_account_feed(self):

def get_account_statements(self):
feed = self.get_account_feed()
feed = map(parse_pix_transaction, feed)
return list(filter(lambda x: x['__typename'] in PAYMENT_EVENT_TYPES, feed))

def get_account_balance(self):
Expand All @@ -179,7 +184,7 @@ def get_account_investments_yield(self, date=datetime.datetime.now()) -> float:

value = data['data']['viewer']['productFeatures']['savings']['screens']['detailedBalance']['monthBalanceSection']['yieldSection']['semantics']['label']

return float(re.search(r'\d*,\d\d', value).group().replace(',', '.'))
return parse_float(value)

def create_boleto(self, amount: float) -> str:
customer_id_response = self._make_graphql_request('account_id')
Expand Down
28 changes: 28 additions & 0 deletions pynubank/utils/parsing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import re

TITLE_INFLOW_PIX = 'Transferência recebida'
TITLE_OUTFLOW_PIX = 'Transferência enviada'
TITLE_REVERSAL_PIX = 'Reembolso enviado'
TITLE_FAILED_PIX = 'Transferência falhou'

PIX_TRANSACTION_MAP = {
TITLE_INFLOW_PIX: 'PixTransferInEvent',
TITLE_OUTFLOW_PIX: 'PixTransferOutEvent',
TITLE_REVERSAL_PIX: 'PixTransferOutReversalEvent',
TITLE_FAILED_PIX: 'PixTransferFailedEvent',
}


def parse_float(value: str):
return float(re.search(r'(?:\d.)?\d+,\d*', value).group().replace('.', '').replace(',', '.'))


def parse_pix_transaction(transaction: dict) -> dict:
if transaction['__typename'] != 'GenericFeedEvent':
return transaction

if transaction['title'] in PIX_TRANSACTION_MAP.keys():
transaction['__typename'] = PIX_TRANSACTION_MAP[transaction['title']]
transaction['amount'] = parse_float(transaction['detail'])

return transaction
14 changes: 7 additions & 7 deletions tests/test_nubank_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,20 @@ def test_get_account_statements():

statements = nubank_client.get_account_statements()

assert len(statements) == 12
assert len(statements) == 23
assert statements[0]['id'] == 'e409e495-4a16-4bad-9ddb-5c447c84fdcb'
assert statements[0]['__typename'] == 'TransferOutEvent'
assert statements[0]['title'] == 'Transferência enviada'
assert statements[0]['detail'] == 'Waldisney da Silva - R$ 4.496,90'
assert statements[0]['postDate'] == '2021-04-14'
assert statements[0]['amount'] == 4496.9

assert statements[11]['id'] == 'a9f96774-37f2-431e-9e6f-a081defacf25'
assert statements[11]['__typename'] == 'BarcodePaymentEvent'
assert statements[11]['title'] == 'Pagamento efetuado'
assert statements[11]['detail'] == 'CONFIDENCE CORRETORA DE CAMBIO S A'
assert statements[11]['postDate'] == '2020-12-08'
assert statements[11]['amount'] == 4245.1
assert statements[22]['id'] == 'a9f96774-37f2-431e-9e6f-a081defacf25'
assert statements[22]['__typename'] == 'BarcodePaymentEvent'
assert statements[22]['title'] == 'Pagamento efetuado'
assert statements[22]['detail'] == 'CONFIDENCE CORRETORA DE CAMBIO S A'
assert statements[22]['postDate'] == '2020-12-08'
assert statements[22]['amount'] == 4245.1


def test_get_account_investments_details():
Expand Down
60 changes: 60 additions & 0 deletions tests/test_parsing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from pynubank.utils.parsing import parse_pix_transaction

base_transaction = {
"id": "12c77a49-21c2-427d-8662-beba354e8356",
"__typename": "GenericFeedEvent",
"title": "Transferência enviada",
"detail": "Waldisney da Silva\nR$ 3.668,40",
"postDate": "2021-03-24"
}


def test_should_do_nothing_with_transactions_that_arent_pix():
transaction = base_transaction.copy()
transaction['__typename'] = 'TransferInEvent'
transaction['amount'] = 3429

parsed = parse_pix_transaction(transaction)

assert parsed['__typename'] == transaction['__typename']
assert parsed['amount'] == transaction['amount']


def test_should_parse_inflow_pix_transaction():
transaction = base_transaction.copy()
transaction['title'] = 'Transferência recebida'

parsed = parse_pix_transaction(transaction)

assert parsed['__typename'] == 'PixTransferInEvent'
assert parsed['amount'] == 3668.40


def test_should_parse_outflow_pix_transaction():
transaction = base_transaction.copy()
transaction['title'] = 'Transferência enviada'

parsed = parse_pix_transaction(transaction)

assert parsed['__typename'] == 'PixTransferOutEvent'
assert parsed['amount'] == 3668.40


def test_should_parse_reversal_pix_transaction():
transaction = base_transaction.copy()
transaction['title'] = 'Reembolso enviado'

parsed = parse_pix_transaction(transaction)

assert parsed['__typename'] == 'PixTransferOutReversalEvent'
assert parsed['amount'] == 3668.40


def test_should_parse_failed_pix_transaction():
transaction = base_transaction.copy()
transaction['title'] = 'Transferência falhou'

parsed = parse_pix_transaction(transaction)

assert parsed['__typename'] == 'PixTransferFailedEvent'
assert parsed['amount'] == 3668.40

0 comments on commit faf1550

Please sign in to comment.