Unable to generate PDF quotes after migrating to 7.14.6 #5334

Open
opened 2026-02-20 16:59:44 -05:00 by deekerman · 2 comments
Owner

Originally created by @vmw on GitHub (Jul 1, 2025).

Issue

Problem

After migrating to SuiteCRM version 7.14.6 (migrating from from 7.11.18 to 7.12.8 to 7.14.6) we are no longer able to generate PDF quotes.

Reproduction

  1. From within our installation, we just find an opportunity, and then click on "create quote".
  2. We populate and fill out the quote field.
  3. We attempt to generate a pdf-quote

Expected

We get generate a PDF quote.

Observed

When trying to generate a quote,

TCPDF ERROR: Some data has already been output, can't send PDF file.

The specific error message is being printed by:

/langford/suitecrm/vendor/tecnickcom/tcpdf/tcpdf.php:7745

This only occurs when trying to generate PDF-quotes. We are otherwise able to generate PDF reports and invoices. Just not quotes.

Workaround

After making some code changes, discussed below, I was able to get to a point where I can get pdf-quotes working, but ONLY if they do NOT have a corresponding opportunity associated with them. If the quote has an opportunity associated with it, I continue to get the error above.

Discussion

Given that this occurred after updating SuiteCRM, I thought it might be related to the shift from php7.4 to 8.2.

More specifically, I believe it might be due to how php82 vs php74 handle type inferences. After the initial upgrade, we had problems converting leads to opportunities, and it was because not all of the custom lead fields had default attributes. When using php82, some of the operations that previously worked with null inputs failed with an error message. After updating those attributes to have default values, I was able to get the lead conversion working.

This may also be related to issue #10650 , but applying the commit in the pull request did not seem to fix the issue.

Possible Fix

Attempts to fix

After some experimenting with changing some of the quote properties, and modifying the templates, I was able to trigger the following error:

2025/06/30 18:56:04 [error] 2741744#0: *1025 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught TypeError: round(): Argument #1 ($num) must be of type int|float, array given in /suitecrm/modules/Currencies/Currency.php:412
Stack trace:
#0 /web/suitecrm/modules/Currencies/Currency.php(412): round(Array, '2')
#1 /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php(170): format_number(Array)
#2 /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php(37): templateParser::parse_template_bean('<tr><td style="...', 'aos_products_qu...', Object(AOS_Products_Quotes))
#3 /web/suitecrm/modules/AOS_PDF_Templates/generatePdf.php(353): templateParser::parse_template('<tr><td style="...', Array)
#4 /web/suitecrm/modules/AOS_PDF_Templates/generatePdf.php(242): populate_product_lines('<table style="w...', Array)
#5 /web/suitecrm/modules/AOS_PDF_Templates/generatePdf.php(133): populate_group_lines('<table style="h...', Array, Array)

This seemed promising, as the previous issue mentioned there may be some problems with that part of the code. In addition, this seems to be related to the change from php7.2 to 8.2, as indicated here:

https://stackoverflow.com/questions/75591411/abs-argument-1-num-must-be-of-type-intfloat-string-given-in-php-8-2

So I tried doing exactly what stackover flow suggested and modified:

suitecrm/modules/Currencies/Currencies.php:412 to read:

[Currencies]$ diff Currency.php Currency.php.old
412,417c412,413
<           if(is_array($amount)){
<               $amount = number_format(round((float)$amount, $round), $decimals, $dec_sep, $num_grp_sep);
<           } else {
<               $amount = number_format(round($amount, $round), $decimals, $dec_sep, $num_grp_sep);
<           }
<           $amount = format_place_symbol($amount, $symbol, (empty($params['symbol_space']) ? false : true));
---
>         $amount = number_format(round($amount, $round), $decimals, $dec_sep, $num_grp_sep);
>         $amount = format_place_symbol($amount, $symbol, (empty($params['symbol_space']) ? false : true));

This resulted in the following error message:

Warning: Attempt to read property "field_defs" on bool in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66

Warning: foreach() argument must be of type array|object, null given in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66

Warning: Attempt to read property "field_defs" on bool in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66

Warning: foreach() argument must be of type array|object, null given in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66

Warning: Attempt to read property "field_defs" on bool in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66

Warning: foreach() argument must be of type array|object, null given in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66

After change suitecrm/modules/AOS_PDF_Templates:131 as follows:

[AOS_PDF_Templates]# diff templateParser.php templateParser.php.old
66d65
<       if (is_bool($focus) == false) {
131,132c130
<       } // end foreach()
<       } //end if is_array
---
>         } // end foreach()

This change got me to the point where I realized that I could generate a pdf quote from our templates, but ONLY if there was no opportunity attached to the quote.

I'm not able to get any additional debugging messages, and, I think perhaps some one of the changes I made to get to the point that I was able to work around the issue may have caused additional problems.

Given that the first lead I had was with Currencies.php, I think this issue may somehow be related to #10650 , but I don't understand how the presence of the opportunity field could cause additional issues here.

Versions

This occurred on SuiteCRM 7.14.6

