diff --git a/lib/OfxParser/Ofx.php b/lib/OfxParser/Ofx.php index c3d0b6e..b6bfb54 100644 --- a/lib/OfxParser/Ofx.php +++ b/lib/OfxParser/Ofx.php @@ -147,32 +147,47 @@ private function buildBankAccounts(SimpleXMLElement $xml) // Loop through the bank accounts $bankAccounts = []; foreach ($xml->BANKMSGSRSV1->STMTTRNRS as $accountStatement) { - $bankAccounts[] = $this->buildBankAccount($accountStatement); + foreach ($accountStatement->STMTRS as $statementResponse) { + $bankAccounts[] = $this->buildBankAccount($accountStatement->TRNUID, $statementResponse); + } } return $bankAccounts; } /** - * @param SimpleXMLElement $xml + * @param string $transactionUid + * @param SimpleXMLElement $statementResponse * @return BankAccount * @throws \Exception */ - private function buildBankAccount(SimpleXMLElement $xml) + private function buildBankAccount($transactionUid, SimpleXMLElement $statementResponse) { $bankAccount = new BankAccount(); - $bankAccount->transactionUid = $xml->TRNUID; - $bankAccount->agencyNumber = $xml->STMTRS->BANKACCTFROM->BRANCHID; - $bankAccount->accountNumber = $xml->STMTRS->BANKACCTFROM->ACCTID; - $bankAccount->routingNumber = $xml->STMTRS->BANKACCTFROM->BANKID; - $bankAccount->accountType = $xml->STMTRS->BANKACCTFROM->ACCTTYPE; - $bankAccount->balance = $xml->STMTRS->LEDGERBAL->BALAMT; - $bankAccount->balanceDate = $this->createDateTimeFromStr($xml->STMTRS->LEDGERBAL->DTASOF, true); + $bankAccount->transactionUid = $transactionUid; + $bankAccount->agencyNumber = $statementResponse->BANKACCTFROM->BRANCHID; + $bankAccount->accountNumber = $statementResponse->BANKACCTFROM->ACCTID; + $bankAccount->routingNumber = $statementResponse->BANKACCTFROM->BANKID; + $bankAccount->accountType = $statementResponse->BANKACCTFROM->ACCTTYPE; + $bankAccount->balance = $statementResponse->LEDGERBAL->BALAMT; + $bankAccount->balanceDate = $this->createDateTimeFromStr( + $statementResponse->LEDGERBAL->DTASOF, + true + ); $bankAccount->statement = new Statement(); - $bankAccount->statement->currency = $xml->STMTRS->CURDEF; - $bankAccount->statement->startDate = $this->createDateTimeFromStr($xml->STMTRS->BANKTRANLIST->DTSTART); - $bankAccount->statement->endDate = $this->createDateTimeFromStr($xml->STMTRS->BANKTRANLIST->DTEND); - $bankAccount->statement->transactions = $this->buildTransactions($xml->STMTRS->BANKTRANLIST->STMTTRN); + $bankAccount->statement->currency = $statementResponse->CURDEF; + + $bankAccount->statement->startDate = $this->createDateTimeFromStr( + $statementResponse->BANKTRANLIST->DTSTART + ); + + $bankAccount->statement->endDate = $this->createDateTimeFromStr( + $statementResponse->BANKTRANLIST->DTEND + ); + + $bankAccount->statement->transactions = $this->buildTransactions( + $statementResponse->BANKTRANLIST->STMTTRN + ); return $bankAccount; } @@ -264,6 +279,8 @@ private function buildStatus(SimpleXMLElement $xml) */ private function createDateTimeFromStr($dateString, $ignoreErrors = false) { + if((!isset($dateString) || trim($dateString) === '')) return null; + $regex = '/' . "(\d{4})(\d{2})(\d{2})?" // YYYYMMDD 1,2,3 . "(?:(\d{2})(\d{2})(\d{2}))?" // HHMMSS - optional 4,5,6 @@ -310,7 +327,7 @@ private function createDateTimeFromStr($dateString, $ignoreErrors = false) private function createAmountFromStr($amountString) { // Decimal mark style (UK/US): 000.00 or 0,000.00 - if (preg_match('/^-?([\d,]+)(\.?)([\d]{2})$/', $amountString) === 1) { + if (preg_match('/^(-|\+)?([\d,]+)(\.?)([\d]{2})$/', $amountString) === 1) { return (float)preg_replace( ['/([,]+)/', '/\.?([\d]{2})$/'], ['', '.$1'], @@ -319,7 +336,7 @@ private function createAmountFromStr($amountString) } // European style: 000,00 or 0.000,00 - if (preg_match('/^-?([\d\.]+,?[\d]{2})$/', $amountString) === 1) { + if (preg_match('/^(-|\+)?([\d\.]+,?[\d]{2})$/', $amountString) === 1) { return (float)preg_replace( ['/([\.]+)/', '/,?([\d]{2})$/'], ['', '.$1'], diff --git a/lib/OfxParser/Parser.php b/lib/OfxParser/Parser.php index 081c82a..4fec0a7 100644 --- a/lib/OfxParser/Parser.php +++ b/lib/OfxParser/Parser.php @@ -63,6 +63,10 @@ private function conditionallyAddNewlines($ofxContent) return str_replace('<', "\n<", $ofxContent); // add line breaks to allow XML to parse } + if (preg_match('/<.+>.*<.+>/', $ofxContent) === 1) { + return str_replace('<', "\n<", $ofxContent); // add line breaks to allow XML to parse + } + return $ofxContent; } @@ -98,7 +102,7 @@ private function closeUnclosedXmlTags($line) // Does not match: // Does not match: blah if (preg_match( - "/<([A-Za-z0-9.]+)>([\wà-úÀ-Ú0-9\.\-\_\+\, ;:\[\]\'\&\/\\\*\(\)\+\{\|\}\!\£\$\?=@€£#%±§~`]+)$/", + "/<([A-Za-z0-9.]+)>([\wà-úÀ-Ú0-9\.\-\_\+\, ;:\[\]\'\&\/\\\*\(\)\+\{\|\}\!\£\$\?=@€£#%±§~`\"]+)$/", trim($line), $matches )) { @@ -117,6 +121,8 @@ private function convertSgmlToXml($sgml) { $sgml = str_replace(["\r\n", "\r"], "\n", $sgml); + $sgml = preg_replace('/&(?!#?[a-z0-9]+;)/', '&', $sgml); + $lines = explode("\n", $sgml); $xml = ''; diff --git a/lib/OfxParser/Parserv2.php b/lib/OfxParser/Parserv2.php new file mode 100644 index 0000000..508fb41 --- /dev/null +++ b/lib/OfxParser/Parserv2.php @@ -0,0 +1,126 @@ + + * @author James Titcumb + * @author Oliver Lowe + */ +class Parserv2 +{ + /** + * Load an OFX file into this parser by way of a filename + * + * @param string $ofxFile A path that can be loaded with file_get_contents + * @return Ofx + * @throws \Exception + */ + public function loadFromFile($ofxFile) + { + if (!file_exists($ofxFile)) { + throw new \InvalidArgumentException("File '{$ofxFile}' could not be found"); + } + + return $this->loadFromString(file_get_contents($ofxFile)); + } + + /** + * Load an OFX by directly using the text content + * + * @param string $ofxContent + * @return Ofx + * @throws \Exception + */ + public function loadFromString($ofxContent) + { + $ofxContent = utf8_encode($ofxContent); + $xml = $this->xmlLoadString($ofxContent); + + return new Ofx($xml); + } + + /** + * Detect if the OFX file is on one line. If it is, add newlines automatically. + * + * @param string $ofxContent + * @return string + */ + private function conditionallyAddNewlines($ofxContent) + { + if (preg_match('/.*<\/OFX>/', $ofxContent) === 1) { + return str_replace('<', "\n<", $ofxContent); // add line breaks to allow XML to parse + } + + if (preg_match('/<.+>.*<.+>/', $ofxContent) === 1) { + return str_replace('<', "\n<", $ofxContent); // add line breaks to allow XML to parse + } + + return $ofxContent; + } + + /** + * Load an XML string without PHP errors - throws exception instead + * + * @param string $xmlString + * @throws \Exception + * @return \SimpleXMLElement + */ + private function xmlLoadString($xmlString) + { + libxml_clear_errors(); + libxml_use_internal_errors(true); + $xml = simplexml_load_string($xmlString); + + if ($errors = libxml_get_errors()) { + throw new \RuntimeException('Failed to parse OFX: ' . var_export($errors, true)); + } + + return $xml; + } + + /** + * Detect any unclosed XML tags - if they exist, close them + * + * @param string $line + * @return string + */ + private function closeUnclosedXmlTags($line) + { + // Matches: blah + // Does not match: + // Does not match: blah + if (preg_match( + "/<([A-Za-z0-9.]+)>([\wà-úÀ-Ú0-9\.\-\_\+\, ;:\[\]\'\&\/\\\*\(\)\+\{\|\}\!\£\$\?=@€£#%±§~`]+)$/", + trim($line), + $matches + )) { + return "<{$matches[1]}>{$matches[2]}"; + } + return $line; + } + + /** + * Convert an SGML to an XML string + * + * @param string $sgml + * @return string + */ + private function convertSgmlToXml($sgml) + { + $sgml = str_replace(["\r\n", "\r"], "\n", $sgml); + + $lines = explode("\n", $sgml); + + $xml = ''; + foreach ($lines as $line) { + $xml .= trim($this->closeUnclosedXmlTags($line)) . "\n"; + } + + return trim($xml); + } +} diff --git a/tests/OfxParser/OfxTest.php b/tests/OfxParser/OfxTest.php index 486f287..8691d97 100644 --- a/tests/OfxParser/OfxTest.php +++ b/tests/OfxParser/OfxTest.php @@ -38,6 +38,12 @@ public function amountConversionProvider() '1' => ['1', 1.0], '10' => ['10', 10.0], '100' => ['100', 1.0], // @todo this is weird behaviour, should not really expect this + '+1' => ['+1', 1.0], + '+10' => ['+10', 10.0], + '+1000.00' => ['+1000.00', 1000.0], + '+1000,00' => ['+1000,00', 1000.0], + '+1,000.00' => ['+1,000.00', 1000.0], + '+1.000,00' => ['+1.000,00', 1000.0], ]; } @@ -81,6 +87,11 @@ public function testCreateDateTimeFromOFXDateFormats() // Test YYYYMMDDHHMMSS.XXX $DateTimeFour = $method->invoke($Ofx, '20081005132200.124'); self::assertEquals($expectedDateTime->getTimestamp(), $DateTimeFour->getTimestamp()); + + // Test empty datetime + $DateTimeFour = $method->invoke($Ofx, ''); + self::assertEquals(null, $DateTimeFour); + } public function testBuildsSignOn() diff --git a/tests/OfxParser/ParserTest.php b/tests/OfxParser/ParserTest.php index 77d2f1e..20bcf5f 100644 --- a/tests/OfxParser/ParserTest.php +++ b/tests/OfxParser/ParserTest.php @@ -112,6 +112,18 @@ public function convertSgmlToXmlProvider() XXXXXXXXXXX CHECKING +HERE + ],[<< + bar & restaurant + bat + +HERE + , << +bar & restaurant +bat + HERE ], ]; @@ -163,8 +175,12 @@ public function loadFromStringProvider() 'ofxdata-oneline.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-oneline.ofx'], 'ofxdata-cmfr.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-cmfr.ofx'], 'ofxdata-bb.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-bb.ofx'], + 'ofxdata-bb-two-stmtrs.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-bb-two-stmtrs.ofx'], 'ofxdata-credit-card.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-credit-card.ofx'], 'ofxdata-bpbfc.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-bpbfc.ofx'], + 'ofxdata-memoWithQuotes.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-memoWithQuotes.ofx'], + 'ofxdata-emptyDateTime.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-emptyDateTime.ofx'], + 'ofxdata-memoWithAmpersand.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-memoWithAmpersand.ofx'], ]; } diff --git a/tests/fixtures/ofxdata-bb-two-stmtrs.ofx b/tests/fixtures/ofxdata-bb-two-stmtrs.ofx new file mode 100644 index 0000000..8775285 --- /dev/null +++ b/tests/fixtures/ofxdata-bb-two-stmtrs.ofx @@ -0,0 +1,357 @@ +OFXHEADER:100 +DATA:OFXSGML +VERSION:102 +SECURITY:NONE +ENCODING:USASCII +CHARSET:1252 +COMPRESSION:NONE +OLDFILEUID:NONE +NEWFILEUID:NONE + + + + + 0 + INFO + + 20170329 + POR + 20170329 + + Banco do Brasil S/A + 001 + + + + + + 0 + + 0 + INFO + + + BRL + + 001 + 455000-5 + CHECKING + + + 20170220 + 20170220 + + + 0.00 + 20170329 + + Banco do Brasil, esse parceiro é todo seu. + + + BRL + + 001 + 655000-2 + CHECKING + + + 20170224 + 20170329 + + DEP + 20170301 + 13318.36 + 2017030101331836 + 5322222 + TED-CRÉDITO EM CONTA + + + DEP + 20170301 + 413.29 + 20170301041329 + 5398076 + TED-CRÉDITO EM CONTA + + + DEP + 20170301 + 1.00 + 201703010100 + 6728440 + TED-CRÉDITO EM CONTA + + + DEP + 20170302 + 1657.34 + 201703020165734 + 7472895 + TED-CRÉDITO EM CONTA + + + DEP + 20170302 + 2299.00 + 201703020229900 + 74283522 + CRÉDITO SISTEMA CDA + + + DEP + 20170302 + 4000.00 + 201703020400000 + 74283531 + CRÉDITO SISTEMA CDA + + + DEP + 20170303 + 1580.04 + 201703030158004 + 74643016 + CRÉDITO SISTEMA CDA + + + DEP + 20170306 + 408.31 + 20170306040831 + 200005 + RECEBIMENTO FORNECEDOR + + + DEP + 20170306 + 106.43 + 20170306010643 + 7177022 + TED-CRÉDITO EM CONTA + + + DEBIT + 20170306 + -92.16 + 2017030619216 + 27238 + SEGURO VIDA EMPRESA FLEX + + + DEP + 20170308 + 138.79 + 20170308013879 + 443977 + DOC-FORNECEDOR/HONORÁRIOS + + + DEP + 20170308 + 408.72 + 20170308040872 + 9681298 + TED-PAG FORNECEDORES + + + DEP + 20170308 + 699.58 + 20170308069958 + 74699168 + CRÉDITO SISTEMA CDA + + + DEP + 20170309 + 5973.24 + 201703090597324 + 5741509 + TED-CRÉDITO EM CONTA + + + DEP + 20170313 + 75.62 + 2017031307562 + 9731 + DOC CRÉDITO EM CONTA + + + DEP + 20170313 + 100.94 + 20170313010094 + 9732 + DOC CRÉDITO EM CONTA + + + DEP + 20170313 + 395.64 + 20170313039564 + 9824 + DOC CRÉDITO EM CONTA + + + DEP + 20170313 + 39.30 + 2017031303930 + 318100 + DOC-FORNECEDOR/HONORÁRIOS + + + DEP + 20170313 + 1312.38 + 201703130131238 + 74744818 + CRÉDITO SISTEMA CDA + + + DEP + 20170313 + 1203.26 + 201703130120326 + 74744904 + CRÉDITO SISTEMA CDA + + + DEP + 20170313 + 1005.39 + 201703130100539 + 74744955 + CRÉDITO SISTEMA CDA + + + DEP + 20170313 + 16660.00 + 2017031301666000 + 00033703 + ORDEM BANCÁRIA + + + DEP + 20170316 + 2299.00 + 201703160229900 + 74554810 + CRÉDITO SISTEMA CDA + + + DEBIT + 20170317 + -41272.37 + 2017031714127237 + 31701 + IMPOSTOS + + + DEP + 20170320 + 337.05 + 20170320033705 + 200005 + RECEBIMENTO FORNECEDOR + + + DEP + 20170321 + 3568.96 + 201703210356896 + 58509 + TED-CRÉDITO EM CONTA + + + DEP + 20170322 + 473.68 + 20170322047368 + 571721 + DOC CRÉDITO EM CONTA + + + DEP + 20170322 + 3153.76 + 201703220315376 + 6995389 + TED-CRÉDITO EM CONTA + + + DEP + 20170322 + 4000.00 + 201703220400000 + 74554819 + CRÉDITO SISTEMA CDA + + + DEP + 20170323 + 2676.10 + 201703230267610 + 9397855 + TED-CRÉDITO EM CONTA + + + XFER + 20170323 + 4992.92 + 201703230499292 + 00044345 + TRANSFERÊNCIA AGENDADA + + + DEBIT + 20170324 + -37000.00 + 2017032413700000 + 32401 + TED TRANSF.ELETR.DISPONIV + + + DEP + 20170327 + 917.96 + 20170327091796 + 4329891 + TED-CRÉDITO EM CONTA + + + DEP + 20170327 + 413.29 + 20170327041329 + 4452039 + TED-CRÉDITO EM CONTA + + + DEP + 20170327 + 154.52 + 20170327015452 + 5171371 + TED-PAG FORNECEDORES + + + DEBIT + 20170327 + -68.00 + 2017032716800 + 01096659 + TARIFA PACOTE DE SERVIÇOS + + + + 4555.28 + 20170329 + + Banco do Brasil, esse parceiro é todo seu. + + + + \ No newline at end of file diff --git a/tests/fixtures/ofxdata-emptyDateTime.ofx b/tests/fixtures/ofxdata-emptyDateTime.ofx new file mode 100644 index 0000000..fe7e7a2 --- /dev/null +++ b/tests/fixtures/ofxdata-emptyDateTime.ofx @@ -0,0 +1,49 @@ +OFXHEADER:100 +DATA:OFXSGML +VERSION:102 +SECURITY:NONE +ENCODING:USASCII +CHARSET:1252 +COMPRESSION:NONE +OLDFILEUID:NONE +NEWFILEUID:NONE + + + + +0 +INFO + +20181217111357 +ENG + + + + +1 + +0 +INFO + + +AUD + + +CREDIT +20181214000000 +337.50 +140217 +TEST TEST TEST AAAA + + +CREDIT +20181213000000 +150.00 +126659 +TEST TEST TEST BBBB + + + + + + \ No newline at end of file diff --git a/tests/fixtures/ofxdata-memoWithAmpersand.ofx b/tests/fixtures/ofxdata-memoWithAmpersand.ofx new file mode 100644 index 0000000..09320e6 --- /dev/null +++ b/tests/fixtures/ofxdata-memoWithAmpersand.ofx @@ -0,0 +1,176 @@ +OFXHEADER:100 +DATA:OFXSGML +VERSION:102 +SECURITY:NONE +ENCODING:USASCII +CHARSET:1252 +COMPRESSION:NONE +OLDFILEUID:NONE +NEWFILEUID:NONE + + + + +0 +INFO + + +20181026000000[-3:GMT] +POR + + + + + +1001 + +0 +INFO + + + +BRL + +99999999-9999-9999-9999-999999999999 + + + +20180913000000[-3:GMT] +20181013000000[-3:GMT] + +DEBIT +20180913000000[-3:GMT] +-33.3 +5b4f6eea-9999-9999-9999-794a31c8f61b +Amazon.Com.Br Amazon & Cloud 3/3 + + + +DEBIT +20180913000000[-3:GMT] +-9.9 +5b62619e-9999-9999-9999-e26b2df210fc +Empiricus 3/12 + + + +DEBIT +20180913000000[-3:GMT] +-140 +5b4f3b92-9999-9999-9999-902a256f3470 +Funcern 3/4 + + + +DEBIT +20180913000000[-3:GMT] +-40 +5b2b9e42-9999-9999-9999-1742bdf860ad +Azul Linhas Aereas*Fef 4/4 + + + +DEBIT +20180917000000[-3:GMT] +-5.27 +5ba09990-9999-9999-9999-ebd979a2a758 +IOF de "Leupay.Eu" & Whoelse + + + +DEBIT +20180917000000[-3:GMT] +-82.54 +5ba09c73-9999-9999-9999-191cf5c75cb1 +Leupay.Eu + + + +DEBIT +20180918000000[-3:GMT] +-225 +5b9fe897-9999-9999-9999-8ef65fb1ec8f +Mercpago + + + +CREDIT +20180920000000[-3:GMT] +600 +5ba47b96-9999-9999-9999-d57a38a6507d +Pagamento recebido + + + +DEBIT +20180920000000[-3:GMT] +-12.2 +5ba2937e-9999-9999-9999-7f21ffede0af +Mundo Verde + + + +CREDIT +20180920000000[-3:GMT] +127.87 +5ba47b64-9999-9999-9999-4e784e26540d +Pagamento recebido + + + +CREDIT +20180920000000[-3:GMT] +400 +5ba47b9d-9999-9999-9999-3635c88dfb3f +Pagamento recebido + + + +DEBIT +20180921000000[-3:GMT] +-80.68 +5ba38bad-9999-9999-9999-354f59379d1d +Assai Ata + + + +DEBIT +20180922000000[-3:GMT] +-14.5 +5ba5599b-9999-9999-9999-986103e3cd9e +Pag*Marianadiasdebrit + + + +DEBIT +20180924000000[-3:GMT] +-9.88 +5ba66b2a-9999-9999-9999-2da061b5ad4d +Superfacil Atacado + + + +DEBIT +20181005000000[-3:GMT] +-4.84 +5bb8d7fa-9999-9999-9999-d9632e284d02 +IOF de "Leupay.Eu" + + + +DEBIT +20181005000000[-3:GMT] +-75.94 +5bb8d808-9999-9999-9999-dfa3886b11ab +Leupay.Eu + + + + +-734.05 +20181013000000[-3:GMT] + + + + + diff --git a/tests/fixtures/ofxdata-memoWithQuotes.ofx b/tests/fixtures/ofxdata-memoWithQuotes.ofx new file mode 100644 index 0000000..0b16682 --- /dev/null +++ b/tests/fixtures/ofxdata-memoWithQuotes.ofx @@ -0,0 +1,176 @@ +OFXHEADER:100 +DATA:OFXSGML +VERSION:102 +SECURITY:NONE +ENCODING:USASCII +CHARSET:1252 +COMPRESSION:NONE +OLDFILEUID:NONE +NEWFILEUID:NONE + + + + +0 +INFO + + +20181026000000[-3:GMT] +POR + + + + + +1001 + +0 +INFO + + + +BRL + +99999999-9999-9999-9999-999999999999 + + + +20180913000000[-3:GMT] +20181013000000[-3:GMT] + +DEBIT +20180913000000[-3:GMT] +-33.3 +5b4f6eea-9999-9999-9999-794a31c8f61b +Amazon.Com.Br Amazon S 3/3 + + + +DEBIT +20180913000000[-3:GMT] +-9.9 +5b62619e-9999-9999-9999-e26b2df210fc +Empiricus 3/12 + + + +DEBIT +20180913000000[-3:GMT] +-140 +5b4f3b92-9999-9999-9999-902a256f3470 +Funcern 3/4 + + + +DEBIT +20180913000000[-3:GMT] +-40 +5b2b9e42-9999-9999-9999-1742bdf860ad +Azul Linhas Aereas*Fef 4/4 + + + +DEBIT +20180917000000[-3:GMT] +-5.27 +5ba09990-9999-9999-9999-ebd979a2a758 +IOF de "Leupay.Eu" + + + +DEBIT +20180917000000[-3:GMT] +-82.54 +5ba09c73-9999-9999-9999-191cf5c75cb1 +Leupay.Eu + + + +DEBIT +20180918000000[-3:GMT] +-225 +5b9fe897-9999-9999-9999-8ef65fb1ec8f +Mercpago + + + +CREDIT +20180920000000[-3:GMT] +600 +5ba47b96-9999-9999-9999-d57a38a6507d +Pagamento recebido + + + +DEBIT +20180920000000[-3:GMT] +-12.2 +5ba2937e-9999-9999-9999-7f21ffede0af +Mundo Verde + + + +CREDIT +20180920000000[-3:GMT] +127.87 +5ba47b64-9999-9999-9999-4e784e26540d +Pagamento recebido + + + +CREDIT +20180920000000[-3:GMT] +400 +5ba47b9d-9999-9999-9999-3635c88dfb3f +Pagamento recebido + + + +DEBIT +20180921000000[-3:GMT] +-80.68 +5ba38bad-9999-9999-9999-354f59379d1d +Assai Ata + + + +DEBIT +20180922000000[-3:GMT] +-14.5 +5ba5599b-9999-9999-9999-986103e3cd9e +Pag*Marianadiasdebrit + + + +DEBIT +20180924000000[-3:GMT] +-9.88 +5ba66b2a-9999-9999-9999-2da061b5ad4d +Superfacil Atacado + + + +DEBIT +20181005000000[-3:GMT] +-4.84 +5bb8d7fa-9999-9999-9999-d9632e284d02 +IOF de "Leupay.Eu" + + + +DEBIT +20181005000000[-3:GMT] +-75.94 +5bb8d808-9999-9999-9999-dfa3886b11ab +Leupay.Eu + + + + +-734.05 +20181013000000[-3:GMT] + + + + +