gui-sparim commited on
Commit
af24288
·
verified ·
1 Parent(s): 4e531da

Unifica composição das áreas com construção na primeira coluna

Browse files

Reúne as áreas equivalentes em uma tabela, preservando nome da construção e exercícios quando a composição variar. Mantém dimensões e coeficientes, com ajuste automático da fonte. Validação: 108 testes e renderização da cobaia.

document/evolutivo.py CHANGED
@@ -352,19 +352,24 @@ def construction_characteristics(doc, groups):
352
  for values,subset in variants.items():
353
  records.append([entry_scope(subset,groups,show_base=False)]+list(values))
354
  if len(records)>1: table(doc,records,[1.6,1.6,1.2,1.1,1.5],font_size=7)
355
- areas = OrderedDict()
356
  for entries in groups.values():
 
357
  for row,c,i in entries:
358
  details = [{key:a.get(key) for key in ('descricao','area','coeficiente')} for a in c.get('areasEquivalentes') or []]
359
  # A single area at coefficient 1 contributes no additional explanation.
360
  if not details or (len(details)==1 and number(details[0].get('coeficiente'))==1
361
  and number(c.get('areaTotal'))==number(c.get('areaCalculada'))==number(details[0].get('area'))): continue
362
  areas.setdefault(json.dumps(details,sort_keys=True,ensure_ascii=False),[]).append((row,c,i))
363
- for identity,entries in areas.items():
364
- add_body_text(doc,'Composição das áreas — '+entry_scope(entries,groups)+'.')
365
- table(doc,[['Tipo de área','Área real (m²)','Coeficiente','Parcela equivalente (m²)']]+[
366
- [a.get('descricao') or 'Não informado',fmt(a.get('area')),fmt(a.get('coeficiente'),4),
367
- fmt(number(a['area'])*number(a['coeficiente'])) if number(a.get('area')) is not None and number(a.get('coeficiente')) is not None else 'Não informado'] for a in json.loads(identity)],[3,1,1,1.4])
 
 
 
 
368
 
369
 
370
  def construction_cub_notes(doc, groups):
 
352
  for values,subset in variants.items():
353
  records.append([entry_scope(subset,groups,show_base=False)]+list(values))
354
  if len(records)>1: table(doc,records,[1.6,1.6,1.2,1.1,1.5],font_size=7)
355
+ area_records = [['Construção / referência','Tipo de área','Área real (m²)','Coeficiente','Parcela equivalente (m²)']]
356
  for entries in groups.values():
357
+ areas = OrderedDict()
358
  for row,c,i in entries:
359
  details = [{key:a.get(key) for key in ('descricao','area','coeficiente')} for a in c.get('areasEquivalentes') or []]
360
  # A single area at coefficient 1 contributes no additional explanation.
361
  if not details or (len(details)==1 and number(details[0].get('coeficiente'))==1
362
  and number(c.get('areaTotal'))==number(c.get('areaCalculada'))==number(details[0].get('area'))): continue
363
  areas.setdefault(json.dumps(details,sort_keys=True,ensure_ascii=False),[]).append((row,c,i))
364
+ for identity,subset in areas.items():
365
+ label = entry_scope(subset,groups,show_base=False)
366
+ area_records.extend([
367
+ [label,a.get('descricao') or 'Não informado',fmt(a.get('area')),fmt(a.get('coeficiente'),4),
368
+ fmt(number(a['area'])*number(a['coeficiente'])) if number(a.get('area')) is not None and number(a.get('coeficiente')) is not None else 'Não informado'] for a in json.loads(identity)])
369
+ if len(area_records)>1:
370
+ add_body_text(doc,'Composição das áreas').paragraph_format.keep_with_next = True
371
+ obj = table(doc,area_records,[2.1,2.8,1,1,1.4],auto_fit=False)
372
+ fit_table_to_page(doc,obj)
373
 
374
 
375
  def construction_cub_notes(doc, groups):
tests/test_evo_adjustments.py CHANGED
@@ -5,7 +5,7 @@ from unittest.mock import patch
5
 
6
  from docx import Document
7
  from document.evo_adjustments import applied_reducers, visible_memory
