Skip to content

Commit

Permalink
Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
folix-01 committed Feb 26, 2025
1 parent cd9a372 commit 1b0251a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Changelog
alphabetically after the current form fields.
[folix-01]

- Add current form columns to CSV export event if field are empty.
[folix-01]


3.2.1 (2025-01-09)
------------------
Expand Down
48 changes: 40 additions & 8 deletions src/collective/volto/formsupport/restapi/services/form_data/csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from plone.restapi.serializer.converters import json_compatible
from plone.restapi.services import Service
from zope.component import getMultiAdapter
from collective.volto.formsupport.utils import get_blocks
from copy import deepcopy

import csv

Expand All @@ -23,12 +25,37 @@ def __init__(self, context, request):
block_type = block.get("@type", "")
if block_type == "form":
self.form_block = block
self.form_block_id = id

if self.form_block:
for field in self.form_block.get("subblocks", []):
field_id = field["field_id"]
self.form_fields_order.append(field_id)

def get_form_fields(self):
blocks = get_blocks(self.context)

if not blocks:
return {}
form_block = {}
for id, block in blocks.items():
if id != self.form_block_id:
continue
block_type = block.get("@type", "")
if block_type == "form":
form_block = deepcopy(block)
if not form_block:
return {}

subblocks = form_block.get("subblocks", [])

# Add the 'custom_field_id' field back in as this isn't stored with each subblock
for index, field in enumerate(subblocks):
if form_block.get(field["field_id"]):
subblocks[index]["custom_field_id"] = form_block.get(field["field_id"])

return subblocks

def get_ordered_keys(self, record):
"""
We need this method because we want to maintain the fields order set in the form.
Expand Down Expand Up @@ -61,8 +88,12 @@ def render(self):
data = data.encode("utf-8")
self.request.response.write(data)

def get_fields_labels(self, item):
return item.attrs.get("fields_labels", {})
def get_fields_labels(self):
return {
x["field_id"]: x.get("custom_field_id", x.get("label", x["field_id"]))
for x in self.get_form_fields()
if x.get("field_type", "") != "static_text"
}

def get_data(self):
store = getMultiAdapter((self.context, self.request), IFormDataStore)
Expand All @@ -71,24 +102,23 @@ def get_data(self):
columns = []
legacy_columns = []
rows = []
fields_labels = self.get_fields_labels()

for item in store.search():
data = {}
fields_labels = self.get_fields_labels(item)

for k in self.get_ordered_keys(item):
if k in SKIP_ATTRS:
continue

value = item.attrs.get(k, None)
label = fields_labels.get(k, k)
label = {**item.attrs.get("fields_labels", {}), **fields_labels}.get(
k, k
)

if k not in self.form_fields_order:
if k not in self.form_fields_order and label not in legacy_columns:
legacy_columns.append(label)

elif label not in columns and label not in fixed_columns:
columns.append(label)

data[label] = json_compatible(value)

for k in fixed_columns:
Expand All @@ -98,8 +128,10 @@ def get_data(self):

rows.append(data)

columns.extend(fields_labels.values())
columns.extend(fixed_columns)
columns.extend(sorted(legacy_columns))

writer = csv.DictWriter(sbuf, fieldnames=columns, quoting=csv.QUOTE_ALL)
writer.writeheader()

Expand Down

0 comments on commit 1b0251a

Please sign in to comment.