Steps to Reproduce the Issue

1.
2.
3.
...

Context

This bug is impacting our ability to generate PDF quotes.

  1. From within our installation, we just find an opportunity, and then click on "create quote".
  2. We populate and fill out the quote field.
  3. We attempt to generate a pdf-quote

Version

7.14.8

What browser are you currently using?

Firefox

Browser Version

Firefox 139.0.4 (64 bit)

Environment Information

mariadb from 11.0.2-MariaDB, client 15.2 for Linux (x86_64) using readline 5.1, PHP8.2

Operating System and Version

ArchLinux

Originally created by @vmw on GitHub (Jul 1, 2025). ### Issue ### Problem After migrating to SuiteCRM version 7.14.6 (migrating from from 7.11.18 to 7.12.8 to 7.14.6) we are no longer able to generate PDF quotes. ### Reproduction 1. From within our installation, we just find an opportunity, and then click on "create quote". 2. We populate and fill out the quote field. 3. We attempt to generate a pdf-quote ### Expected We get generate a PDF quote. ### Observed When trying to generate a quote, ``` TCPDF ERROR: Some data has already been output, can't send PDF file. ``` The specific error message is being printed by: `/langford/suitecrm/vendor/tecnickcom/tcpdf/tcpdf.php:7745` This only occurs when trying to generate PDF-quotes. We are otherwise able to generate PDF reports and invoices. Just not quotes. ### Workaround After making some code changes, discussed below, I was able to get to a point where I can get pdf-quotes working, but ONLY if they do NOT have a corresponding opportunity associated with them. If the quote has an opportunity associated with it, I continue to get the error above. ### Discussion Given that this occurred after updating SuiteCRM, I thought it might be related to the shift from php7.4 to 8.2. More specifically, I believe it might be due to how php82 vs php74 handle type inferences. After the initial upgrade, we had problems converting leads to opportunities, and it was because not all of the custom lead fields had default attributes. When using php82, some of the operations that previously worked with null inputs failed with an error message. After updating those attributes to have default values, I was able to get the lead conversion working. This may also be related to issue #10650 , but applying the commit in the pull request did not seem to fix the issue. ### Possible Fix ### Attempts to fix After some experimenting with changing some of the quote properties, and modifying the templates, I was able to trigger the following error: ``` 2025/06/30 18:56:04 [error] 2741744#0: *1025 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught TypeError: round(): Argument #1 ($num) must be of type int|float, array given in /suitecrm/modules/Currencies/Currency.php:412 Stack trace: #0 /web/suitecrm/modules/Currencies/Currency.php(412): round(Array, '2') #1 /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php(170): format_number(Array) #2 /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php(37): templateParser::parse_template_bean('<tr><td style="...', 'aos_products_qu...', Object(AOS_Products_Quotes)) #3 /web/suitecrm/modules/AOS_PDF_Templates/generatePdf.php(353): templateParser::parse_template('<tr><td style="...', Array) #4 /web/suitecrm/modules/AOS_PDF_Templates/generatePdf.php(242): populate_product_lines('<table style="w...', Array) #5 /web/suitecrm/modules/AOS_PDF_Templates/generatePdf.php(133): populate_group_lines('<table style="h...', Array, Array) ``` This seemed promising, as the previous issue mentioned there may be some problems with that part of the code. In addition, this seems to be related to the change from php7.2 to 8.2, as indicated here: https://stackoverflow.com/questions/75591411/abs-argument-1-num-must-be-of-type-intfloat-string-given-in-php-8-2 So I tried doing exactly what stackover flow suggested and modified: suitecrm/modules/Currencies/Currencies.php:412 to read: ``` [Currencies]$ diff Currency.php Currency.php.old 412,417c412,413 < if(is_array($amount)){ < $amount = number_format(round((float)$amount, $round), $decimals, $dec_sep, $num_grp_sep); < } else { < $amount = number_format(round($amount, $round), $decimals, $dec_sep, $num_grp_sep); < } < $amount = format_place_symbol($amount, $symbol, (empty($params['symbol_space']) ? false : true)); --- > $amount = number_format(round($amount, $round), $decimals, $dec_sep, $num_grp_sep); > $amount = format_place_symbol($amount, $symbol, (empty($params['symbol_space']) ? false : true)); ``` This resulted in the following error message: ``` Warning: Attempt to read property "field_defs" on bool in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66 Warning: foreach() argument must be of type array|object, null given in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66 Warning: Attempt to read property "field_defs" on bool in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66 Warning: foreach() argument must be of type array|object, null given in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66 Warning: Attempt to read property "field_defs" on bool in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66 Warning: foreach() argument must be of type array|object, null given in /web/suitecrm/modules/AOS_PDF_Templates/templateParser.php on line 66 ``` After change suitecrm/modules/AOS_PDF_Templates:131 as follows: ``` [AOS_PDF_Templates]# diff templateParser.php templateParser.php.old 66d65 < if (is_bool($focus) == false) { 131,132c130 < } // end foreach() < } //end if is_array --- > } // end foreach() ``` This change got me to the point where I realized that I could generate a pdf quote from our templates, but ONLY if there was no opportunity attached to the quote. I'm not able to get any additional debugging messages, and, I think perhaps some one of the changes I made to get to the point that I was able to work around the issue may have caused additional problems. Given that the first lead I had was with Currencies.php, I think this issue may somehow be related to #10650 , but I don't understand how the presence of the opportunity field could cause additional issues here. ### Versions This occurred on SuiteCRM 7.14.6 ### Steps to Reproduce the Issue ```bash 1. 2. 3. ... ``` ### Context This bug is impacting our ability to generate PDF quotes. 1. From within our installation, we just find an opportunity, and then click on "create quote". 2. We populate and fill out the quote field. 3. We attempt to generate a pdf-quote ### Version 7.14.8 ### What browser are you currently using? Firefox ### Browser Version Firefox 139.0.4 (64 bit) ### Environment Information mariadb from 11.0.2-MariaDB, client 15.2 for Linux (x86_64) using readline 5.1, PHP8.2 ### Operating System and Version ArchLinux
Author
Owner

