{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "insert_query = \"INSERT IGNORE INTO default.TRANSACTION (ID, TDATE, ACCOUNT_ID, MEMO, COUNTRY, OUTFLOW, INFLOW, OWNER_ID, INSTALLMENT_NR, INSTALLMENT_TT, BILL, CREATED, UPDATED) VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s );\"" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def find_owner(queried_name: str):\n", " from mysql.connector import connect, Error\n", "\n", " query = \"SELECT * FROM OWNER\"\n", " result = []\n", "\n", " try:\n", " with connect(\n", " host=\"127.0.0.1\",\n", " user=\"root\",\n", " password=\"pleasehashapasswordomg\",\n", " database=\"default\",\n", " ) as connection:\n", " print(\"[robopato] CONNECTED!\", connection)\n", " with connection.cursor() as cursor:\n", " cursor.execute(query)\n", " query_result = cursor.fetchall()\n", "\n", " for item in query_result:\n", " if item[1].lower() == queried_name:\n", " result.append(item[0])\n", " result.append(item[1])\n", " print(\"[robopato] \", result)\n", " print(\"[robopato] DONE!\")\n", " except Error as e:\n", " print(e)\n", " finally:\n", " connection.close()\n", "\n", " return result if result else None" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Tests\n", "# find_owner(\"daniel\")[0]" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def create_lists(file_name: str, bill: str):\n", " import re\n", "\n", " # Open the text file\n", " with open(file_name, \"r\", encoding=\"latin\") as file:\n", " # Read the contents of the file\n", " contents = file.readlines()\n", "\n", " # Define the regex patterns\n", " owner_pattern = r\"\\s\\d\\s?-\\s?([A-Z]+)\"\n", " line_pattern = r\"\\d{2}\\.\\d{2}\\.\\d{4}.{23}.{14}.{2}\\s*-?\\d*\\.?\\d+,\\d{2}\\s*\\d+,\\d{2}\"\n", " payment_pattern = (\n", " r\"\\d{2}\\.\\d{2}\\.\\d{4}PGTO.*200211(\\s*-?\\d*\\.?\\d+,\\d{2})(\\s*\\d+,\\d{2})\"\n", " )\n", " partial_invoice_line_pattern = (\n", " r\"\\d{2}\\/\\d{2}.{27}.{16}.{2}\\s+\\s*-?\\d*\\.?\\d+,\\d{2}\\s*\\d+,\\d{2}\"\n", " )\n", "\n", " # Lists\n", " current_list = None\n", " owner_list = []\n", " result = {}\n", "\n", " line_counter = 0\n", " isPartial = True\n", "\n", " # Find Owners\n", " for line in contents:\n", " line_counter = line_counter + 1\n", "\n", " found_owners = re.findall(owner_pattern, line)\n", " if found_owners:\n", " for owner_name in found_owners:\n", " print(owner_name)\n", " list_name = f\"list_{owner_name.lower()}\"\n", " owner_list.append(list_name)\n", " result[list_name] = {}\n", " result[list_name][\"owner_name\"] = owner_name\n", " result[list_name][\"owner_id\"] = find_owner(owner_name.lower())[0]\n", " result[list_name][\"bill\"] = bill\n", " print(\"[robopato] owner_name\", result[list_name][\"owner_name\"])\n", " print(\"[robopato] owner_id\", result[list_name][\"owner_id\"])\n", "\n", " print(\"[robopato] linhas: \", line_counter)\n", "\n", " # Treat and create transaction lists\n", " counter2 = 0\n", " for line in contents:\n", " counter2 = counter2 + 1\n", "\n", " if re.search(owner_pattern, line):\n", " found_owner = re.search(owner_pattern, line)\n", " print(line)\n", " print(\"found_owner: \", found_owner.group(1).lower())\n", " owner_list = f\"list_{found_owner.group(1).lower()}\"\n", " current_list = owner_list\n", " result[current_list][\"tlist\"] = []\n", "\n", " else:\n", " if re.match(payment_pattern, line):\n", " result[current_list][\"tlist\"].append(line)\n", " elif re.match(line_pattern, line) or re.match(\n", " partial_invoice_line_pattern, line\n", " ):\n", " result[current_list][\"tlist\"].append(line)\n", "\n", " # Check file pattern\n", " if current_list:\n", " sample = result[current_list][\"tlist\"][1]\n", " print(\"sample: \" + sample)\n", " if re.search(line_pattern, sample):\n", " isPartial = False\n", "\n", " for listObj in result:\n", " result[listObj][\"isPartial\"] = isPartial\n", "\n", " print(\"[robopato] create_lists: DONE\")\n", "\n", " return result" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Test\n", "# create_lists(\"./documents/OUROCARD_VISA_INFINITE-Mar_26.txt\", \"Mar-2026\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "def build_insert(input_dict: dict, account: int):\n", " from datetime import date, datetime\n", " from decimal import Decimal\n", " import re\n", " import hashlib\n", "\n", " insert_bulk = []\n", "\n", " # RegEx Patterns\n", " line_group_pattern = r\"(?P\\d{2})\\.(?P\\d{2})\\.(?P\\d{4})(?:(?P.+PARC (?P\\d+.)\\/(?P\\d+)\\s.{12})|(?P.{37}))(?P.{2})(?P\\s*-?\\d*\\.?\\d+,\\d{2})(?P\\s*\\d*\\.?\\d+,\\d{2})\"\n", " partial_invoice_group_pattern = r\"(?P\\d{2})\\/(?P\\d{2})(?:(?P.+PARC (?P\\d{2})\\/(?P\\d{2}).{15})|(?P.{43}))(?P.{2})(?P\\s+\\s*-?\\d*\\.?\\d+,\\d{2})(?P\\s*\\d+,\\d{2})\"\n", " payment_pattern = r\"(?P\\d{2})\\.(?P\\d{2})\\.(?P\\d{4})(?PPGTO DEBITO CONTA).*200211(?P\\s*-?\\d*\\.?\\d+,\\d{2})(?P\\s*\\d+,\\d{2})\"\n", "\n", " for key in input_dict:\n", " if input_dict[key][\"isPartial\"]:\n", " pattern_to_use = partial_invoice_group_pattern\n", " else:\n", " pattern_to_use = line_group_pattern\n", "\n", " for item in input_dict[key][\"tlist\"]:\n", " # check if it is an invoice payment\n", " matches = re.match(payment_pattern, item)\n", " if matches:\n", " tTdate = str(\n", " date(\n", " int(matches.group(\"year\")),\n", " int(matches.group(\"month\")),\n", " int(matches.group(\"day\")),\n", " )\n", " )\n", " tAccount = account\n", " tMemo = matches.group(\"memo\")\n", " tCountry = None\n", " tOutflow = \"0.00\"\n", " tInflow = (\n", " matches.group(\"inflow\")\n", " .strip()\n", " .replace(\".\", \"\")\n", " .replace(\",\", \".\")\n", " .replace(\"-\", \"\")\n", " )\n", " tOwner = input_dict[key][\"owner_id\"]\n", " tInstallmentNr = None\n", " tInstallmentTt = None\n", " tBill = input_dict[key][\"bill\"]\n", " tCreated = str(datetime.now(tz=None))\n", " tUpdated = None\n", " else:\n", " matches = re.match(pattern_to_use, item)\n", " tTdate = str(\n", " date(\n", " # partial files will not have the year data on transactions\n", " (\n", " int(matches.group(\"year\"))\n", " if pattern_to_use == line_group_pattern\n", " else datetime.now().year\n", " ),\n", " int(matches.group(\"month\")),\n", " int(matches.group(\"day\")),\n", " )\n", " )\n", "\n", " tAccount = account\n", "\n", " tMemo = (\n", " matches.group(\"p_memo\")\n", " if matches.group(\"p_memo\")\n", " else matches.group(\"memo\")\n", " )\n", " tInstallmentNr = (\n", " int(matches.group(\"p_nr\")) if matches.group(\"p_nr\") else None\n", " )\n", " tInstallmentTt = (\n", " int(matches.group(\"p_tt\")) if matches.group(\"p_tt\") else None\n", " )\n", "\n", " tCountry = matches.group(\"country\")\n", " tOutflow = (\n", " matches.group(\"outflow\").strip().replace(\".\", \"\").replace(\",\", \".\")\n", " )\n", " tInflow = (\n", " matches.group(\"inflow\").strip().replace(\".\", \"\").replace(\",\", \".\")\n", " )\n", " tOwner = input_dict[key][\"owner_id\"]\n", " tBill = input_dict[key][\"bill\"]\n", "\n", " tCreated = str(datetime.now(tz=None))\n", " tUpdated = None\n", "\n", " preHash = tTdate + tMemo + tOutflow + tInflow\n", " tId = hashlib.sha256(preHash.encode()).hexdigest()\n", "\n", " if matches.group(\"memo\") != \"Saldo Anterior\":\n", " insert_bulk.append(\n", " (\n", " tId,\n", " tTdate,\n", " tAccount,\n", " tMemo.strip(),\n", " tCountry,\n", " tOutflow,\n", " tInflow,\n", " tOwner,\n", " tInstallmentNr,\n", " tInstallmentTt,\n", " tBill,\n", " tCreated,\n", " tUpdated,\n", " )\n", " )\n", "\n", " return insert_bulk" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# Test\n", "# build_insert(\n", "# create_lists(\"./documents/OUROCARD_VISA_INFINITE-Mar_26.txt\", \"Mar-2026\"), 2\n", "# )" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def db_insert(insert_bulk: list[tuple]):\n", " from mysql.connector import connect, Error\n", "\n", " try:\n", " with connect(\n", " host=\"127.0.0.1\",\n", " user=\"root\",\n", " password=\"pleasehashapasswordomg\",\n", " database=\"default\",\n", " ) as connection:\n", " print(\"CONNECTED!\", connection)\n", " with connection.cursor() as cursor:\n", " cursor.executemany(insert_query, insert_bulk)\n", " connection.commit()\n", " print(\"DONE!\")\n", " except Error as e:\n", " print(e)\n", " finally:\n", " connection.close()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# Tests\n", "# db_insert(\n", "# build_insert(\n", "# create_lists(\"./documents/OUROCARD_VISA_INFINITE-Mar_26.txt\", \"Mar-2026\"), 2\n", "# )\n", "# )" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def executor():\n", "\n", " from pathlib import Path\n", "\n", " file_path = Path(\".\") / \"documents\"\n", "\n", " matched_files = file_path.glob(\"OUROCARD*.txt\")\n", "\n", " for file in matched_files:\n", " bill = file.name[:-4][23:]\n", " db_insert(build_insert(create_lists(file, bill), 2))\n", "\n", " print(\"EXECUTOR COMPLETED.\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 66\n", " 1-DANIEL O C \n", "\n", "found_owner: daniel\n", "sample: 08/08 CINEMARK BRASIL S A EC SAO PAULO BR 58,00 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 253\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 13.04.2025CINE PARK SHOPPING GUARA BR 112,50 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 248\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 04.04.2026GOG.com Warsaw PL 28,59 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 201\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 05.08.2025Steam SAO PAULO BR 118,24 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 230\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 01.12.2025AMAZONMKTPLC*KARINAALV SAO PAULO BR -54,27 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 214\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 19.01.2026CINEMARK BRASIL S.A EC SAO PAULO BR 41,04 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 186\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 19.12.2025AMAZONMKTPLC*ARTCLUBSH SAO PAULO BR -285,78 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 203\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 13.06.2025ECB SUDOESTE BRASILIA BR 45,00 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 205\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 22.06.2026UBER *ONE MEMBERSHIP UBSAO PAULO BR -1,93 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 210\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 31.05.2025CINEMARK BRASIL SAO PAULO BR 94,00 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 210\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 19.05.2026BURGER KING BRASILIA BR 68,70 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 235\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 20.04.2025CINEMARK BRASIL SAO PAULO BR 39,33 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 239\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 11.02.2026OBA HORTIFRUTI BRASILIA BR 142,23 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 212\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 15.10.2025GRUPO FARTURA DE HORTI BRASILIA BR 160,43 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 192\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 17.09.2025ZP *CANTINAGOODLANCHEV Brasilia BR 105,00 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 158\n", " 1-DANIEL O C \n", "\n", "found_owner: daniel\n", "sample: 15/07 VELOE*Daniel de O BARUERI BR 50,00 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "DANIEL\n", "[robopato] CONNECTED! \n", "[robopato] [1, 'Daniel']\n", "[robopato] DONE!\n", "[robopato] owner_name DANIEL\n", "[robopato] owner_id 1\n", "[robopato] linhas: 188\n", " 1 - DANIEL O CARVALHO \n", "\n", "found_owner: daniel\n", "sample: 14.08.2025ECB SUDOESTE BRASILIA BR 500,00 0,00\n", "\n", "[robopato] create_lists: DONE\n", "CONNECTED! \n", "DONE!\n", "EXECUTOR COMPLETED.\n" ] } ], "source": [ "executor()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.14.0" } }, "nbformat": 4, "nbformat_minor": 2 }