The task
I've got a pdf in XSTRING, I've got some PEPPOL XML. I want to produce from this a ZUGFeRD PDF.
With my first solution, I was testing and it worked fine. PDF generated from an Adobe Form, converted to ZUGFeRD.
But then, as I was refining my solution, it suddenly stopped working. Worse, it worked from some invoice types, but not for others.
Hopefully, this will help anyone who struggles with what I've been struggling over for the last week.
The symptoms
This is my code
TRY.
DATA(pdf_convertor) = NEW cl_fp_conv_pdfa( ).
r_result = pdf_convertor->run_convert_zf_1p0(
iv_pdf = i_pdf
iv_invoice_xml = i_xml
iv_invoice_xml_descr = 'ZUGFeRD Invoice' "#EC NOTEXT
iv_conflevel = cl_fp_conv_pdfa=>co_zugferd_conf_lev_comfort ).
CATCH cx_fp_conv INTO DATA(error).
MESSAGE error TYPE 'E'.
ENDTRY.
This was throwing a cx_fp_conv exception. The error message wasn't very enlightening. A little digging found this code in the
run_convert_zf_1p0 method.
* Execute, call ADS.
TRY.
mo_pdf_obj->execute( ).
CATCH cx_fp_runtime_usage
cx_fp_runtime_system
cx_fp_runtime_internal INTO lx_fp_runtime.
IF lx_fp_runtime->textid EQ cx_fp_runtime_system=>ads_error AND
lx_fp_runtime->errmsgshort cs 'Validation of PDFA'. "#EC NOTEXT
RAISE EXCEPTION TYPE cx_fp_conv EXPORTING
textid = cx_fp_conv=>error_pdfa_convert.
ELSE.
RAISE EXCEPTION TYPE cx_fp_conv EXPORTING
textid = cx_fp_conv=>error_ads.
ENDIF.
ENDTRY.
Message to the developer of this code: please add previous = lx_fp_runtime to the EXPORTING of the RAISE EXCEPTIONs. Otherwise we have to debug to find the true cause of the error! It's really very remiss of you. ?
By looking at
lx_fp_runtime in the debugger, I could see this rather cryptic error message (Actually, this is from the trace, but it's basically the same).
Processing exception during a "ConvertToPdfa" operation.
Request start time: Fri Nov 20 17:25:12 CET 2020
com.adobe.ProcessingException: com.adobe.ProcessingException: com.adobe.ProcessingException:
PDFA conversion failed. ANNOT_CREATE permission required for this operation
Resolution
I searched everywhere for some indication of what this meant. I compared the pdfs where the conversion worked with those that didn't -> at hex level and throught Acrobat. I looked on support.sap.com, and in ZUGFeRD forums.
I figured out the issue was that there was some kind of complexity in the PDFs that worked that weren't on the ones that did. Eventually, I looked at the properties of the pdfs in Acrobat, and, specifically, the security settings. Then I saw it - the PDF that wasn't working had under Document Security:
Security Method: Password Security.
All contents of the document are encrypted.
Whereas the PDF that was working had:
Security Method: No Security.
But how? I checked the Adobe Form definitions, but nothing different was there.
In the meantime, I decided to take the four different print programs we had, and unify them into one. At this point, ALL the pdf conversion failed.
That was my lightbulb moment. I compared my new unified print program with the one for the PDFs that did work, and found the difference lay here:
ls_outputparams-noprint = abap_true.
That was the issue. The old print program for the PDFs I could convert didn't have this. While working on my solution, I wanted to stop the pdf being sent to the spool. I mistakenly assumed this meant "don't print". But of course, it doesn't. It means "Does not allow print output from the print preview". As it says in the
help... And I didn't even need to suppress sending the output to the spool.
ls_outputparams-getpdf = abap_true.
does that perfectly well.
noprint sets the security on the generated PDF with a generated random password in order to prevent printing.
I removed the offending line, and all is now working.
TL;DR
1. RTFM (Read the flippin' manual).
2. You can't convert a pdf with any kind of security on it nor with comments nor with annotations into the ZUGFeRD format.