@vmw commented on GitHub (Jul 4, 2025):

Additional Discussion

The root cause of this issue is that, for some reason, by the time we hit

modules/AOS_PDF_Templates/generatePdf.php:142

the output buffer has been written to with a single space " " in it.

As a consequence, when we hit vendor/tecnickcom/tcpdf/tcpdf.php:7744 , we return true for ob_get_contents().

Within generatePdf.php, the output buffer is empty, until we hit:

generatePdf.php :~55

$bean = BeanFactory::getBean($_REQUEST['module'], $_REQUEST['uid']);

For some reason, which I have not yet finished investigating, after this call, the output buffer is filled with a space.

Workaround

To avoid this issue, I have added a blanket ob_flush() in modules/AOS_PDF_Templates/generatePdf.php:142

right before the if ( $task === 'pdf' || ... ) statement. This seems reasonably safe and ensures that the output buffer is empty prior to attempting to generate a pdf.

If I have time over the weekend, I'll see whether I can further isolate the cause of this issue, or else I will simply add the line to flush the output buffer prior to attempting to generate a pdf.

@vmw commented on GitHub (Jul 4, 2025): ### Additional Discussion The root cause of this issue is that, for some reason, by the time we hit modules/AOS_PDF_Templates/generatePdf.php:142 the output buffer has been written to with a single space " " in it. As a consequence, when we hit vendor/tecnickcom/tcpdf/tcpdf.php:7744 , we return true for ob_get_contents(). Within generatePdf.php, the output buffer is empty, until we hit: generatePdf.php :~55 $bean = BeanFactory::getBean($_REQUEST['module'], $_REQUEST['uid']); For some reason, which I have not yet finished investigating, after this call, the output buffer is filled with a space. ### Workaround To avoid this issue, I have added a blanket ob_flush() in modules/AOS_PDF_Templates/generatePdf.php:142 right before the if ( $task === 'pdf' || ... ) statement. This seems reasonably safe and ensures that the output buffer is empty prior to attempting to generate a pdf. If I have time over the weekend, I'll see whether I can further isolate the cause of this issue, or else I will simply add the line to flush the output buffer prior to attempting to generate a pdf.
Author
Owner

@johnM2401 commented on GitHub (Aug 5, 2025):

Hey!

Thank you for raising this issue.

I've given this some tries locally, but I haven't been able to replicate the issue as of yet.
I've tried the Quotes->Print as PDF action with various Currencies / Thousand Separators / Related Opportunities, but it appears to be generating the PDF as expected.

Could you perhaps share some more information to help us in trying to narrow this down?

Anything that might seem relevant, such as:

  • Are you using any custom-added currencies? If so, have you set a symbol and conversion rate for these?
  • Does your PDF template have any Opportunity-related fields on it?
  • Are you using a specific Thousand / Decimal Separator value that is different from the OOTB install? (ie: . for Decimal / , for Thousand)
  • Does this happen just for "Print as PDF" or are all three actions affected? (ie: Print PDF / Email PDF / Email Quotation)

Thank you again for raising this, and thank you for your time investigating!

@johnM2401 commented on GitHub (Aug 5, 2025): Hey! Thank you for raising this issue. I've given this some tries locally, but I haven't been able to replicate the issue as of yet. I've tried the ```Quotes```->```Print as PDF``` action with various Currencies / Thousand Separators / Related Opportunities, but it appears to be generating the PDF as expected. Could you perhaps share some more information to help us in trying to narrow this down? Anything that might seem relevant, such as: - Are you using any custom-added currencies? If so, have you set a symbol and conversion rate for these? - Does your PDF template have any Opportunity-related fields on it? - Are you using a specific Thousand / Decimal Separator value that is different from the OOTB install? (ie: ```.``` for Decimal / ```,``` for Thousand) - Does this happen just for "Print as PDF" or are all three actions affected? (ie: Print PDF / Email PDF / Email Quotation) <br> Thank you again for raising this, and thank you for your time investigating!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/SuiteCRM-SuiteCRM#5334
No description provided.