8
- from document.evolutivo import gerar_corpo_evolutivo, condition_description
9
  from document.avaliacoes_importadas import calculation_sections
10
  from document.numbering import NumeradorSecoes
11
  from test_evolutivo_documento import fixture, resolved, all_text
@@ -19,6 +19,42 @@ def body(imported):
19
 
20
 
21
  class AppliedAdjustmentsTests(unittest.TestCase):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def test_neutral_execution_overrides_selected_conditions_and_reference_rates(self):
23
  row=resolved(fixture((2021,)))['avaliacoes'][0]
24
  row['evolutivo']['resultadoComposicao']['redutor88I']=.7
 
5
 
6
  from docx import Document
7
  from document.evo_adjustments import applied_reducers, visible_memory
8
+ from document.evolutivo import gerar_corpo_evolutivo, condition_description, construction_characteristics, construction_groups
9
  from document.avaliacoes_importadas import calculation_sections
10
  from document.numbering import NumeradorSecoes
11
  from test_evolutivo_documento import fixture, resolved, all_text
 
19
 
20
 
21
  class AppliedAdjustmentsTests(unittest.TestCase):
22
+ def test_area_compositions_share_one_table_with_construction_names(self):
23
+ data=fixture((2021,2022))
24
+ for year in data['anos']:
25
+ first=year['construcao']['construcoes'][0]
26
+ first.update(nome='Casa principal',areaTotal=90,areaCalculada=87.5,
27
+ areasEquivalentes=[{'descricao':'área privativa','area':80,'coeficiente':1},
28
+ {'descricao':'varandas','area':10,'coeficiente':.75}])
29
+ second=copy.deepcopy(first)
30
+ second.update(id='segundo',seq=2,nome='Edícula de apoio',areaTotal=50,areaCalculada=45,
31
+ areasEquivalentes=[{'descricao':'área privativa','area':40,'coeficiente':1},
32
+ {'descricao':'área de serviço','area':10,'coeficiente':.5}])
33
+ year['construcao']['construcoes'].append(second)
34
+ doc=Document()
35
+ construction_characteristics(doc,construction_groups(resolved(data)['avaliacoes']))
36
+ tables=[t for t in doc.tables if t.rows[0].cells[1].text=='Tipo de área']
37
+ self.assertEqual(len(tables),1)
38
+ rows=[[c.text for c in row.cells] for row in tables[0].rows]
39
+ self.assertEqual(rows[1:], [
40
+ ['Construção 1 — Casa principal','área privativa','80,00','1,0000','80,00'],
41
+ ['Construção 1 — Casa principal','varandas','10,00','0,7500','7,50'],
42
+ ['Construção 2 — Edícula de apoio','área privativa','40,00','1,0000','40,00'],
43
+ ['Construção 2 — Edícula de apoio','área de serviço','10,00','0,5000','5,00']])
44
+ self.assertEqual([p.text for p in doc.paragraphs if p.text.startswith('Composição das áreas')],['Composição das áreas'])
45
+
46
+ def test_area_changes_preserve_exercise_scope_in_the_unified_table(self):
47
+ data=fixture((2021,2022))
48
+ data['anos'][1]['construcao']['construcoes'][0]['areasEquivalentes'][0]['coeficiente']=.8
49
+ doc=Document()
50
+ construction_characteristics(doc,construction_groups(resolved(data)['avaliacoes']))
51
+ table=next(t for t in doc.tables if t.rows[0].cells[1].text=='Tipo de área')
52
+ self.assertEqual(len(table.rows),3)
53
+ self.assertIn('IPTU 2022',table.cell(1,0).text)
54
+ self.assertIn('IPTU 2023',table.cell(2,0).text)
55
+ self.assertEqual(table.cell(1,4).text,'75,00')
56
+ self.assertEqual(table.cell(2,4).text,'80,00')
57
+
58
  def test_neutral_execution_overrides_selected_conditions_and_reference_rates(self):
59
  row=resolved(fixture((2021,)))['avaliacoes'][0]
60
  row['evolutivo']['resultadoComposicao']['redutor88I']=.7