├── budget ├── __init__.py ├── tests │ ├── __init__.py │ ├── chamber_of_deputies │ │ ├── __init__.py │ │ ├── test_text_file_parser.py │ │ ├── test_pdf.py │ │ └── test_amendment_parser.py │ └── fixtures │ │ ├── single_page.pdf │ │ ├── single_page.txt │ │ ├── multi_page.txt │ │ ├── multi_page.pdf │ │ └── amendment_attributes.csv └── chamber_of_deputies │ ├── __init__.py │ ├── pdf.py │ ├── text_file_parser.py │ └── amendment_parser.py ├── scraper ├── __init__.py ├── tests │ ├── __init__.py │ └── test_pipelines.py ├── legislative_amendments │ ├── __init__.py │ ├── spiders │ │ ├── __init__.py │ │ └── chamber_of_deputies.py │ ├── items.py │ ├── middlewares.py │ ├── settings.py │ └── pipelines.py └── scrapy.cfg ├── requirements.txt ├── .gitlab-ci.yml ├── LICENSE ├── .gitignore └── README.md /budget/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scraper/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /budget/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scraper/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /budget/chamber_of_deputies/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scraper/legislative_amendments/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /budget/tests/chamber_of_deputies/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas==0.20.3 2 | pyspark==2.2.0 3 | scrapy==1.4.0 4 | -------------------------------------------------------------------------------- /budget/tests/fixtures/single_page.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Irio/budget/HEAD/budget/tests/fixtures/single_page.pdf -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: python:3.6.2 2 | test: 3 | before_script: 4 | - pip install -r requirements.txt 5 | script: 6 | - python -m unittest 7 | -------------------------------------------------------------------------------- /scraper/legislative_amendments/spiders/__init__.py: -------------------------------------------------------------------------------- 1 | # This package will contain the spiders of your Scrapy project 2 | # 3 | # Please refer to the documentation for information on how to create and manage 4 | # your spiders. 5 | -------------------------------------------------------------------------------- /scraper/scrapy.cfg: -------------------------------------------------------------------------------- 1 | # Automatically created by: scrapy startproject 2 | # 3 | # For more information about the [deploy] section see: 4 | # https://scrapyd.readthedocs.org/en/latest/deploy.html 5 | 6 | [settings] 7 | default = legislative_amendments.settings 8 | 9 | [deploy] 10 | #url = http://localhost:6800/ 11 | project = legislative_amendments 12 | -------------------------------------------------------------------------------- /scraper/legislative_amendments/items.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define here the models for your scraped items 4 | # 5 | # See documentation in: 6 | # http://doc.scrapy.org/en/latest/topics/items.html 7 | 8 | import scrapy 9 | 10 | 11 | class ChamberOfDeputiesAmendment(scrapy.Item): 12 | _id = scrapy.Field() 13 | application_method_id = scrapy.Field() 14 | author = scrapy.Field() 15 | code = scrapy.Field() 16 | description = scrapy.Field() 17 | expenditure_group_id = scrapy.Field() 18 | page_number = scrapy.Field() 19 | party = scrapy.Field() 20 | pdfs = scrapy.Field() 21 | commitment_info_url = scrapy.Field() 22 | state = scrapy.Field() 23 | target_location = scrapy.Field() 24 | urls = scrapy.Field() 25 | value = scrapy.Field() 26 | year = scrapy.Field() 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Irio Irineu Musskopf Junior 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /budget/chamber_of_deputies/pdf.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | import glob 3 | import subprocess 4 | import sys 5 | 6 | from .text_file_parser import TextFileParser 7 | 8 | 9 | class PDF: 10 | """ 11 | Class to handle PDF files for amendments made by congresspeople from 12 | the Chamber of Deputies on the federal budget. 13 | """ 14 | 15 | def __init__(self, pathname): 16 | """ 17 | pathname: the path for the PDF file(s). It accepts Unix style pathname 18 | pattern expansion, like `/Documents/*.pdf`. 19 | """ 20 | self.pathname = pathname 21 | self.filenames = glob.glob(self.pathname) 22 | 23 | def extract_text(self): 24 | """ 25 | Create a .txt file for every .pdf in the pathname. 26 | """ 27 | if sys.platform != 'darwin': 28 | raise ( 29 | 'Platform not supported. ' 30 | 'Only macOS version of `pdftotext` has the expected behavior.' 31 | ) 32 | for filename in self.filenames: 33 | text_filename = filename.replace('.pdf', '.txt') 34 | command = 'pdftotext -table -enc "UTF-8" {} {}' 35 | command = command.format(filename, text_filename) 36 | subprocess.run(command, shell=True) 37 | 38 | def dataframe(self): 39 | pathname = self.pathname.replace('.pdf', '.txt') 40 | return TextFileParser(pathname).dataframe() 41 | -------------------------------------------------------------------------------- /budget/chamber_of_deputies/text_file_parser.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | import pandas as pd 3 | from pyspark import SparkContext 4 | import re 5 | 6 | from .amendment_parser import AmendmentParser 7 | 8 | 9 | SC = SparkContext() 10 | 11 | 12 | class TextFileParser(object): 13 | """ 14 | Class to read text version of PDFs and parse amendments from them. 15 | """ 16 | 17 | def __init__(self, pathname): 18 | """ 19 | pathname: the path for the text file(s). It accepts Unix style pathname 20 | pattern expansion, like `/Documents/*.txt`. 21 | """ 22 | self.pathname = pathname 23 | 24 | def attributes(self): 25 | """ 26 | Return a list of attributes for every amendment page. 27 | """ 28 | result = SC.textFile(self.pathname) \ 29 | .map(lambda line: line.strip()) \ 30 | .filter(lambda line: line != '') \ 31 | .flatMap(lambda line: re.split(r'\s{2,}', line)) \ 32 | .map(lambda line: '---' if line == 'CONGRESSO NACIONAL' else line) 33 | values = result.collect() 34 | return [list(g) 35 | for k, g in itertools.groupby(values, lambda x: x == '---') 36 | if not k] 37 | 38 | def dataframe(self): 39 | pages = [AmendmentParser(attr).parse_page() 40 | for attr in self.attributes()] 41 | data = pd.DataFrame(pages) 42 | data['file_generation_date'] = pd.to_datetime( 43 | data['file_generation_date'], dayfirst=True) 44 | return data 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /data 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | 58 | # Flask stuff: 59 | instance/ 60 | .webassets-cache 61 | 62 | # Scrapy stuff: 63 | .scrapy 64 | 65 | # Sphinx documentation 66 | docs/_build/ 67 | 68 | # PyBuilder 69 | target/ 70 | 71 | # Jupyter Notebook 72 | .ipynb_checkpoints 73 | 74 | # pyenv 75 | .python-version 76 | 77 | # celery beat schedule file 78 | celerybeat-schedule 79 | 80 | # SageMath parsed files 81 | *.sage.py 82 | 83 | # Environments 84 | .env 85 | .venv 86 | env/ 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Budget 2 | 3 | *Unveiling where the Brazilian Congress is targeting federal money.* 4 | 5 | ## Setup 6 | 7 | ```console 8 | $ brew install xpdf 9 | $ python -m unittest 10 | ``` 11 | 12 | ## Data collection 13 | 14 | Data comes directly from the [official Chamber of Deputies website](http://www2.camara.leg.br/orcamento-da-uniao/leis-orcamentarias/loa/ob_loa_consulta_emendas). 15 | 16 | ```console 17 | $ cd scraper 18 | $ scrapy crawl chamber_of_deputies -a year=2017 \ 19 | --output ../data/chamber_of_deputies_2017.json 20 | $ cd .. 21 | ``` 22 | 23 | And this is an ugly script to generate a single CSV from everything in this project, including both seacheable information and data available only in PDFs. Code to be included in the main codebase soon. Wanna help? Open an issue. 24 | 25 | ```python 26 | from budget.chamber_of_deputies.text_file_parser import TextFileParser 27 | import pandas as pd 28 | 29 | data = pd.DataFrame() 30 | for year in range(2009, 2018): 31 | subset = pd.read_json('data/chamber_of_deputies_{}.json'.format(year), 32 | orient='records') 33 | data = data.append(subset) 34 | 35 | parser = TextFileParser('data/full/*.txt') 36 | pdf_data = parser.dataframe() 37 | data['_id'] = data['_id'].str.replace(' ', '') 38 | data = data[['_id', 'commitment_info_url', 'urls']] 39 | df = pdf_data.merge(data, left_on='number', right_on='_id', how='left') 40 | df.drop_duplicates(['number', 'file_generation_date', 'author'], inplace=True) 41 | del(df['_id']) 42 | df['urls'] = df['urls'].apply(lambda x: isinstance(x, list) and x[0] or None) 43 | df = df[df['category'].notnull() & df['urls'].notnull()] 44 | df.rename(columns={'urls': 'url'}, inplace=True) 45 | df.to_csv('data/amendments.csv', index=False) 46 | ``` 47 | -------------------------------------------------------------------------------- /budget/tests/chamber_of_deputies/test_text_file_parser.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | import tempfile 3 | from unittest import TestCase 4 | from unittest.mock import patch 5 | 6 | import pandas as pd 7 | import pandas.api.types as ptypes 8 | 9 | from budget.chamber_of_deputies.text_file_parser import SC, TextFileParser 10 | 11 | 12 | class TestTextFileParser(TestCase): 13 | def setUp(self): 14 | path = 'budget/tests/fixtures/amendment_attributes.csv' 15 | self.attributes = pd.read_csv(path, dtype=str) 16 | 17 | def fixture_by_index(self, index): 18 | return [attr 19 | for attr in self.attributes.iloc[index].values.tolist() 20 | if not isinstance(attr, float)] 21 | 22 | def test_attributes_single_page(self): 23 | subject = TextFileParser('budget/tests/fixtures/single_page.txt') 24 | self.assertEqual([self.fixture_by_index(10)], 25 | subject.attributes()) 26 | 27 | def test_attributes_multi_page(self): 28 | subject = TextFileParser('budget/tests/fixtures/multi_page.txt') 29 | expected = [self.fixture_by_index(11), self.fixture_by_index(12)] 30 | self.assertEqual(expected, subject.attributes()) 31 | 32 | @patch('budget.chamber_of_deputies.text_file_parser.AmendmentParser') 33 | def test_dataframe(self, parser_mock): 34 | parser_mock.return_value.parse_page.return_value = { 35 | 'file_generation_date': '30/12/2016', 36 | 'author': '3841 - Jones Martins', 37 | 'number': '38410001', 38 | } 39 | subject = TextFileParser('budget/tests/fixtures/multi_page.txt') 40 | result = subject.dataframe() 41 | self.assertIsInstance(result, pd.DataFrame) 42 | self.assertEqual((2, 3), result.shape) 43 | self.assertTrue( 44 | ptypes.is_datetime64_dtype(result['file_generation_date'])) 45 | -------------------------------------------------------------------------------- /scraper/legislative_amendments/middlewares.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define here the models for your spider middleware 4 | # 5 | # See documentation in: 6 | # http://doc.scrapy.org/en/latest/topics/spider-middleware.html 7 | 8 | from scrapy import signals 9 | 10 | 11 | class LegislativeAmendmentsSpiderMiddleware(object): 12 | # Not all methods need to be defined. If a method is not defined, 13 | # scrapy acts as if the spider middleware does not modify the 14 | # passed objects. 15 | 16 | @classmethod 17 | def from_crawler(cls, crawler): 18 | # This method is used by Scrapy to create your spiders. 19 | s = cls() 20 | crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) 21 | return s 22 | 23 | def process_spider_input(self, response, spider): 24 | # Called for each response that goes through the spider 25 | # middleware and into the spider. 26 | 27 | # Should return None or raise an exception. 28 | return None 29 | 30 | def process_spider_output(self, response, result, spider): 31 | # Called with the results returned from the Spider, after 32 | # it has processed the response. 33 | 34 | # Must return an iterable of Request, dict or Item objects. 35 | for i in result: 36 | yield i 37 | 38 | def process_spider_exception(self, response, exception, spider): 39 | # Called when a spider or process_spider_input() method 40 | # (from other spider middleware) raises an exception. 41 | 42 | # Should return either None or an iterable of Response, dict 43 | # or Item objects. 44 | pass 45 | 46 | def process_start_requests(self, start_requests, spider): 47 | # Called with the start requests of the spider, and works 48 | # similarly to the process_spider_output() method, except 49 | # that it doesn’t have a response associated. 50 | 51 | # Must return only requests (not items). 52 | for r in start_requests: 53 | yield r 54 | 55 | def spider_opened(self, spider): 56 | spider.logger.info('Spider opened: %s' % spider.name) 57 | -------------------------------------------------------------------------------- /scraper/tests/test_pipelines.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | from unittest.mock import MagicMock 3 | 4 | from scraper.legislative_amendments.pipelines import TargetLocationPipeline 5 | 6 | 7 | class TestTargetLocationPipeline(TestCase): 8 | def setUp(self): 9 | self.subject = TargetLocationPipeline() 10 | 11 | def test_process_item(self): 12 | spider = MagicMock() 13 | 14 | def assert_location(location, description, code=''): 15 | item = {'code': code, 'description': description} 16 | result = self.subject.process_item(item, spider) 17 | self.assertEqual(location, item['target_location']) 18 | 19 | assert_location('Nacional', 20 | 'Estruturação e Modernização de Unidades de Saúde das Forças Armadas - Nacional') 21 | assert_location('Amazônia Legal', 22 | 'Regularização da Estrutura Fundiária na Área de Abrangência da Lei 11.952, de 2009 - Na Amazônia Legal') 23 | assert_location('Sul', 24 | 'Apoio à Manutenção de Unidades de Saúde - Na Região Sul') 25 | assert_location('Exterior', 26 | 'Reconstrução da Estação Antártica Comandante Ferraz - No Exterior') 27 | assert_location('AM', 28 | 'Apoio à Infraestrutura para a Educação Básica - Na Região Metropolitana de Macapá') 29 | assert_location('TO', 30 | 'Apoio a Projetos de Infraestrutura Turística - Região Metropolitana de Palmas - TO') 31 | assert_location('AM', 32 | 'Apoio à Política Nacional de Desenvolvimento Urbano - Na Região Metropolitana de Manaus - No Estado do Amazonas') 33 | assert_location('RS', 34 | 'Estruturação de Unidades de Atenção Especializada em Saúde - No Estado do Rio Grande do Sul') 35 | assert_location('DF', 36 | 'Promoção e Fomento à Cultura Brasileira - No Distrito Federal') 37 | assert_location('PE', 38 | 'Promoção e Fomento à Cultura Brasileira - Em Municípios do Estado de Pernambuco') 39 | assert_location('SP', 40 | 'Estruturação de Unidades de Atenção Especializada em Saúde - No Estado de São Paulo') 41 | assert_location('Norte', 42 | 'Apreciação de Causas na Justiça do Trabalho - Na 11ª Região da Justiça do Trabalho - AM, RR') 43 | assert_location('Norte', 44 | 'Apreciação de Causas na Justiça do Trabalho - Na 14ª Região da Justiça do Trabalho - AC, RO') 45 | assert_location('Porto Alegre - RS', 46 | 'Estruturação de Unidades de Atenção Especializada em Saúde - Irmandade da Santa Casa de Misericórdia de Porto Alegre - Porto Alegre - RS.') 47 | assert_location('Rio de Janeiro - RJ', 48 | 'Prestação de Serviços Médico-Hospitalares do Hospital das Forças Armadas - Aquisição de Ambulância UTI') 49 | assert_location('Agrestina - PE', 50 | 'Implantação e Modernização de Infraestrutura para Esporte Educacional, Recreativo e de Lazer - Ampliação e Reforma de Campo de Futebol', 51 | '27.812.2035.5450.7222') 52 | -------------------------------------------------------------------------------- /scraper/legislative_amendments/spiders/chamber_of_deputies.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import datetime 3 | import itertools 4 | import re 5 | 6 | import scrapy 7 | 8 | from legislative_amendments.items import ChamberOfDeputiesAmendment 9 | 10 | 11 | class ChamberOfDeputiesSpider(scrapy.Spider): 12 | name = 'chamber_of_deputies' 13 | allowed_domains = ['camara.gov.br', 'camara.leg.br'] 14 | start_urls = [ 15 | 'http://www2.camara.leg.br' 16 | '/orcamento-da-uniao/leis-orcamentarias/loa/ob_loa_consulta_emendas' 17 | ] 18 | UFS = ['AC', 'AL', 'AM', 'AP', 'BA', 'CE', 'DF', 'ES', 'GO', 'MA', 'MG', 19 | 'MS', 'MT', 'PA', 'PB', 'PE', 'PI', 'PR', 'RJ', 'RN', 'RO', 'RR', 20 | 'RS', 'SC', 'SE', 'SP', 'TO'] 21 | 22 | def __init__(self, year=None, *args, **kwargs): 23 | super(ChamberOfDeputiesSpider, self).__init__(*args, **kwargs) 24 | if year: 25 | self.year = year 26 | else: 27 | self.year = str(datetime.datetime.now().year) 28 | 29 | def start_requests(self): 30 | url = self.start_urls[0] 31 | form_data = { 32 | 'ano': self.year, 33 | 'autor': '', 34 | 'form.button.submit': 'Pesquisar', 35 | 'form.submitted': '1', 36 | 'localidade': '', 37 | 'momento': '39-10-99', # option named "Redação Final - Autógrafo" 38 | 'ordem': 'autor', 39 | 'orgao': '', 40 | 'partido': '', 41 | # 'uf': 'RS', 42 | } 43 | 44 | for uf in self.UFS: 45 | form_data['uf'] = uf 46 | yield scrapy.FormRequest(url, callback=self.parse, formdata=form_data) 47 | 48 | def parse(self, response): 49 | selector = '.tabela-padrao-bootstrap tr:not(:first-child)' 50 | elements = response.css(selector) 51 | for index in range(len(elements) // 2): 52 | header_node, info_node = elements[index * 2], elements[index * 2 + 1] 53 | yield self.parse_amendment(response, header_node, info_node) 54 | 55 | def parse_amendment(self, response, header_node, info_node): 56 | header_node = header_node.css('th::text')[0].extract().strip() 57 | author_info = header_node.split(' - ') 58 | assert len(author_info) == 2 59 | author_group = author_info[1].split('/') 60 | party = '/'.join(author_group[:-1]) 61 | party = None if 'S/PARTIDO' in party else party 62 | urls = info_node.css('a::attr(href)').extract() 63 | page_number = re.search(r'page=(\d+)', urls[0])[1] 64 | _id = ''.join(info_node.css('td:first-child span::text').extract()) 65 | about_node = info_node.css('td:nth-child(2) span::text').extract() 66 | description = ' - '.join(about_node[5:-1]) 67 | target_location = about_node[-1] 68 | expenditure_group_id = info_node.css('td:nth-child(3) span::text')[0].extract() 69 | application_method_id = info_node.css('td:nth-child(4) span::text')[0].extract() 70 | value = info_node.css('td:nth-child(5) span::text')[0].extract() 71 | 72 | return ChamberOfDeputiesAmendment({ 73 | '_id': _id, 74 | 'application_method_id': application_method_id, 75 | 'author': author_info[0], 76 | 'code': '.'.join(about_node[:5]), 77 | 'description': ' - '.join(about_node[5:7]), 78 | 'expenditure_group_id': expenditure_group_id, 79 | 'page_number': page_number, 80 | 'party': party, 81 | 'commitment_info_url': urls[1] if len(urls) > 1 else None, 82 | 'state': author_group[-1], 83 | 'urls': urls[0].split('#')[:1], 84 | 'value': float(value.replace('.', '').replace(',', '.')), 85 | 'year': self.year, 86 | }) 87 | -------------------------------------------------------------------------------- /scraper/legislative_amendments/settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Scrapy settings for legislative_amendments project 4 | # 5 | # For simplicity, this file contains only settings considered important or 6 | # commonly used. You can find more settings consulting the documentation: 7 | # 8 | # http://doc.scrapy.org/en/latest/topics/settings.html 9 | # http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html 10 | # http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html 11 | 12 | BOT_NAME = 'legislative_amendments' 13 | 14 | SPIDER_MODULES = ['legislative_amendments.spiders'] 15 | NEWSPIDER_MODULE = 'legislative_amendments.spiders' 16 | 17 | 18 | # Crawl responsibly by identifying yourself (and your website) on the user-agent 19 | #USER_AGENT = 'legislative_amendments (+http://www.yourdomain.com)' 20 | 21 | # Obey robots.txt rules 22 | ROBOTSTXT_OBEY = True 23 | 24 | # Configure maximum concurrent requests performed by Scrapy (default: 16) 25 | #CONCURRENT_REQUESTS = 32 26 | 27 | # Configure a delay for requests for the same website (default: 0) 28 | # See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay 29 | # See also autothrottle settings and docs 30 | #DOWNLOAD_DELAY = 3 31 | # The download delay setting will honor only one of: 32 | #CONCURRENT_REQUESTS_PER_DOMAIN = 16 33 | #CONCURRENT_REQUESTS_PER_IP = 16 34 | 35 | # Disable cookies (enabled by default) 36 | #COOKIES_ENABLED = False 37 | 38 | # Disable Telnet Console (enabled by default) 39 | #TELNETCONSOLE_ENABLED = False 40 | 41 | # Override the default request headers: 42 | # DEFAULT_REQUEST_HEADERS = { 43 | # 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 44 | # 'Accept-Language': 'en', 45 | #} 46 | 47 | # Enable or disable spider middlewares 48 | # See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html 49 | # SPIDER_MIDDLEWARES = { 50 | # 'legislative_amendments.middlewares.LegislativeAmendmentsSpiderMiddleware': 543, 51 | #} 52 | 53 | # Enable or disable downloader middlewares 54 | # See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html 55 | # DOWNLOADER_MIDDLEWARES = { 56 | # 'legislative_amendments.middlewares.MyCustomDownloaderMiddleware': 543, 57 | #} 58 | 59 | # Enable or disable extensions 60 | # See http://scrapy.readthedocs.org/en/latest/topics/extensions.html 61 | # EXTENSIONS = { 62 | # 'scrapy.extensions.telnet.TelnetConsole': None, 63 | #} 64 | 65 | # Configure item pipelines 66 | # See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html 67 | ITEM_PIPELINES = { 68 | 'scrapy.pipelines.files.FilesPipeline': 1, 69 | 'legislative_amendments.pipelines.TargetLocationPipeline': 300, 70 | } 71 | 72 | FILES_STORE = '../data' 73 | FILES_URLS_FIELD = 'urls' 74 | FILES_RESULT_FIELD = 'pdfs' 75 | FILES_EXPIRES = 180 76 | MEDIA_ALLOW_REDIRECTS = True 77 | 78 | # Enable and configure the AutoThrottle extension (disabled by default) 79 | # See http://doc.scrapy.org/en/latest/topics/autothrottle.html 80 | #AUTOTHROTTLE_ENABLED = True 81 | # The initial download delay 82 | #AUTOTHROTTLE_START_DELAY = 5 83 | # The maximum download delay to be set in case of high latencies 84 | #AUTOTHROTTLE_MAX_DELAY = 60 85 | # The average number of requests Scrapy should be sending in parallel to 86 | # each remote server 87 | #AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0 88 | # Enable showing throttling stats for every response received: 89 | #AUTOTHROTTLE_DEBUG = False 90 | 91 | # Enable and configure HTTP caching (disabled by default) 92 | # See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings 93 | #HTTPCACHE_ENABLED = True 94 | #HTTPCACHE_EXPIRATION_SECS = 0 95 | #HTTPCACHE_DIR = 'httpcache' 96 | #HTTPCACHE_IGNORE_HTTP_CODES = [] 97 | #HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage' 98 | -------------------------------------------------------------------------------- /budget/tests/chamber_of_deputies/test_pdf.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | import sys 3 | import tempfile 4 | from unittest import TestCase, skipIf 5 | from unittest.mock import patch 6 | 7 | import pandas as pd 8 | 9 | from budget.chamber_of_deputies.pdf import PDF 10 | 11 | 12 | class TestPDF(TestCase): 13 | @skipIf(sys.platform != 'darwin', 'feature not supported outside macOS') 14 | def test_extract_text_single_page(self): 15 | tempfolder = tempfile.mkdtemp() 16 | pdf_path = '{}/single_page.pdf'.format(tempfolder) 17 | shutil.copy('budget/tests/fixtures/single_page.pdf', pdf_path) 18 | PDF(pdf_path).extract_text() 19 | with open('budget/tests/fixtures/single_page.txt') as content_path: 20 | expected_content = content_path.read() 21 | with open(pdf_path.replace('.pdf', '.txt')) as result_path: 22 | result_content = result_path.read() 23 | self.assertEqual(expected_content, result_content) 24 | 25 | @skipIf(sys.platform != 'darwin', 'feature not supported outside macOS') 26 | def test_content_multi_page(self): 27 | tempfolder = tempfile.mkdtemp() 28 | pdf_path = '{}/multi_page.pdf'.format(tempfolder) 29 | shutil.copy('budget/tests/fixtures/multi_page.pdf', pdf_path) 30 | PDF(pdf_path).extract_text() 31 | with open('budget/tests/fixtures/multi_page.txt') as content_path: 32 | expected_content = content_path.read() 33 | with open(pdf_path.replace('.pdf', '.txt')) as result_path: 34 | result_content = result_path.read() 35 | self.assertEqual(expected_content, result_content) 36 | 37 | @skipIf(sys.platform != 'darwin', 'feature not supported outside macOS') 38 | def test_content_multi_documents(self): 39 | tempfolder = tempfile.mkdtemp() 40 | pdf_1_path = '{}/single_page.pdf'.format(tempfolder) 41 | shutil.copy('budget/tests/fixtures/single_page.pdf', tempfolder) 42 | pdf_2_path = '{}/multi_page.pdf'.format(tempfolder) 43 | shutil.copy('budget/tests/fixtures/multi_page.pdf', tempfolder) 44 | 45 | PDF('{}/*.pdf'.format(tempfolder)).extract_text() 46 | 47 | doc_1_fixture = open('budget/tests/fixtures/single_page.txt') 48 | expect_doct_1_content = doc_1_fixture.read() 49 | doc_1_fixture.close() 50 | doc_2_fixture = open('budget/tests/fixtures/multi_page.txt') 51 | expect_doct_2_content = doc_2_fixture.read() 52 | doc_2_fixture.close() 53 | 54 | with open(pdf_1_path.replace('.pdf', '.txt')) as result_path: 55 | result_content = result_path.read() 56 | self.assertEqual(expect_doct_1_content, result_content) 57 | with open(pdf_2_path.replace('.pdf', '.txt')) as result_path: 58 | result_content = result_path.read() 59 | self.assertEqual(expect_doct_2_content, result_content) 60 | 61 | def test_fail_in_non_macos_systems(self): 62 | filepath = 'budget/tests/fixtures/single_page.pdf' 63 | subject = PDF(filepath) 64 | with patch('budget.chamber_of_deputies.pdf.sys') as sys_mock: 65 | sys_mock.platform = 'linux' 66 | with self.assertRaises(Exception): 67 | subject.extract_text() 68 | sys_mock.platform = 'win32' 69 | with self.assertRaises(Exception): 70 | subject.extract_text() 71 | 72 | def test_dataframe(self): 73 | tempfolder = tempfile.mkdtemp() 74 | pdf_1_path = '{}/single_page.pdf'.format(tempfolder) 75 | shutil.copy('budget/tests/fixtures/single_page.pdf', tempfolder) 76 | pdf_2_path = '{}/multi_page.pdf'.format(tempfolder) 77 | shutil.copy('budget/tests/fixtures/multi_page.pdf', tempfolder) 78 | 79 | subject = PDF('{}/*.pdf'.format(tempfolder)) 80 | subject.extract_text() 81 | result = subject.dataframe() 82 | self.assertIsInstance(result, pd.DataFrame) 83 | -------------------------------------------------------------------------------- /budget/tests/fixtures/single_page.txt: -------------------------------------------------------------------------------- 1 | CONGRESSO NACIONAL Data: 20/10/2016 2 | 3 | COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO Hora: 21:31 4 | 5 | EMENDAS AO PLN 0018 / 20-16 - LOA Página: 2529 de 7916 6 | 1 de 1 7 | 8 | ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA 9 | 10 | AUTOR DA EMENDA EMENDA 11 | 12 | 2783 - Francisco Floriano 27830001 13 | 14 | MODALIDADE DA EMENDA TIPO DE EMENDA 15 | 16 | Individual Apropriação - Inclusão 17 | 18 | ÁREA DE GOVERNO 19 | 20 | Saúde 21 | 22 | MODALIDADE DE INTERVENÇÃO TIPO DE REALIZAÇÃO PRETENDIDA 23 | 24 | 050 Manutenção (apenas GND 3 - Despesas Correntes) 615 Manutenção de Unidade de Saúde (GND 3 - Despesa Corrente) 25 | 26 | LOCALIDADE BENEFICIADA 27 | 28 | 3300000 - Rio de Janeiro 29 | 30 | COMPLEMENTO DA LOCALIDADE 31 | 32 | ESFERA ORÇAMENTÁRIA UNIDADE ORÇAMENTÁRIA PRETENDIDA 33 | 34 | Orçamento da Seguridade Social Fundo Nacional de Saúde 35 | 36 | FUNCIONAL / AÇÃO / SUBTÍTULO 37 | 38 | 10.122.2015.4525 39 | 40 | Apoio à Manutenção de Unidades de Saúde 41 | 42 | No Estado do Rio de Janeiro 43 | 44 | ESPECIFICAÇÃO DA META QUANTIDADE 45 | 46 | Unidade apoiada(unidade) 20 47 | 48 | ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00) 49 | 50 | GND MOD. APLICAÇÃO RP Valor Acrescido 51 | 52 | 3 Outras Despesas Correntes 40 Transf. a Municípios 6 15.319.536 53 | 54 | TOTAL ........ 15.319.536 55 | 56 | CANCELAMENTOS COMPENSATÓRIOS 57 | 58 | SEQUENCIAL FONTE GND MOD. APLICAÇÃO ID RP Valor Deduzido 59 | 60 | 004202 188 9 Reserva de Contingência 99 A Definir 0 2 15.319.536 61 | 62 | TOTAL ........ 15.319.536 63 | 64 | TIPO DA SUBVENÇÃO 65 | 66 | Público 67 | 68 | JUSTIFICATIVA 69 | 70 | Objetivo: INSUMOS ou Reforço de Dotação Piso de Atenção Básica / Média e Alta Complexidade- Atenção Especializada / Básica. 71 | 72 | a) auxílio na realização de despesas correntes e na aquisição de material de consumo e médico-hospitalar necessário ao desenvolvimento das atividades; ou 73 | 74 | b) reforço das dotações repassadas a título de piso de atenção básica e de procedimentos de média e alta complexidade, constituindo tais valores acréscimos aos tetos 75 | 76 | transferidos pela União para cumprimento de metas estabelecidas. 77 | -------------------------------------------------------------------------------- /scraper/legislative_amendments/pipelines.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define your item pipelines here 4 | # 5 | # Don't forget to add your pipeline to the ITEM_PIPELINES setting 6 | # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html 7 | 8 | import re 9 | 10 | 11 | class TargetLocationPipeline(object): 12 | UFS = { 13 | 'Acre': 'AC', 14 | 'Alagoas': 'AL', 15 | 'Amapá': 'AP', 16 | 'Amazonas': 'AM', 17 | 'Bahia': 'BA', 18 | 'Ceará': 'CE', 19 | 'Espírito Santo': 'ES', 20 | 'Goiás': 'GO', 21 | 'Maranhão': 'MA', 22 | 'Mato Grosso': 'MT', 23 | 'Mato Grosso do Sul': 'MS', 24 | 'Minas Gerais': 'MG', 25 | 'Pará': 'PA', 26 | 'Paraíba': 'PB', 27 | 'Paraná': 'PR', 28 | 'Pernambuco': 'PE', 29 | 'Piauí': 'PI', 30 | 'Rio de Janeiro': 'RJ', 31 | 'Rio Grande do Norte': 'RN', 32 | 'Rio Grande do Sul': 'RS', 33 | 'Rondônia': 'RO', 34 | 'Roraima': 'RR', 35 | 'Santa Catarina': 'SC', 36 | 'São Paulo': 'SP', 37 | 'Sergipe': 'SE', 38 | 'Tocantins': 'TO', 39 | } 40 | 41 | def process_item(self, item, spider): 42 | description = re.sub(r'(?<=\w)\-(?=\w{2}$)', ' - ', item['description']).replace('¿', '-') 43 | sections = description.split(' - ') 44 | lower_description = description.lower() 45 | 46 | if 'limoeiro de anadia' in lower_description: 47 | item['target_location'] = 'Limoeiro de Anadia - AL' 48 | elif 'pedra redonda - pi' in lower_description: 49 | item['target_location'] = 'PI' 50 | elif 'centro de tecnologia da informação renato archer' in lower_description: 51 | item['target_location'] = 'Campinas - SP' 52 | elif 'na br-116/rj' in lower_description or 'uerj' in lower_description: 53 | item['target_location'] = 'RJ' 54 | elif 'prestação de serviços médico-hospitalares do hospital das forças armadas' in lower_description: 55 | item['target_location'] = 'Rio de Janeiro - RJ' 56 | elif '11ª região da justiça do trabalho - am, rr' in lower_description or \ 57 | '14ª região da justiça do trabalho - ac, ro' in lower_description: 58 | item['target_location'] = 'Norte' 59 | elif item['code'] == '27.812.2035.5450.7222': 60 | item['target_location'] = 'Agrestina - PE' 61 | elif 'no município d' in lower_description: 62 | item['target_location'] = description.split('unicípio d')[-1][2:] 63 | if 'no estado d' in lower_description: 64 | sections = item['target_location'].split(' - ') 65 | city = ' - '.join(sections[:-1]) 66 | uf = self.UFS[sections[-1][13:]] 67 | item['target_location'] = '{} - {}'.format(city, uf) 68 | elif 'no estado d' in lower_description: 69 | item['target_location'] = self.UFS[sections[-1][13:]] 70 | elif 'em municípios do estado de' in lower_description: 71 | item['target_location'] = self.UFS[sections[-1][27:]] 72 | elif 'no distrito federal' in lower_description or \ 73 | 'pcdf' in lower_description: 74 | item['target_location'] = 'DF' 75 | elif 'região metropolitana' in lower_description: 76 | matches = re.search(r'([a-zA-Z]{2})$', description) 77 | if matches: 78 | item['target_location'] = matches[1] 79 | else: 80 | if 'macapá' in lower_description: 81 | item['target_location'] = 'AM' 82 | elif 'manaus' in lower_description: 83 | item['target_location'] = 'MA' 84 | elif 'rio de janeiro' in lower_description: 85 | item['target_location'] = 'RJ' 86 | else: 87 | raise NotImplementedError 88 | elif 'na região' in lower_description: 89 | item['target_location'] = sections[-1][10:] 90 | elif 'nacional' in lower_description: 91 | item['target_location'] = sections[-1] 92 | elif 'no exterior' in lower_description: 93 | item['target_location'] = 'Exterior' 94 | elif 'na amazônia legal' in lower_description: 95 | item['target_location'] = sections[-1][3:] 96 | elif 'reserva de contingência fiscal' in lower_description: 97 | item['target_location'] = None 98 | else: 99 | item['target_location'] = ' - '.join(description.split(' - ')[-2:]) 100 | assert ' - ' in item['target_location'] 101 | 102 | if item['target_location'][-1] == '.': 103 | item['target_location'] = item['target_location'][:-1] 104 | return item 105 | -------------------------------------------------------------------------------- /budget/chamber_of_deputies/amendment_parser.py: -------------------------------------------------------------------------------- 1 | class AmendmentParser: 2 | """ 3 | Class to parse contents from a list of arguments (as received 4 | from a Apache Spark PDF preprocessor) into a dictionary, 5 | with all expected attributes. 6 | """ 7 | 8 | def __init__(self, attributes): 9 | self.attrs = attributes 10 | 11 | def parse_page(self): 12 | """ 13 | Parse attributes. 14 | """ 15 | self._join_splitted_author() 16 | amendment = { 17 | 'file_generation_date': self.attribute('Data:', 1), 18 | 'file_generation_time': self.attribute('Hora:', 1), 19 | 'total_page_summary': self.attribute('Página:', 1), 20 | 'author_page_summary': self.attribute('Página:', 2), 21 | 'author': self.attribute('AUTOR DA EMENDA', 2), 22 | 'number': self.attribute('EMENDA', 2), 23 | 'destination': self.attrs[9], 24 | } 25 | if amendment['destination'] == 'ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA': 26 | self._fix_broken_intervention() 27 | self._join_splitted_intervention() 28 | amendment.update({ 29 | 'category': self.attribute('MODALIDADE DA EMENDA', 2), 30 | 'type': self.attribute('TIPO DE EMENDA', 2), 31 | 'department': self.attribute('ÁREA DE GOVERNO', 1), 32 | 'intervention_code': self.attribute('MODALIDADE DE INTERVENÇÃO', 2), 33 | 'intervention': self.attribute('MODALIDADE DE INTERVENÇÃO', 3), 34 | 'achievement_code': self.attribute('TIPO DE REALIZAÇÃO PRETENDIDA', 3), 35 | 'achievement': self.attribute('TIPO DE REALIZAÇÃO PRETENDIDA', 4), 36 | 'location': self.attribute('LOCALIDADE BENEFICIADA', 1), 37 | 'additional_value': self.attribute('TOTAL ........', 1), 38 | }) 39 | elif amendment['destination'] == 'ESPELHO DE EMENDAS AO TEXTO DA LEI': 40 | amendment.update({ 41 | 'category': self.attribute('MODALIDADE DA EMENDA', 3), 42 | 'type': self.attribute('TIPO DE EMENDA', 3), 43 | 'reference': self.attribute('REFERÊNCIA', 3), 44 | 'proposed_wording': self.attribute('TEXTO PROPOSTO', 1), 45 | 'justification': self.justification(), 46 | }) 47 | return amendment 48 | 49 | def attribute(self, reference, element_diff): 50 | if reference in self.attrs: 51 | value_index = self.attrs.index(reference) 52 | return self.attrs[value_index + element_diff] 53 | 54 | def justification(self): 55 | if 'JUSTIFICATIVA' in self.attrs: 56 | return '\n'.join(self.attrs[self.attrs.index('JUSTIFICATIVA') + 1:]) 57 | 58 | def _join_splitted_author(self): 59 | """ 60 | Identify if an author is contained in the page and needs to have 61 | have values merged (sometimes in the PDF text extraction, 62 | author gets splitted into multiple values). 63 | """ 64 | has_attributes = 'AUTOR DA EMENDA' in self.attrs and \ 65 | 'MODALIDADE DA EMENDA' in self.attrs 66 | if has_attributes: 67 | title1_index = self.attrs.index('AUTOR DA EMENDA') 68 | title2_index = self.attrs.index('MODALIDADE DA EMENDA') 69 | author_index = title1_index + 2 70 | author_part2_index = author_index + 1 71 | for index in range(author_part2_index, title2_index - 1): 72 | self.attrs[author_index] += ' ' + self.attrs[author_part2_index] 73 | del(self.attrs[author_part2_index]) 74 | 75 | def _join_splitted_intervention(self): 76 | has_attributes = 'MODALIDADE DE INTERVENÇÃO' in self.attrs and \ 77 | 'LOCALIDADE BENEFICIADA' in self.attrs 78 | if has_attributes: 79 | title1_index = self.attrs.index('MODALIDADE DE INTERVENÇÃO') 80 | title2_index = self.attrs.index('LOCALIDADE BENEFICIADA') 81 | author_index = title1_index + 3 82 | author_part2_index = author_index + 1 83 | for index in range(author_part2_index, title2_index - 2): 84 | self.attrs[author_index] += ' ' + self.attrs[author_part2_index] 85 | del(self.attrs[author_part2_index]) 86 | 87 | def _fix_broken_intervention(self): 88 | values = [ 89 | 'PSB: Apoio CRAS/Centro:Convivência-Juventude-Criança- 285', 90 | 'PSE:CREAS/Abrigo/ILPI/República/CasaLar/CentroDia/PessoaDe 285', 91 | ] 92 | values = [value 93 | for value in values 94 | if value in self.attrs] 95 | if any(values): 96 | value = values[0] 97 | index = self.attrs.index(value) 98 | self.attrs[index] = value[:-4] + self.attrs[index + 2] 99 | del(self.attrs[index + 2]) 100 | self.attrs.insert(index + 1, value[-3:]) 101 | -------------------------------------------------------------------------------- /budget/tests/fixtures/multi_page.txt: -------------------------------------------------------------------------------- 1 | CONGRESSO NACIONAL Data: 20/10/2016 2 | 3 | COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO Hora: 21:33 4 | 5 | EMENDAS AO PLN 0018 / 20-16 - LOA Página: 1781 de 7916 6 | 1 de 2 7 | 8 | ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA 9 | 10 | AUTOR DA EMENDA EMENDA 11 | 12 | 2701 - Domingos Neto 27010001 13 | 14 | MODALIDADE DA EMENDA TIPO DE EMENDA 15 | 16 | Individual Apropriação - Acréscimo 17 | 18 | LOCALIDADE BENEFICIADA 19 | 20 | 9000000 - Nacional 21 | 22 | COMPLEMENTO DA LOCALIDADE 23 | 24 | ESFERA ORÇAMENTÁRIA UNIDADE ORÇAMENTÁRIA PRETENDIDA 25 | 26 | Orçamento da Seguridade Social Fundo Nacional de Saúde 27 | 28 | FUNCIONAL / AÇÃO / SUBTÍTULO 29 | 30 | 10.302.2015.6148.0001 31 | 32 | Assistência Médica Qualificada e Gratuita a Todos os Níveis da População e Desenvolvimento de Atividades Educacionais e de Pesquisa no Campo da Saúde - 33 | 34 | Serviço Social Autônomo Associação das Pioneiras Sociais 35 | 36 | Nacional 37 | 38 | ESPECIFICAÇÃO DA META QUANTIDADE 39 | 40 | Procedimento realizado(unidade) 1 41 | 42 | ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00) 43 | 44 | GND MOD. APLICAÇÃO RP Valor Acrescido 45 | 46 | 3 Outras Despesas Correntes 90 Aplic. Diretas 6 159.769 47 | 48 | TOTAL ........ 159.769 49 | 50 | CANCELAMENTOS COMPENSATÓRIOS 51 | 52 | SEQUENCIAL FONTE GND MOD. APLICAÇÃO ID RP Valor Deduzido 53 | 54 | 004202 188 9 Reserva de Contingência 99 A Definir 0 2 159.769 55 | 56 | TOTAL ........ 159.769 57 | 58 | JUSTIFICATIVA 59 | 60 | Esta emenda pleiteia recursos de acréscimo ao PLOA/2017 para execução do Contrato de Gestão, correspondente às despesas correntes (pessoaL, materiais e serviços) 61 | 62 | para todas as unidades da Rede, garantindo a continuidade dos atendimentos, dos projetos educacionais e de pesquisa no campo da saúde. 63 | CONGRESSO NACIONAL Data: 20/10/2016 64 | 65 | COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO Hora: 21:33 66 | 67 | EMENDAS AO PLN 0018 / 20-16 - LOA Página: 1782 de 7916 68 | 2 de 2 69 | 70 | ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA 71 | 72 | AUTOR DA EMENDA EMENDA 73 | 74 | 2701 - Domingos Neto 27010002 75 | 76 | MODALIDADE DA EMENDA TIPO DE EMENDA 77 | 78 | Individual Apropriação - Inclusão 79 | 80 | ÁREA DE GOVERNO 81 | 82 | Saúde 83 | 84 | MODALIDADE DE INTERVENÇÃO TIPO DE REALIZAÇÃO PRETENDIDA 85 | 86 | 050 Manutenção (apenas GND 3 - Despesas Correntes) 615 Manutenção de Unidade de Saúde (GND 3 - Despesa Corrente) 87 | 88 | LOCALIDADE BENEFICIADA 89 | 90 | 2300000 - Ceará 91 | 92 | COMPLEMENTO DA LOCALIDADE 93 | 94 | ESFERA ORÇAMENTÁRIA UNIDADE ORÇAMENTÁRIA PRETENDIDA 95 | 96 | Orçamento da Seguridade Social Fundo Nacional de Saúde 97 | 98 | FUNCIONAL / AÇÃO / SUBTÍTULO 99 | 100 | 10.122.2015.4525 101 | 102 | Apoio à Manutenção de Unidades de Saúde 103 | 104 | No Estado do Ceará 105 | 106 | ESPECIFICAÇÃO DA META QUANTIDADE 107 | 108 | Unidade apoiada(unidade) 1 109 | 110 | ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00) 111 | 112 | GND MOD. APLICAÇÃO RP Valor Acrescido 113 | 114 | 3 Outras Despesas Correntes 99 A Definir 2 15.159.769 115 | 116 | TOTAL ........ 15.159.769 117 | 118 | CANCELAMENTOS COMPENSATÓRIOS 119 | 120 | SEQUENCIAL FONTE GND MOD. APLICAÇÃO ID RP Valor Deduzido 121 | 122 | 004202 188 9 Reserva de Contingência 99 A Definir 0 2 15.159.769 123 | 124 | TOTAL ........ 15.159.769 125 | 126 | TIPO DA SUBVENÇÃO 127 | 128 | Público 129 | 130 | JUSTIFICATIVA 131 | 132 | Destinação de Recursos correntes para a manutenção de Unidades de Saúde, que integram a Rede do Sistema Único de Saúde. 133 | -------------------------------------------------------------------------------- /budget/tests/fixtures/multi_page.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.4 2 | 1 0 obj 3 | << 4 | /Creator (Oracle11gR1 AS Reports Services) 5 | /CreationDate (D:20161020213357) 6 | /ModDate (D:20161020213357) 7 | /Producer (Oracle PDF driver) 8 | /Title (P5563_AV_LOA_AUTOR2_2701.PDF) 9 | /Author (Oracle Reports) 10 | >> 11 | endobj 12 | 5 0 obj 13 | <> 16 | stream 17 | Gatm=95ik3&\]4RJ*960R_YZ0S'<:j2d2BX>0*EhdMj5_;-- 18 | 2F).?jclcon0+"8@'P>%RhCY0p%[gQ.aD%?IO9I$\=E>fO2'--q:Xje-&amLP4[f1fkC&^a'tB` 19 | omrprSY*Haj)Mq'LC5Ciiq/D]92:o)!]*[KWR_u,f:de8L>!Jg"=,&hrGN6(bEPIHA':nZfN&ha>q$Q[>cZ/1A"Y8a%jBe?HBM8\D]=c]TP# 21 | b@iYlQdJ,aV^09$\hrhNinJaAr"'P:Pt#:F,HF8?N0=V^YCDLKB?N,,aGaBMP=`-Ks$$;LLU\!F 22 | k5.n%+o3gk%+$!@%O#VCW>>%EWP'@8bJ>#e+2a'5UnZ2E)-AbU&e`/klVacl*2E[mPtf0+CSg3' 23 | .+&%!K<)M:NX33sH3#A3&#CLEF=:_:TUdWqG\0VJ`6\]f/k),*F_J.ji`Z9[Eqat0gB&VRtF,@ 25 | YZ`r6,/Q^L&/K?+!^%%?L"b@T5u([_F)V1N>F&Y6PU3`8O.uM.?B](kg1&P<3B[;>cNCi]Go"Dc-@.Rqje1p@e7%=/$eY[TZ"br%rk6Do_/fN5dN"HIH(9BQ.[4aK7[Wp)ALD%P3VrISi 31 | ><\"+]4.7Ho7mjRMH'DUVX\(--hH["7&Mmd\$OT&8O0+F7Ju;,]DH90Wm(+1R\M,H7?MB4mU"p: 32 | l"NGmb(HcdgUkpj7F=%P1m?7:@$3_l@;T4][)lRqjfF%.0#)d_8 33 | d;X71r,:f8/b<]SPfrq5md*#Q1=ipVBNLp8aHAPYpUQ,>a,JJt7e 35 | SORImGb+-sV+sP$O4AQB6H-h_ngic*:BfWM#[C,Ij6ist.p9ocS"8m*DHk\[_'YR\s4cZ_7@]&] 36 | `aKlQQm#OhR@4kq3*YSc.MrGOYLrp`-=e,Q!RB?5%#k:Lp^kH(@)HIFh6qP[[RZgpPCjSp$K`PB 37 | n6l%0/FfLtX%%os1R>Dt=A-#krOu!]-FaEHlcYptp[9E73#CG'0Lm 40 | JO]/MN!s\!p:/K];22jg@,Rqm;.X9>P"kZJU'dnekW&#b-VT[o-CQsPk/5OrZST&87oWJWFnk\@ 41 | .[8`f]Ic#Z\V%7*+5mP:L"J_RNs-d\,AE!Xj/DRAf=Xq_YKE3lPA58$RH@M`HS(jr9j[rlU'&8' 42 | `G,%cb>la/M=ja]#gc_(%MGi0[EO,QQ@2G0^8]!+O!D]h1gX/r%E4XG!)-/Cl 45 | 2p:IT8-caN`o#g"j*WX)3\ZIEoZ3cWE*!Wa1Cei&4dC@6[W5c9D==_%A]4%HO?A=KZt''7@Y"4' 46 | b6Q?&m*Z)t\F3Db9ASOV$A`bY2q1I$A:Rp$7`hQ;j,du[cOX/3KS?>\>o82]3S:8m]rAIM-HsA= 47 | 2!icY,C.p$aMI](;]WKPea69?4-*aLA'hE6bd;t]^A)rg17hYfT3*"]0-&n$%58bhq=C6fr"'#0 48 | H8=oCA'A=##?Bdg@qhH"NB62tn*u";i5:<4Gl_],&9Ri7G3r;b/aBp_ 50 | f1YCZG+i)E>C/#jS'&bcj%Np(_aGdJ+lub3;81=q7*)TR9iQ=d<*ci>lsW[!4a:/!i.tccJRg,l 51 | oK(qdKgZMt$*KV6 53 | :#=9<10`D_ZoEieQ:[>?@m,m:?X]cB/lhl(!9,#6E'9bNTQsVfDMP+40\**=Xnea2':=:s<:afg 54 | 55 | endstream 56 | endobj 57 | 6 0 obj 58 | 2911 59 | endobj 60 | 7 0 obj 61 | <> 67 | endobj 68 | 8 0 obj 69 | <> 75 | endobj 76 | 9 0 obj 77 | << 78 | /Type /XObject 79 | /Subtype /Image 80 | /Name /im1 81 | /Width 61 82 | /Height 61 83 | /BitsPerComponent 8 84 | /ColorSpace [/Indexed /DeviceRGB 255 10 0 R] 85 | /Filter [/ASCII85Decode /FlateDecode] 86 | /Length 11 0 R 87 | >> 88 | stream 89 | Gat%bCHrP7(<=<*L+io?kQDhiGuId9:f)G]+J?nG,TmfD6V2M*Lk&B&U96@O_"%t;'L=tq1b'n; 90 | TN2G&C3R.iS'^_^A=>(Qf\LEg%2?$^\,ETk_$X4W]B;OnP2+qXkFV]:k?\d8))M-FZPR-BE^Q-O 91 | '8UHsU6lf;_^2&GsXg`skWp)1C`akME9XAhN 93 | F5/]jo^LYsCqG#bjt0o/f<6oaeki?\%$S@JQB.fS08a4f>Q"ZV/qM*Pc0MhnRBGj2^0H@*2BGZ/D/D7,risIJmjIHnKs!3;&&ba%ZB;b 95 | L*3)5_;!sUhn'_Wo&FL\89'D+dJr 96 | &uNGq#[6olC8nR>a=Sut_oHbEK?.hN_VTM;,O*MQ)6W:1[qsfq+'^c9D&brH%OtI83R7pDE5/QbKE1n`$tTNitD5&\WV/u]_hg9;<#uepq)n)Mq[>a 99 | 2ITaU/rHOPZT3*E]-nKA6'(js',(`\Mi(/"bK?Xrd`PK$rs\%:%n'ff)pP 102 | J6flge9&.m>dFga3T%e&4iY70+H2H*BR*?/&1>g%C`\Y(SS+.(M_p]kXcQeMeOcsqk]'aHo=;FN 103 | al1lXa*-l.N/9h;Mc#tA+tgOt[qu_0("JXDM_<1`AYdli""\5&#+9h99`Rj()t'6`']qqm&DJ%6 104 | =^K9Uq479\pf4UD5sd%FT\j>f*h18RG-JM%@t>f$A)r%T/6J@K&&=-7&Ico[S&:l'k$5qi8dHo`a8Oh`m'6o&A>tMWV]Tb#DJCG&105\H3=QdKF=Ret3 107 | &e%tqe<[)U4cV03jfjA)JaX-89:D<@P%-L:N$rJjT9SLkCshreI9d/9;E(3P*cLWdLf4u\dFlQPT)F6T^3\$jMBXKlJ:kK8+> 110 | D!;B#,i0;gj4o\i(/=j.Di5=V\%!h&m65sGg:sp^.Zp"G]T@)8`JN<'0'e>f3.!>!XRQ3H(tNVD 111 | A&neY_t]njnaW+SELZ2eFgBe3g!;5DPNj&XL0I7_#A`A\#]P!8k?;?73?o05[Y$ 114 | []stqi[M.[V9f1BZeTeC2WI^4`R1.o\>]A_'YX&Tn&2H[tPft_Fsa'WBE51 116 | 36C*C&S.a0oOV0Q[][3K^9439VrUlS6d:GtJRGBg'bCOe_ska:9A0qkV42B^NcVctn'+ID#4RW< 117 | 7@uEdoX't8QBmb:1jKdi#QtD')oZ:F8_f)8"o@=)$pebtPg:/@g]NP-H%6'2`JrXGc$-?JSSFJc 118 | K@u:^$=^>oPJE%nU\C,[KrE6qGX!"4^Ak[Gt>$(cc>BS 119 | -=iLN`/K]U8r:d.:2`-.*1.4F'EU,-hjX*!;-6,14tePn.6K06CR^%H9Cfb^['>=J;1>2gMWkY?E9^_m*I9qc3=rdAk=X"JO\NerUe%0(jQiHt/`K<:2&G^8+$$VF)d 121 | A0/"9EH09RH`(LdZl_YWo7c4MTms8u*>+VV[5si`]HD,5&W%^!HJ$%g66o1IW,cq;na[U3*5!I: 122 | r9ZN?&W%cOe\=3poO(MJ<=*q*_)pG_4qpHCB,!/.+OTBN".@O[*;?I.:N3l7VKa6P)8O'p&nso4 123 | GZY.5?6U%K4>&N9*EgL/2pVHq$\^Y5O]g'!^CP_^q3NL2f[bJ*NpNWn5pH@SN@ILeK-Y`WOr+<8 124 | Bu\.)A0NlU/KT!i$q:+Cruh;T(8Ur]=8"%4I%T0Lh3LD'G9Ps3k_DALj?q'j;X6#&oFI(uSfFBN 125 | (/e>e`oDG$NakS[QsY7'lK\5*DXqa:4N>@p"OUc.22'AT)4PO2<>+k:Y[T;CSt;NNBQY4#M%mu7 126 | 2h5FfQu95$>M__Ri&dpEPC#!B.m++*Ih-Y>gq7*.84aZrlbb(Uh6`',eP/dOnm6Ar2@9NS!.TLi 127 | `nKg8^iQ"t!$r:ig,_3qRJLZ)UXZWMen5kMo%c^+8u_6JSXCKqV7lmTRe*B]d5U`jLT]ABksgL! 128 | CEL=kn_2$(6DL$k<'4/T"'3.7f9h:8L/in-4/l5\LIYQLOM5A_r;PH+%j1fFqp(2#huZ*<,1P?: 129 | bW1Y\7D-D;=uh\D;p+tBk/Kouo,>#On=l\6ChcE`4Yh0PV@9Jh`72FoM8gTh)L=HF#-3beEqfKE#-`[/+SR.g&X]8,T0binUmF.2sfss<6q!@AFgsjj+ 131 | aR",.R>EBPX-n6m@TGWN1I",%puTBV<=NUV",(Q8<_]OiZssc.\J_MmAk&]G.]/$"MYT8a:e^)e 132 | *dpIS)7J>QesZ=_ieJmRjYW[^b`'f+%?,ia.]:h.55eYBrUSN@Z[."D8hgYM&5#jh8#(]D&'>,I 133 | LEJT_Sm`.<);njaqRO?8]r'K[u4&T(Yf 148 | QWFjH[Vjo)7o63>E2kLec('a&:&iHC1Na)UaH7uKSI$_g#X^`=9nk!#JRkV%%%8%<bJ%<_G$,m$r3-I6,Mp]YF,jB&FA!X 153 | 5H$nKRF[_?phHb/jk6Mtb"?l\GQ:tR.tm[-ZjXpsp?:c8CW0\UUn0E!d8-1udR$*Nc?;?65PZuh 154 | lf5+mcH=)>fPtp'='):-$g]8degsFq$Oc\f2oL`:o=;F%-n+i@f(V0bpJFfZ!)0JMlY5IHG+F=AWkp$>uY5o)74e,Ap!zzz~> 157 | endstream 158 | endobj 159 | 12 0 obj 160 | 974 161 | endobj 162 | 4 0 obj 163 | << 164 | /Type /Page 165 | /MediaBox [0 0 595 842] 166 | /Parent 3 0 R 167 | /Resources <> /XObject << /im1 9 0 R >> >> 168 | /Contents 5 0 R 169 | /CropBox [0 0 595 842] 170 | >> 171 | endobj 172 | 14 0 obj 173 | <> 176 | stream 177 | Gatm=95ii['##=SJ*=ckPf8IHDK[t\gh;Of'\K3OUh>6amt#71L).5YOfS]>?-u 178 | &7BuS:0Z6Z4u>uFFqDPeWE1]Br 179 | 7]O4qSqJk\SF@f^6H`+`4_+,C;l5L="tJN>>%8TX<"R>O)rlLBAD<21OnIt\H.A*VJQ,+r]RG!9 180 | TrPSTP"5;Y1_3-G"L0((@mM+3N90Et0JnhdNNM>+<;jdJlVpX`"a:\Q!iE%;elOXXo#kTFQ3GCZ 181 | fqQR:/+]9sR)8+1\j%^J(M3DJ6/Y7uP'KN7Y0ss2hiM=CIV+$#HFUVM0Xi)+E 191 | cr8p7f.qCfM;0Yg$=^L>o]Sl$DCG]-[egp+`>^oeaK`sJL\5ung8m#NGE_m"=k>`UREnH\A_-3S 192 | RN9$pgMF@DqR,#4IHEICPY$HR\hIne!1ZlDWp>])^u43V2cc*Ij=-H6Qs-eOi]R.RAb&P;U++9fF"NeT1F(gO1?qqsh')J\d^?''e[URg0:Pu?:u>"@joq*C 195 | WU=[BiVA_ma2OU&CY1)UA>jY6"*cTG)9ktH*?ERm4J_`QeN%F1m8#Y#)SOU]ohp7$/^nn6rtbGZ3DsQF"%%k'=K9BY 198 | O+On/fLAeUJ#T&k(4\hg;DsU5Xat&o\R3l__kC2tYs:$bN/S;^#oYmmMQIRN=,Y)QguMr&8(Ss+ 199 | muSB(gOKSr#d_GdPrd#>#/eqqm+2aeP1TH/c+8@=$.Yo/1YlqW?ZjZ1_KL!cl,='hZ3S(J6@n'J 200 | g--#pL72,ubQ'%0CO8g\)]9FWLXk"WLV:mb_81Hq#[pn)g&E5Kn\?+RUpQThsOlK 201 | ]ltK]][Y])eE#<7O`kREhiRU0L90!LC=KB!q1`Flf,D;TcX*aJp^MNuV0\Sk3=bD%lT4)c'On2qMqd#l 203 | ,*4UT]>5@6DpPJ6=1;7b^RC[80aXP-;BPDC]IbYi?E1t+bE^;QkAe+(Qr,NUe'-00L_o1q;mObu 204 | ^hEg^kfn)eO\W.:TI)V4rp:#r@V[_SlT*#&1o[&us&I>[f0r:1#s;-k0%4SVVE7liamosq]qNsK 205 | =a.WV&!8EJf1Q]&iaBm:1-dIpdD1\u4uUSd(HElWYp\B^L^1.*?($FbeF6;`$Z4SY?2_.`P4X4X 206 | m-[pchSo!EkV5J)8ZH\EN_O_peOo$KmQrNt]^oU.&5??'d]HZ4&[%=Vg8PKMZKA4*;\1$&g"IG=N!Z\Fb60u@fO#n/`aflj@D[, 208 | ,';\kB_HE:#A=IW1G%6&n/`1HJu:><-c:L(9&K"#&9;uO.(Hkr)(K2s@Ei#YTe9TbiV2)P3Ns/of.o@AVX@JCT]9!t$G_@E7rq&%mbG:h5!QS@6s)"$hG 214 | ;$GN>(TPI0cW83(`7VstH!*[d@GT8@QPY>'TKs@3Q>qk6,;`\^YT9,qQ%8D[rrMPE[RgH!~> 215 | endstream 216 | endobj 217 | 15 0 obj 218 | 2921 219 | endobj 220 | 13 0 obj 221 | << 222 | /Type /Page 223 | /MediaBox [0 0 595 842] 224 | /Parent 3 0 R 225 | /Resources <> /XObject << /im1 9 0 R >> >> 226 | /Contents 14 0 R 227 | /CropBox [0 0 595 842] 228 | >> 229 | endobj 230 | 2 0 obj 231 | << 232 | /Type /Catalog 233 | /Pages 3 0 R 234 | >> 235 | endobj 236 | 3 0 obj 237 | << 238 | /Type /Pages 239 | /Kids [ 240 | 4 0 R 13 0 R ] 241 | /Count 2 242 | >> 243 | endobj 244 | xref 245 | 0 16 246 | 0000000000 65535 f 247 | 0000000010 00000 n 248 | 0000011877 00000 n 249 | 0000011932 00000 n 250 | 0000008378 00000 n 251 | 0000000238 00000 n 252 | 0000003247 00000 n 253 | 0000003270 00000 n 254 | 0000003408 00000 n 255 | 0000003543 00000 n 256 | 0000007296 00000 n 257 | 0000007272 00000 n 258 | 0000008355 00000 n 259 | 0000011649 00000 n 260 | 0000008604 00000 n 261 | 0000011625 00000 n 262 | trailer 263 | << 264 | /Size 16 265 | /Root 2 0 R 266 | /Info 1 0 R 267 | >> 268 | startxref 269 | 12007 270 | %%EOF 271 | -------------------------------------------------------------------------------- /budget/tests/chamber_of_deputies/test_amendment_parser.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | import tempfile 3 | from unittest import TestCase 4 | 5 | import pandas as pd 6 | 7 | from budget.chamber_of_deputies.amendment_parser import AmendmentParser 8 | 9 | 10 | class TestAmendmentParser(TestCase): 11 | def setUp(self): 12 | path = 'budget/tests/fixtures/amendment_attributes.csv' 13 | self.attributes = pd.read_csv(path, dtype=str) 14 | 15 | def fixture_by_index(self, index): 16 | return [attr 17 | for attr in self.attributes.iloc[index].values.tolist() 18 | if not isinstance(attr, float)] 19 | 20 | def test_parse_simple(self): 21 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/OR2017/emendas/despesa/P5563_AV_LOA_AUTOR2_3841.pdf#page=1 22 | subject = AmendmentParser(self.fixture_by_index(0)) 23 | result = subject.parse_page() 24 | 25 | self.assertEqual('20/10/2016', result['file_generation_date']) 26 | self.assertEqual('21:34', result['file_generation_time']) 27 | self.assertEqual('3403 de 7916', result['total_page_summary']) 28 | self.assertEqual('1 de 10', result['author_page_summary']) 29 | self.assertEqual('3841 - Jones Martins', result['author']) 30 | self.assertEqual('38410001', result['number']) 31 | self.assertEqual('Individual', result['category']) 32 | self.assertEqual('Apropriação - Inclusão', result['type']) 33 | self.assertEqual('Defesa Nacional', result['department']) 34 | self.assertEqual('434', result['intervention_code']) 35 | self.assertEqual('Implantação/Instalação/Ampliação', result['intervention']) 36 | self.assertEqual('167', result['achievement_code']) 37 | self.assertEqual('Instalações/Equip.Militares', result['achievement']) 38 | self.assertEqual('4300000 - Rio Grande do Sul', result['location']) 39 | self.assertEqual('100.000', result['additional_value']) 40 | 41 | def test_parse_splitted_author_bancada_mato_grosso_do_sul(self): 42 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/OR2017/emendas/despesa/P5563_AV_LOA_AUTOR2_7113.pdf#page=14 43 | subject = AmendmentParser(self.fixture_by_index(1)) 44 | result = subject.parse_page() 45 | 46 | self.assertEqual('20/10/2016', result['file_generation_date']) 47 | self.assertEqual('21:35', result['file_generation_time']) 48 | self.assertEqual('7451 de 7916', result['total_page_summary']) 49 | self.assertEqual('14 de 15', result['author_page_summary']) 50 | self.assertEqual('7113 - Bancada do Mato Grosso do Sul', result['author']) 51 | self.assertEqual('71130014', result['number']) 52 | self.assertEqual('Bancada Estadual', result['category']) 53 | self.assertEqual('Apropriação - Inclusão', result['type']) 54 | self.assertEqual('Irrigação e Integração Nacional', result['department']) 55 | self.assertEqual('591', result['intervention_code']) 56 | self.assertEqual('Promoção/Fomento do/da', result['intervention']) 57 | self.assertEqual('987', result['achievement_code']) 58 | self.assertEqual('Desenvolvimento Economico', result['achievement']) 59 | self.assertEqual('5000000 - Mato Grosso do Sul', result['location']) 60 | self.assertEqual('100.000.000', result['additional_value']) 61 | 62 | def test_parse_splitted_author_professora_dorinha_seabra_rezende(self): 63 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/OR2017/emendas/despesa/P5563_AV_LOA_AUTOR2_2693.pdf#page=11 64 | subject = AmendmentParser(self.fixture_by_index(2)) 65 | result = subject.parse_page() 66 | 67 | self.assertEqual('20/10/2016', result['file_generation_date']) 68 | self.assertEqual('21:33', result['file_generation_time']) 69 | self.assertEqual('5703 de 7916', result['total_page_summary']) 70 | self.assertEqual('11 de 11', result['author_page_summary']) 71 | self.assertEqual('2693 - Professora Dorinha Seabra Rezende', result['author']) 72 | self.assertEqual('26930011', result['number']) 73 | self.assertEqual('Individual', result['category']) 74 | self.assertEqual('Apropriação - Inclusão', result['type']) 75 | self.assertEqual('Defesa Nacional', result['department']) 76 | self.assertEqual('028', result['intervention_code']) 77 | self.assertEqual('Apoio Comunitário', result['intervention']) 78 | self.assertEqual('805', result['achievement_code']) 79 | self.assertEqual('Cooperação', result['achievement']) 80 | self.assertEqual('1721000 - Palmas', result['location']) 81 | self.assertEqual('100.000', result['additional_value']) 82 | 83 | def test_parse_splitted_author_bancada_rio_grande_do_norte(self): 84 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/OR2017/emendas/despesa/P5563_AV_LOA_AUTOR2_7121.pdf#page=3 85 | subject = AmendmentParser(self.fixture_by_index(3)) 86 | result = subject.parse_page() 87 | 88 | self.assertEqual('20/10/2016', result['file_generation_date']) 89 | self.assertEqual('21:35', result['file_generation_time']) 90 | self.assertEqual('7580 de 7916', result['total_page_summary']) 91 | self.assertEqual('3 de 15', result['author_page_summary']) 92 | self.assertEqual('7121 - Bancada do Rio Grande do Norte', result['author']) 93 | self.assertEqual('71210003', result['number']) 94 | self.assertEqual('Bancada Estadual', result['category']) 95 | self.assertEqual('Apropriação - Inclusão', result['type']) 96 | self.assertEqual('Saúde', result['department']) 97 | self.assertEqual('990', result['intervention_code']) 98 | self.assertEqual('Atipica / Outras', result['intervention']) 99 | self.assertEqual('334', result['achievement_code']) 100 | self.assertEqual('Sem Previsão (Atípico) - Adequar UO-Subf-Prog-Ação-Subt.', 101 | result['achievement']) 102 | self.assertEqual('2400000 - Rio Grande do Norte', result['location']) 103 | self.assertEqual('40.000.000', result['additional_value']) 104 | 105 | def test_parse_splitted_author_bancada_rio_grande_do_sul(self): 106 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/OR2017/emendas/despesa/P5563_AV_LOA_AUTOR2_7122.pdf#page=3 107 | subject = AmendmentParser(self.fixture_by_index(4)) 108 | result = subject.parse_page() 109 | 110 | self.assertEqual('20/10/2016', result['file_generation_date']) 111 | self.assertEqual('21:35', result['file_generation_time']) 112 | self.assertEqual('7595 de 7916', result['total_page_summary']) 113 | self.assertEqual('3 de 18', result['author_page_summary']) 114 | self.assertEqual('7122 - Bancada do Rio Grande do Sul', result['author']) 115 | self.assertEqual('71220003', result['number']) 116 | self.assertEqual('Bancada Estadual', result['category']) 117 | self.assertEqual('Apropriação - Inclusão', result['type']) 118 | self.assertEqual('Agricultura e Desenvolvimento Agrário', result['department']) 119 | self.assertEqual('004', result['intervention_code']) 120 | self.assertEqual('Fomento a(o)', result['intervention']) 121 | self.assertEqual('761', result['achievement_code']) 122 | self.assertEqual('Setor Agropecuário', result['achievement']) 123 | self.assertEqual('4300000 - Rio Grande do Sul', result['location']) 124 | self.assertEqual('100.000.000', result['additional_value']) 125 | 126 | def test_parse_sequence_page(self): 127 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/OR2012/emendas/despesa/CARLOSFX_AV_LOA_AUTOR2_2818.pdf#page=4 128 | subject = AmendmentParser(self.fixture_by_index(5)) 129 | result = subject.parse_page() 130 | 131 | self.assertEqual('25/11/2011', result['file_generation_date']) 132 | self.assertEqual('01:07', result['file_generation_time']) 133 | self.assertEqual('8183 de 9656', result['total_page_summary']) 134 | self.assertEqual('5 de 15', result['author_page_summary']) 135 | self.assertEqual('2818 - Tiririca', result['author']) 136 | self.assertEqual('28180004', result['number']) 137 | self.assertIsNone(result['category']) 138 | self.assertIsNone(result['type']) 139 | 140 | def test_parse_suppressive_amendment(self): 141 | # http://www.camara.gov.br/internet/comissao/index/mista/orca/orcamento/OR2017/emendas/despesa/P5563_AV_LOA_AUTOR2_2868.pdf#page=11 142 | subject = AmendmentParser(self.fixture_by_index(6)) 143 | result = subject.parse_page() 144 | 145 | self.assertEqual('20/10/2016', result['file_generation_date']) 146 | self.assertEqual('21:32', result['file_generation_time']) 147 | self.assertEqual('5121 de 7916', result['total_page_summary']) 148 | self.assertEqual('11 de 11', result['author_page_summary']) 149 | self.assertEqual('2868 - Nelson Marchezan Junior', result['author']) 150 | self.assertEqual('28680010', result['number']) 151 | self.assertEqual('Individual', result['category']) 152 | self.assertEqual('Supressiva', result['type']) 153 | self.assertEqual('Inciso I Alinea 2 Item 2', result['reference']) 154 | self.assertEqual('Suprima-se o texto atual.', result['proposed_wording']) 155 | self.assertEqual('Devido a crise econômica que o Brasil enfrenta, os recursos para aumento de salário para servidores devem ser suspensos de todos os poderes. Para tanto, é necessário\ncancelar a autorização do Anexo V e os recursos correspondentes à ação 0Z01.', 156 | result['justification']) 157 | 158 | def test_parse_splitted_intervention(self): 159 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/or2009/emendas/despesa/DANIELRJ_AV_LOA_AUTOR2_1970.pdf#page=11 160 | subject = AmendmentParser(self.fixture_by_index(7)) 161 | result = subject.parse_page() 162 | 163 | self.assertEqual('17/11/2008', result['file_generation_date']) 164 | self.assertEqual('21:32', result['file_generation_time']) 165 | self.assertEqual('8258 de 9842', result['total_page_summary']) 166 | self.assertEqual('11 de 11', result['author_page_summary']) 167 | self.assertEqual('1970 - Takayama', result['author']) 168 | self.assertEqual('19700011', result['number']) 169 | self.assertEqual('Individual', result['category']) 170 | self.assertEqual('Apropriação - Inclusão', result['type']) 171 | self.assertEqual('Saúde', result['department']) 172 | self.assertEqual('040', result['intervention_code']) 173 | self.assertEqual('Saneamento em Área Rural, Especial ou com menos 2.500 habit', 174 | result['intervention']) 175 | self.assertEqual('436', result['achievement_code']) 176 | self.assertEqual('Saneamento em Área Rural', result['achievement']) 177 | self.assertEqual('4100000 - Paraná', result['location']) 178 | self.assertEqual('100.000', result['additional_value']) 179 | 180 | def test_parse_broken_intervention(self): 181 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/OR2014/emendas/despesa/P5563_AV_LOA_AUTOR2_2491.pdf#page=5 182 | subject = AmendmentParser(self.fixture_by_index(8)) 183 | result = subject.parse_page() 184 | 185 | self.assertEqual('02/12/2013', result['file_generation_date']) 186 | self.assertEqual('22:00', result['file_generation_time']) 187 | self.assertEqual('4499 de 8807', result['total_page_summary']) 188 | self.assertEqual('5 de 10', result['author_page_summary']) 189 | self.assertEqual('2491 - Lelo Coimbra', result['author']) 190 | self.assertEqual('24910005', result['number']) 191 | self.assertEqual('Individual', result['category']) 192 | self.assertEqual('Apropriação - Inclusão', result['type']) 193 | self.assertEqual('Assistência Social', result['department']) 194 | self.assertEqual('192', result['intervention_code']) 195 | self.assertEqual('PSB: Apoio CRAS/Centro:Convivência-Juventude-Criança-Adolesc', 196 | result['intervention']) 197 | self.assertEqual('285', result['achievement_code']) 198 | self.assertEqual('Atenção à Familia/Criança/Adolesc./Idoso/Pessoa c/defic.', 199 | result['achievement']) 200 | self.assertEqual('3200000 - Espírito Santo', result['location']) 201 | self.assertEqual('500.000', result['additional_value']) 202 | 203 | def test_parse_broken_intervention2(self): 204 | # http://www.camara.leg.br/internet/comissao/index/mista/orca/orcamento/OR2016/emendas/despesa/ANDRELUF_AV_LOA_AUTOR2_1277.pdf#page=7 205 | subject = AmendmentParser(self.fixture_by_index(9)) 206 | result = subject.parse_page() 207 | 208 | self.assertEqual('21/10/2015', result['file_generation_date']) 209 | self.assertEqual('18:00', result['file_generation_time']) 210 | self.assertEqual('7343 de 8157', result['total_page_summary']) 211 | self.assertEqual('7 de 18', result['author_page_summary']) 212 | self.assertEqual('1277 - Wellington Roberto', result['author']) 213 | self.assertEqual('12770007', result['number']) 214 | self.assertEqual('Individual', result['category']) 215 | self.assertEqual('Apropriação - Inclusão', result['type']) 216 | self.assertEqual('Assistência Social', result['department']) 217 | self.assertEqual('193', result['intervention_code']) 218 | self.assertEqual('PSE:CREAS/Abrigo/ILPI/República/CasaLar/CentroDia/PessoaDef.', 219 | result['intervention']) 220 | self.assertEqual('285', result['achievement_code']) 221 | self.assertEqual('Atenção à Familia/Criança/Adolesc./Idoso/Pessoa c/defic.', 222 | result['achievement']) 223 | self.assertEqual('2507507 - João Pessoa', result['location']) 224 | self.assertEqual('100.000', result['additional_value']) 225 | -------------------------------------------------------------------------------- /budget/tests/fixtures/amendment_attributes.csv: -------------------------------------------------------------------------------- 1 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100 2 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:34","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","3403 de 7916","1 de 10","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","3841 - Jones Martins","38410001","MODALIDADE DA EMENDA","TIPO DE EMENDA","Individual","Apropriação - Inclusão","ÁREA DE GOVERNO","Defesa Nacional","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","434","Implantação/Instalação/Ampliação","167","Instalações/Equip.Militares","LOCALIDADE BENEFICIADA","4300000 - Rio Grande do Sul","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento Fiscal","Comando do Exército","FUNCIONAL / AÇÃO / SUBTÍTULO","05.153.2058.20PY","Adequação de Organizações Militares do Exército","No Estado do Rio Grande do Sul","ESPECIFICAÇÃO DA META","QUANTIDADE","Organização militar adequada(unidade)","1","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","3","Outras Despesas Correntes","90","Aplic. Diretas","6","100.000","TOTAL ........","100.000","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004202","188","9","Reserva de Contingência","99 A Definir","0","2","100.000","TOTAL ........","100.000","JUSTIFICATIVA","A emenda objetiva a conclusão das instalações desportivas do 4º Regimento de Cavalaria Blindado (4º RCB), em São Luiz Gonzaga -RS." 3 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:35","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","7451 de 7916","14 de 15","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","7113 - Bancada do Mato Grosso","do","Sul","71130014","MODALIDADE DA EMENDA","TIPO DE EMENDA","Bancada Estadual","Apropriação - Inclusão","ÁREA DE GOVERNO","Irrigação e Integração Nacional","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","591","Promoção/Fomento do/da","987","Desenvolvimento Economico","LOCALIDADE BENEFICIADA","5000000 - Mato Grosso do Sul","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento Fiscal","SUDECO","FUNCIONAL / AÇÃO / SUBTÍTULO","19.691.2029.8902","Promoção de Investimentos em Infraestrutura Econômica","Construção da Subestação da Curva do Leque - Pantanal - No Estado do Mato Grosso do Sul","ESPECIFICAÇÃO DA META","QUANTIDADE","Iniciativa apoiada(unidade)","1","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","4","Investimentos","30","Transf. a Est. e ao DF","2","100.000.000","TOTAL ........","100.000.000","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004202","188","9","Reserva de Contingência","99 A Definir","0","2","100.000.000","TOTAL ........","100.000.000","JUSTIFICATIVA","Atender a Região da Curva do Leque do Pantanal Sul Mato-Grossense, utilizando redes convencionais, subestações de distribuição e alimentadores para o atendimento","de 524 ligações, sendo a obra a ser realizada em Corumbá com distribuição pelos municípios de Miranda e Aquidauana." 4 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:33","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","5703 de 7916","11 de 11","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","2693 - Professora Dorinha Seabra","Rezende","26930011","MODALIDADE DA EMENDA","TIPO DE EMENDA","Individual","Apropriação - Inclusão","ÁREA DE GOVERNO","Defesa Nacional","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","028","Apoio Comunitário","805","Cooperação","LOCALIDADE BENEFICIADA","1721000 - Palmas","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento Fiscal","M. da Defesa","FUNCIONAL / AÇÃO / SUBTÍTULO","05.243.2058.20IG","Apoio das Forças Armadas ao Desenvolvimento do Desporto Militar e ao Esporte Nacional","Adequação das instalações do 22º BI - Palmas - TO","ESPECIFICAÇÃO DA META","QUANTIDADE","Pessoa beneficiada(unidade)","100","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","3","Outras Despesas Correntes","90","Aplic. Diretas","6","100.000","TOTAL ........","100.000","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004202","188","9","Reserva de Contingência","99 A Definir","0","2","100.000","TOTAL ........","100.000","JUSTIFICATIVA","Os recursos da presente emenda destinam-se ao 22º Batalhão de Infantaria (22º BI), em Palmas - TO para apoiar o Programa Forças no Esporte (PROFESP). O","PROFESP é um programa social de relevância nacional, desenvolvido em parceria firmada entre o Ministério da Defesa, Ministério do Esporte e o Ministério do","Desenvolvimento Social e Combate à Fome, com a missão precípua de promover, por intermédio do esporte, a inclusão social, a melhoria da qualidade de vida e a","prevenção de vulnerabilidade, dos jovens na faixa etária entre 7 e 17 anos, que se encontram em situação de vulnerabilidade social, utilizando para isso mecanismos","que tornem possível a valorização da cidadania. As crianças e adolescentes participantes do programa recebem treinamentos educacionais e esportivos, como também,","ações de inclusão social e cidadania na organização militar do Exército Brasileiro, acima citada, que disponibiliza suas instalações para a execução de atividades","pedagogicamente elaboradas." 5 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:35","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","7580 de 7916","3 de 15","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","7121 - Bancada do Rio Grande","do","Norte","71210003","MODALIDADE DA EMENDA","TIPO DE EMENDA","Bancada Estadual","Apropriação - Inclusão","ÁREA DE GOVERNO","Saúde","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","990","Atipica / Outras","334","Sem Previsão (Atípico) - Adequar UO-Subf-Prog-Ação-Subt.","LOCALIDADE BENEFICIADA","2400000 - Rio Grande do Norte","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento da Seguridade Social","UO Genérica - Area Gov.07","FUNCIONAL / AÇÃO / SUBTÍTULO","10.512.2068.9999","Saneamento Básico","Ações de Saneamento Básico em Áreas Vulneráveis das Periferias Urbanas - No Estado do Rio Grande do Norte","ESPECIFICAÇÃO DA META","QUANTIDADE","Sistema instalado(% de execução física)","1","AÇÃO ATÍPICA","AÇÃO","Ação Atípica","OBJETIVO","Propiciar soluções adequadas de abastecimento público de água ou de esgotamento sanitário em áreas urbanas vulneráveis da periferia dos municípios.","FINALIDADE","Atender a população carente das periferias em áreas urbanas vulneráveis","ESPECIFICAÇÃO DA META","Sistema instalado(% de execução física)","TIPO DA AÇÃO","INÍCIO DA AÇÃO","TÉRMINO DA AÇÃO","Projeto","01/2017","12/2017","CUSTO TOTAL (R$)","META TOTAL","40.000.000","1","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","4","Investimentos","30","Transf. a Est. e ao DF","2","40.000.000","TOTAL ........","40.000.000","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004202","188","9","Reserva de Contingência","99 A Definir","0","2","40.000.000","TOTAL ........","40.000.000","TIPO DA SUBVENÇÃO","Público","JUSTIFICATIVA","A referida emenda tem por objetivo propiciar soluções adequadas de abastecimento público de água ou de esgotamento sanitário, visando à prevenção e ao controle de","doenças e agravos. Para isso são realizadas a implantação, a ampliação ou a melhoria de sistemas públicos de abastecimento de água ou de esgotamento sanitário em","áreas vulneráveis à proliferação de doenças ocasionadas pela falta ou inadequação de saneamento básico. Poderão ser contemplados projetos ou obras eu visem","garantir: abastecimento de água e esgotamento sanitário nas periferias de áreas urbanas das cidades hoje não atendidas pela programa de Saneamento Básico com","dotações do Programa de Aceleramento do Crescimento - PAC." 6 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:35","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","7595 de 7916","3 de 18","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","7122 - Bancada do Rio Grande","do","Sul","71220003","MODALIDADE DA EMENDA","TIPO DE EMENDA","Bancada Estadual","Apropriação - Inclusão","ÁREA DE GOVERNO","Agricultura e Desenvolvimento Agrário","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","004","Fomento a(o)","761","Setor Agropecuário","LOCALIDADE BENEFICIADA","4300000 - Rio Grande do Sul","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento Fiscal","M. Ag., Pec. e Abastecimento","FUNCIONAL / AÇÃO / SUBTÍTULO","20.608.2077.20ZV","Fomento ao Setor Agropecuário","Aquisição de Máquinas e Equipamentos - No Estado do Rio Grande do Sul","ESPECIFICAÇÃO DA META","QUANTIDADE","Projeto apoiado(unidade)","100","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","4","Investimentos","90","Aplic. Diretas","7","100.000.000","TOTAL ........","100.000.000","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004202","188","9","Reserva de Contingência","99 A Definir","0","2","100.000.000","TOTAL ........","100.000.000","JUSTIFICATIVA","A PRESENTE EMENDA DA BANCADA GAÚCHA, DE CARÁTER IMPOSITIVO, VISA A AQUISIÇÃO DE MÁQUINAS E EQUIPAMENTOS POR","INTERMÉDIO DO MINISTÉRIO DA AGRICULTURA, PECUÁRIA E ABASTECIMENTO QUE EM MUITO CONTRIBUIRÃO PARA A MELHORIA DAS","CONDIÇÕES DE PRODUÇÃO E PRODUTIVIDADE ESPECIALMENTE DOS PEQUENOS PRODUTORES GAÚCHOS." 7 | "Data:","25/11/2011","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","01:07","EMENDAS AO PLN 0028 / 20-11 - LOA","Página:","8183 de 9656","5 de 15","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","2818 - Tiririca","28180004","76108660830","Sérgio Antonio Garcia Amoroso","JUSTIFICATIVA","Esta emenda tem por finalidade a alocação de recursos para manutenção e custeio de unidade de saúde no estado de São Paulo e a melhoria no atendimento médico-","hospitalar.","Essas insituições prestam atendimento em diversas especialidades, em sua maioria pelo Sistema Único de Saúde, visando a melhoria na qualidade de vida da","população." 8 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:32","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","5121 de 7916","11 de 11","ESPELHO DE EMENDAS AO TEXTO DA LEI","AUTOR DA EMENDA","EMENDA","2868 - Nelson Marchezan Junior","28680010","MODALIDADE DA EMENDA","TIPO DE EMENDA","REFERÊNCIA","Individual","Supressiva","Inciso I Alinea 2 Item 2","TEXTO PROPOSTO","Suprima-se o texto atual.","JUSTIFICATIVA","Devido a crise econômica que o Brasil enfrenta, os recursos para aumento de salário para servidores devem ser suspensos de todos os poderes. Para tanto, é necessário","cancelar a autorização do Anexo V e os recursos correspondentes à ação 0Z01." 9 | "Data:","17/11/2008","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:32","EMENDAS AO PLN 0038 / 20-08 - LOA","Página:","8258 de 9842","11 de 11","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","1970 - Takayama","19700011","MODALIDADE DA EMENDA","TIPO DE EMENDA","Individual","Apropriação - Inclusão","ÁREA DE GOVERNO","Saúde","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","040","Saneamento em Área Rural, Especial","ou com menos 2.500 habit","436","Saneamento em Área Rural","LOCALIDADE BENEFICIADA","4100000 - Paraná","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento da Seguridade Social","FUNASA","FUNCIONAL / AÇÃO / SUBTÍTULO","10.511.1287.7656","Implantação, Ampliação ou Melhoria do Serviço de Saneamento em Áreas Rurais, em Áreas Especiais (Quilombos, Assentamentos e Reservas Extrativistas) e em","Localidades com População Inferior a 2.500 Habitantes para Prevenção e Controle de Agravos","Em Municipios - No Estado do Paraná","ESPECIFICAÇÃO DA META","QUANTIDADE","Comunidade beneficiada(unidade)","1","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","4","Investimentos","40","Transf. a Municípios","2","100.000","TOTAL ........","100.000","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","020000","100","9","Reserva de Contingência","99 A Definir","0","2","100.000","TOTAL ........","100.000","JUSTIFICATIVA","A presente emenda visa auxiliar financeiramente o município para que melhore o serviço de saneamento básico em área rural." 10 | "Data:","02/12/2013","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","22:00","EMENDAS AO PLN 0009 / 20-13 - LOA","Página:","4499 de 8807","5 de 10","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","2491 - Lelo Coimbra","24910005","MODALIDADE DA EMENDA","TIPO DE EMENDA","Individual","Apropriação - Inclusão","ÁREA DE GOVERNO","Assistência Social","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","192","PSB: Apoio CRAS/Centro:Convivência-Juventude-Criança- 285","Atenção à Familia/Criança/Adolesc./Idoso/Pessoa c/defic.","Adolesc","LOCALIDADE BENEFICIADA","3200000 - Espírito Santo","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento da Seguridade Social","FNAS","FUNCIONAL / AÇÃO / SUBTÍTULO","08.244.2037.2B30","Estruturação da Rede de Serviços de Proteção Social Básica","No Estado do Espírito Santo","ESPECIFICAÇÃO DA META","QUANTIDADE","Ente federado apoiado(unidade)","2","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","4","Investimentos","40","Transf. a Municípios","2","500.000","TOTAL ........","500.000","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","020000","100","9","Reserva de Contingência","99 A Definir","0","2","500.000","TOTAL ........","500.000","TIPO DA SUBVENÇÃO","Privado","BENEFICIÁRIOS","CNPJ","00656378000148","NOME","Centro Comunitario Franco Rossetti","ENDEREÇO","Rua jair machado tomaz s/nº bairro saturnino mauro","RESPONSÁVEIS","CPF","NOME","61923842749","Pe. Aldir Roque Loss","JUSTIFICATIVA","esta emenda visa apoiar a implantação dos serviçõs da proteção social basica, qualificando a estrutura fisica material da instituição aprimorando e melhorando a","qualidade de vida." 11 | "Data:","21/10/2015","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","18:00","EMENDAS AO PLN 0007 / 20-15 - LOA","Página:","7343 de 8157","7 de 18","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","1277 - Wellington Roberto","12770007","MODALIDADE DA EMENDA","TIPO DE EMENDA","Individual","Apropriação - Inclusão","ÁREA DE GOVERNO","Assistência Social","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","193","PSE:CREAS/Abrigo/ILPI/República/CasaLar/CentroDia/PessoaDe 285","Atenção à Familia/Criança/Adolesc./Idoso/Pessoa c/defic.","f.","LOCALIDADE BENEFICIADA","2507507 - João Pessoa","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento da Seguridade Social","FNAS","FUNCIONAL / AÇÃO / SUBTÍTULO","08.244.2037.2B31","Estruturação da Rede de Serviços de Proteção Social Especial","Fundação São Pe. Pio de Pietrelcina - João Pessoa - PB","ESPECIFICAÇÃO DA META","QUANTIDADE","Ente federado apoiado(unidade)","1","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","3","Outras Despesas Correntes","90","Aplic. Diretas","2","100.000","TOTAL ........","100.000","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004411","100","9","Reserva de Contingência","99 A Definir","0","2","100.000","TOTAL ........","100.000","TIPO DA SUBVENÇÃO","Privado","BENEFICIÁRIOS","CNPJ","10441470000144","NOME","Fundação São Pe. Pio de Pietrelcina","ENDEREÇO","Av. Professora Jovita Gomes Alves, n 475, Bairro dos Ipês - João Pessoa/PB - CEP: 52028-870","RESPONSÁVEIS","CPF","NOME","42395313300","George Batista Pereira Filho","JUSTIFICATIVA","No intuito de contribuir para a superação das situações de riscos sociais e pessoais pelas quais passam muitapessoas, a Fundação São Pe. Pio de Pietrelcina oferece","um ambiente acolhedor, além de atividades que além da reestruturação familiar, promovendo a preservação dovínculos afetivos na relação mãe-filho para as","adolescentes que os possuem.","Para essas existe a possibilidade de profissionalização das mesmas como complemento ao processo educacionaformal oferecido na rede de atendimento local","(pública ou privada)." 12 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:31","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","2529 de 7916","1 de 1","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","2783 - Francisco Floriano","27830001","MODALIDADE DA EMENDA","TIPO DE EMENDA","Individual","Apropriação - Inclusão","ÁREA DE GOVERNO","Saúde","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","050","Manutenção (apenas GND 3 - Despesas Correntes)","615","Manutenção de Unidade de Saúde (GND 3 - Despesa Corrente)","LOCALIDADE BENEFICIADA","3300000 - Rio de Janeiro","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento da Seguridade Social","Fundo Nacional de Saúde","FUNCIONAL / AÇÃO / SUBTÍTULO","10.122.2015.4525","Apoio à Manutenção de Unidades de Saúde","No Estado do Rio de Janeiro","ESPECIFICAÇÃO DA META","QUANTIDADE","Unidade apoiada(unidade)","20","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","3","Outras Despesas Correntes","40","Transf. a Municípios","6","15.319.536","TOTAL ........","15.319.536","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004202","188","9","Reserva de Contingência","99 A Definir","0","2","15.319.536","TOTAL ........","15.319.536","TIPO DA SUBVENÇÃO","Público","JUSTIFICATIVA","Objetivo: INSUMOS ou Reforço de Dotação Piso de Atenção Básica / Média e Alta Complexidade- Atenção Especializada / Básica.","a) auxílio na realização de despesas correntes e na aquisição de material de consumo e médico-hospitalar necessário ao desenvolvimento das atividades; ou","b) reforço das dotações repassadas a título de piso de atenção básica e de procedimentos de média e alta complexidade, constituindo tais valores acréscimos aos tetos","transferidos pela União para cumprimento de metas estabelecidas." 13 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:33","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","1781 de 7916","1 de 2","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","2701 - Domingos Neto","27010001","MODALIDADE DA EMENDA","TIPO DE EMENDA","Individual","Apropriação - Acréscimo","LOCALIDADE BENEFICIADA","9000000 - Nacional","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento da Seguridade Social","Fundo Nacional de Saúde","FUNCIONAL / AÇÃO / SUBTÍTULO","10.302.2015.6148.0001","Assistência Médica Qualificada e Gratuita a Todos os Níveis da População e Desenvolvimento de Atividades Educacionais e de Pesquisa no Campo da Saúde -","Serviço Social Autônomo Associação das Pioneiras Sociais","Nacional","ESPECIFICAÇÃO DA META","QUANTIDADE","Procedimento realizado(unidade)","1","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","3","Outras Despesas Correntes","90","Aplic. Diretas","6","159.769","TOTAL ........","159.769","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004202","188","9","Reserva de Contingência","99 A Definir","0","2","159.769","TOTAL ........","159.769","JUSTIFICATIVA","Esta emenda pleiteia recursos de acréscimo ao PLOA/2017 para execução do Contrato de Gestão, correspondente às despesas correntes (pessoaL, materiais e serviços)","para todas as unidades da Rede, garantindo a continuidade dos atendimentos, dos projetos educacionais e de pesquisa no campo da saúde." 14 | "Data:","20/10/2016","COMISSÃO MISTA DE PLANOS, ORÇAMENTOS E FISCALIZAÇÃO","Hora:","21:33","EMENDAS AO PLN 0018 / 20-16 - LOA","Página:","1782 de 7916","2 de 2","ESPELHO DE EMENDA DE APROPRIAÇÃO DE DESPESA","AUTOR DA EMENDA","EMENDA","2701 - Domingos Neto","27010002","MODALIDADE DA EMENDA","TIPO DE EMENDA","Individual","Apropriação - Inclusão","ÁREA DE GOVERNO","Saúde","MODALIDADE DE INTERVENÇÃO","TIPO DE REALIZAÇÃO PRETENDIDA","050","Manutenção (apenas GND 3 - Despesas Correntes)","615","Manutenção de Unidade de Saúde (GND 3 - Despesa Corrente)","LOCALIDADE BENEFICIADA","2300000 - Ceará","COMPLEMENTO DA LOCALIDADE","ESFERA ORÇAMENTÁRIA","UNIDADE ORÇAMENTÁRIA PRETENDIDA","Orçamento da Seguridade Social","Fundo Nacional de Saúde","FUNCIONAL / AÇÃO / SUBTÍTULO","10.122.2015.4525","Apoio à Manutenção de Unidades de Saúde","No Estado do Ceará","ESPECIFICAÇÃO DA META","QUANTIDADE","Unidade apoiada(unidade)","1","ACRÉSCIMOS À PROGRAMAÇÃO (EM R$ 1,00)","GND","MOD. APLICAÇÃO","RP","Valor Acrescido","3","Outras Despesas Correntes","99","A Definir","2","15.159.769","TOTAL ........","15.159.769","CANCELAMENTOS COMPENSATÓRIOS","SEQUENCIAL","FONTE","GND","MOD. APLICAÇÃO","ID","RP","Valor Deduzido","004202","188","9","Reserva de Contingência","99 A Definir","0","2","15.159.769","TOTAL ........","15.159.769","TIPO DA SUBVENÇÃO","Público","JUSTIFICATIVA","Destinação de Recursos correntes para a manutenção de Unidades de Saúde, que integram a Rede do Sistema Único de Saúde." 15 | --------------------------------------------------------------------------------