teste_docs / tests /test_bdi_sections.py
gui-sparim's picture
Organiza justificativa e composição do BDI por construção
46d350b verified
Raw History Blame Contribute Delete
5.28 kB
import copy
import unittest
from docx import Document
from docx.opc.constants import RELATIONSHIP_TYPE as RT
from docx.oxml import parse_xml
from docx.oxml.ns import qn
from document.evolutivo import construction_bdi_notes, construction_groups
from test_evo_adjustments import body
from test_evolutivo_documento import fixture, resolved
LABELS = ['Administração central', 'Despesas financeiras', 'Seguros e garantias', 'Riscos', 'Tributos', 'Remuneração']
def composition(values):
return [{'descricao': label, 'percentual': value} for label, value in zip(LABELS, values)]
def notes(doc):
root = parse_xml(doc.part.part_related_by(RT.FOOTNOTES).blob)
return ' '.join(''.join(n.itertext(qn('w:t'))) for n in root if int(n.get(qn('w:id'))) > 0)
class BdiSectionsTests(unittest.TestCase):
def data(self):
data = fixture((2021, 2022))
for year in data['anos']:
c = year['construcao']['construcoes'][0]
c.update(bdiComposicaoAdotada=composition([4, 1, 1, 2, 7, 10]), bdiJustificativa='Composição aditiva sobre o custo direto.')
return data
def render(self, data):
imported = resolved(data)
before = copy.deepcopy(imported)
doc = Document()
construction_bdi_notes(doc, construction_groups(imported['avaliacoes']))
self.assertEqual(imported, before)
return doc
def test_general_chapter_only_introduction_and_each_construction_has_total(self):
data = self.data()
for year in data['anos']:
second = copy.deepcopy(year['construcao']['construcoes'][0])
second.update(id='second', seq=2, nome='Galpão B', bdi=20,
bdiComposicaoAdotada=composition([3, 1, 1, 2, 6, 7]))
year['construcao']['construcoes'].append(second)
doc = body(resolved(data))
paragraphs = [p.text for p in doc.paragraphs]
start = paragraphs.index('3.4.1.3 BDI e justificativa')
end = paragraphs.index('3.4.1.3.1 Construção 1 — Galpão A')
self.assertEqual(len(paragraphs[start + 1:end]), 2)
self.assertTrue(paragraphs[start + 1].startswith('BDI (%):'))
self.assertTrue(paragraphs[start + 2].startswith('O BDI informado em percentual'))
self.assertIn('3.4.1.3.2 Construção 2 — Galpão B', paragraphs)
tables = [t for t in doc.tables if t.cell(0, 0).text == 'Componente de BDI adotado']
self.assertEqual(len(tables), 2)
for table, total in zip(tables, ['25,00%', '20,00%']):
self.assertEqual([c.text for c in table.rows[-1].cells], ['Total do BDI', total])
self.assertEqual(len(table.rows), 8)
self.assertEqual(len(table.columns), 2)
self.assertTrue(all(run.bold for c in table.rows[-1].cells for p in c.paragraphs for run in p.runs))
self.assertFalse(any('Aplicável a Construção' in p for p in paragraphs[start:paragraphs.index('3.4.1.4 Depreciação e conservação')]))
def test_year_changes_compare_components_and_totals_without_duplicate_subchapters(self):
data = self.data()
c = data['anos'][1]['construcao']['construcoes'][0]
c.update(bdi=20, bdiComposicaoAdotada=composition([3, 1, 1, 2, 6, 7]), bdiJustificativa='Justificativa do segundo exercício.')
doc = self.render(data)
self.assertEqual(len(doc.tables), 1)
table = doc.tables[0]
self.assertEqual([c.text for c in table.rows[0].cells], ['Parâmetro / valor', 'IPTU 2022', 'IPTU 2023'])
self.assertEqual([c.text for c in table.rows[1].cells], ['Administração central', '4,00%', '3,00%'])
self.assertEqual([c.text for c in table.rows[-1].cells], ['Total do BDI', '25,00%', '20,00%'])
text = '\n'.join(p.text for p in doc.paragraphs)
self.assertIn('Justificativa do BDI (IPTU 2022): Composição aditiva', text)
self.assertIn('Justificativa do BDI (IPTU 2023): Justificativa do segundo exercício.', text)
def test_divergent_sum_does_not_replace_saved_bdi(self):
data = self.data()
for year in data['anos']:
year['construcao']['construcoes'][0]['bdiComposicaoAdotada'][0]['percentual'] = 5
doc = self.render(data)
self.assertEqual([c.text for c in doc.tables[0].rows[-2].cells], ['Soma dos componentes', '26,00%'])
self.assertEqual([c.text for c in doc.tables[0].rows[-1].cells], ['Total do BDI', '25,00%'])
self.assertIn('difere do percentual global registrado', notes(doc))
def test_missing_composition_and_private_reason_are_not_invented_or_exposed(self):
data = self.data()
for year in data['anos']:
c = year['construcao']['construcoes'][0]
c.pop('bdiComposicaoAdotada')
c.update(bdi=0, bdiJustificativa='JUSTIFICATIVA INTERNA', bdiJustificativaInterna=True)
doc = self.render(data)
self.assertEqual(len(doc.tables[0].rows), 2)
self.assertEqual([c.text for c in doc.tables[0].rows[-1].cells], ['Total do BDI', '0,00%'])
self.assertNotIn('JUSTIFICATIVA INTERNA', '\n'.join(p.text for p in doc.paragraphs) + notes(doc))
self.assertIn('sem discriminar sua composição', notes(doc))
if __name__ == '__main__':
unittest.main()