Skip to content

Commit 61066f6

Browse files
author
Jens Kürten
committed
feat: Add example for generating a basic report using custom operations
1 parent b0a3353 commit 61066f6

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

docs/examples/basic_report.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Basic Report
2+
3+
This example shows, how you can use custom operations to generate a basic report on a document and attach that report to the document.
4+
5+
The example uses [python-docx](https://python-docx.readthedocs.io/en/latest/) to generate a Word file.
6+
To install the library in your Function, you need to add it to the `requirements.txt`:
7+
8+
```requirements.txt
9+
contactsoftware-functions
10+
python-docx
11+
```
12+
13+
```python
14+
import os
15+
import tempfile
16+
from datetime import datetime
17+
18+
import requests
19+
from docx import Document as DocxDocument
20+
21+
from csfunctions import MetaData, Service
22+
from csfunctions.events import CustomOperationDocumentEvent
23+
from csfunctions.objects import Document
24+
25+
26+
def simple_report(metadata: MetaData, event: CustomOperationDocumentEvent, service: Service):
27+
"""
28+
Generates a simple report for each document the custom operation is called on.
29+
The report contains basic information about the document and is saved as a new file
30+
named "myreport.docx" within the document.
31+
"""
32+
33+
for document in event.data.documents:
34+
# generate a report for each document
35+
report = _create_report(document, metadata)
36+
37+
temp_file_path = None
38+
try:
39+
# we need to use a tempfile, because the rest of the filesystem is read-only
40+
with tempfile.NamedTemporaryFile(suffix=".docx", delete=False) as tmp:
41+
temp_file_path = tmp.name
42+
report.save("test.docx")
43+
44+
# check if the document already has a report file, so we can overwrite it
45+
file_name = "myreport.docx"
46+
existing_file = next((file for file in document.files if file.cdbf_name == file_name), None)
47+
48+
with open(temp_file_path, "rb") as file_stream:
49+
if existing_file:
50+
# overwrite the existing report file
51+
service.file_upload.upload_file_content(
52+
file_object_id=existing_file.cdb_object_id, stream=file_stream, check_access=False
53+
)
54+
else:
55+
# create a new one
56+
service.file_upload.upload_new_file(
57+
parent_object_id=document.cdb_object_id, # type: ignore
58+
filename=file_name,
59+
stream=file_stream,
60+
check_access=False,
61+
)
62+
finally:
63+
if temp_file_path:
64+
# Clean up temp file
65+
os.unlink(temp_file_path)
66+
67+
68+
def _fetch_person_name(persno: str, metadata: MetaData) -> str | None:
69+
"""Fetches the name of a person given their personnel number via GraphQL."""
70+
graphql_url = str(metadata.db_service_url).rstrip("/") + "/graphql/v1"
71+
headers = {"Authorization": f"Bearer {metadata.service_token}"}
72+
73+
query = f"""
74+
{{
75+
persons(personalnummer: \"{persno}\", max_rows: 1) {{
76+
name
77+
}}
78+
}}
79+
"""
80+
response = requests.post(
81+
graphql_url,
82+
headers=headers,
83+
json={"query": query},
84+
)
85+
response.raise_for_status()
86+
data = response.json()
87+
persons = data["data"]["persons"]
88+
if persons:
89+
return persons[0]["name"]
90+
return None
91+
92+
93+
def _create_report(document: Document, metadata: MetaData) -> DocxDocument:
94+
"""Creates a simple Word report for the given document."""
95+
doc = DocxDocument()
96+
97+
doc.add_heading("Simple Report", 0)
98+
99+
report_time_string = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
100+
doc.add_paragraph(f"Report generated on: {report_time_string}")
101+
102+
# add some basic information about the document
103+
doc.add_heading("Document Information", level=1)
104+
doc.add_paragraph(f"Document ID: {document.z_nummer}@{document.z_index}")
105+
doc.add_paragraph(f"Title: {document.titel}")
106+
doc.add_paragraph(f"Created On: {document.cdb_cdate}")
107+
108+
# Fetch the name of the person who created the document via GraphQL
109+
person_name = _fetch_person_name(document.cdb_cpersno, metadata)
110+
doc.add_paragraph(f"Created By: {person_name or document.cdb_cpersno}")
111+
112+
return doc
113+
114+
```

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ nav:
4646
- examples/enforce_field_rules.md
4747
- examples/field_calculation.md
4848
- examples/workflows.md
49+
- examples/basic_report.md
4950
- Reference:
5051
- reference/events.md
5152
- reference/objects.md

0 commit comments

Comments
 (0)