33from plone .restapi .serializer .converters import json_compatible
44from plone .restapi .services import Service
55from zope .component import getMultiAdapter
6+ from collective .volto .formsupport .utils import get_blocks
7+ from copy import deepcopy
68
79import csv
810
@@ -23,12 +25,37 @@ def __init__(self, context, request):
2325 block_type = block .get ("@type" , "" )
2426 if block_type == "form" :
2527 self .form_block = block
28+ self .form_block_id = id
2629
2730 if self .form_block :
2831 for field in self .form_block .get ("subblocks" , []):
2932 field_id = field ["field_id" ]
3033 self .form_fields_order .append (field_id )
3134
35+ def get_form_fields (self ):
36+ blocks = get_blocks (self .context )
37+
38+ if not blocks :
39+ return {}
40+ form_block = {}
41+ for id , block in blocks .items ():
42+ if id != self .form_block_id :
43+ continue
44+ block_type = block .get ("@type" , "" )
45+ if block_type == "form" :
46+ form_block = deepcopy (block )
47+ if not form_block :
48+ return {}
49+
50+ subblocks = form_block .get ("subblocks" , [])
51+
52+ # Add the 'custom_field_id' field back in as this isn't stored with each subblock
53+ for index , field in enumerate (subblocks ):
54+ if form_block .get (field ["field_id" ]):
55+ subblocks [index ]["custom_field_id" ] = form_block .get (field ["field_id" ])
56+
57+ return subblocks
58+
3259 def get_ordered_keys (self , record ):
3360 """
3461 We need this method because we want to maintain the fields order set in the form.
@@ -61,8 +88,12 @@ def render(self):
6188 data = data .encode ("utf-8" )
6289 self .request .response .write (data )
6390
64- def get_fields_labels (self , item ):
65- return item .attrs .get ("fields_labels" , {})
91+ def get_fields_labels (self ):
92+ return {
93+ x ["field_id" ]: x .get ("custom_field_id" , x .get ("label" , x ["field_id" ]))
94+ for x in self .get_form_fields ()
95+ if x .get ("field_type" , "" ) != "static_text"
96+ }
6697
6798 def get_data (self ):
6899 store = getMultiAdapter ((self .context , self .request ), IFormDataStore )
@@ -71,24 +102,23 @@ def get_data(self):
71102 columns = []
72103 legacy_columns = []
73104 rows = []
105+ fields_labels = self .get_fields_labels ()
74106
75107 for item in store .search ():
76108 data = {}
77- fields_labels = self .get_fields_labels (item )
78109
79110 for k in self .get_ordered_keys (item ):
80111 if k in SKIP_ATTRS :
81112 continue
82113
83114 value = item .attrs .get (k , None )
84- label = fields_labels .get (k , k )
115+ label = {** item .attrs .get ("fields_labels" , {}), ** fields_labels }.get (
116+ k , k
117+ )
85118
86- if k not in self .form_fields_order :
119+ if k not in self .form_fields_order and label not in legacy_columns :
87120 legacy_columns .append (label )
88121
89- elif label not in columns and label not in fixed_columns :
90- columns .append (label )
91-
92122 data [label ] = json_compatible (value )
93123
94124 for k in fixed_columns :
@@ -98,8 +128,10 @@ def get_data(self):
98128
99129 rows .append (data )
100130
131+ columns .extend (fields_labels .values ())
101132 columns .extend (fixed_columns )
102133 columns .extend (sorted (legacy_columns ))
134+
103135 writer = csv .DictWriter (sbuf , fieldnames = columns , quoting = csv .QUOTE_ALL )
104136 writer .writeheader ()
105137
0 commit comments