Closed bos4711 closed 6 months ago
The format used to output the date with DATE_DUE_YMD param should be the one defined into the language of the output PDF or ODT (so if you generated the PDF for a french customer, it will use the language of the customer so french format). For which document template do you have this problem ?
The error is not in a document template, but in email template. All our customers are set to use sv_SE language. PDF output is fine (YYYY-MM-DD) but the email template when sending the PDF is wrong.
Sidenote: we have deleted all languages except for sv_SE and en_US, and we have edited both these to use YYYY-MM-DD everywhere, so where DATE_DUE_YMD gets its format from is unbeknownst to me.
This issue is stale because it has been open 1 year with no activity. If this is a bug, please comment to confirm it is still present on latest stable version. if this is a feature request, please comment to notify the request is still relevant and not yet covered by latest stable version. This issue may be closed automatically by stale bot in 10 days (you should still be able to re-open it if required).
Bug still exists in v19.
@bos4711 try with this fix : https://github.com/Dolibarr/dolibarr/pull/28595
@hregis That's the exact same definitions we use today, and they don't work.
I have tried to trace the code to see where the error actually occurs but I haven't found it yet. The only occurence to __DATE_DUEYMD is in functions.lib.php
:
./core/lib/functions.lib.php: $substitutionarray['__DATE_DUE_YMD__'] = is_object($object) ? (isset($object->date_lim_reglement) ? dol_print_date($object->date_lim_reglement, 'day', 0, $outputlangs) : null) : '';
So maybe the source of the error is in dol_print_date()
, or wrong parameters passed to it?
Update: in the quoted line above, if we change 'day' to 'dayrfc' then the result is correct. So something in dol_print_date()
messes up the format when using this variable substitution.
@eldy an idea?
I have played around in our sandbox-installation and I think I have found a clue. In functions.lib.php
, where the DATE_DUE_YMD is substituted, I added three lines of test code:
$substitutionarray['__DATE_YMD__'] = is_object($object) ? (isset($object->date) ? dol_print_date($object->date, 'day', 0, $outputlangs) : null) : '';
$substitutionarray['__DATE_DUE_YMD__'] = is_object($object) ? (isset($object->date_lim_reglement) ? dol_print_date($object->date_lim_reglement, 'day', 0, $outputlangs) : null) : '';
$substitutionarray['__TEST__'] = "We are here";
print_r($substitutionarray);
print "<br><br><br>";
When applying the email template, which triggers the error, the substitution is somehow run twice and this can be seen on the screen:
This means the first run of substitution the date format is correct, but since it runs a second time (why?) the date format is replaced to the incorrect one.
dol_print_date()
always returns the correct date at all times.
The substitution is using the language file of the $outputlang that should be the language of user and not necesserly yours. So the format for lang used is not always the ine in main.lang but can be the one in main.lang of the other language file.
Since the template used is made with sv_SE set, shouldn't the main.lang for sv_SE be used no matter what language the user or anything else has set?
I've dived into this issue some more. On my computer, I use en_US as locale. In dolibarr admin interface, we use en_US. In Dolibarr invoices, sales orders, etc we use sv_SE. I had a hunch that because my computer locale is en_US, Dolibarr/PHP might have been confused so I switched locale to sv_SE just to test but the error remains.
Then I went to functions.lib.php
again and right under the DATE_DUE_YMD-substitution I added this line just to see what happens:
print $outputlangs->defaultlang . " --- " . dol_print_date($object->date_lim_reglement, 'day', 0, $outputlangs) . "<br>";
Now, when I apply the email template I see two lines:
en_US --- 2023-09-28 sv_SE --- 28/09/2023
Which is very weird, because I have altered the Format-strings in main.lang in both en_US and sv_SE to be exactly the same (%Y-%m-%d). I have also deleted every other lang directory so only en_US/sv_SE remains, and as you can see above the first line is correct (Y-m-d) but the second run (why does it run twice when applying email template?) it changes back to d/m/Y, and there is no trace of this format in main.lang or anywhere else.
Yet Dolibarr somehow picks that format from somewhere, but I cannot find from where. Is that a PHP-default or something?
(I'm aware all my problems can be solved by changing to "dayrfc" in dol_print_date()
but there obviously exists a bug here somewhere and I really want to hunt it down)
In dol_print_date()
I added a stacktrace and print $ret;
just before the return of the function, and this happens when clicking "Apply template":
2023-11-16
0 dol_print_date() called at [/var/www/dolibarr.17/core/lib/functions.lib.php:8058]
1 getCommonSubstitutionArray() called at [/var/www/dolibarr.17/core/class/html.formmail.class.php:1531]
2 FormMail->setSubstitFromObject() called at [/var/www/dolibarr.17/core/tpl/card_presend.tpl.php:233]
3 include(/var/www/dolibarr.17/core/tpl/card_presend.tpl.php) called at [/var/www/dolibarr.17/compta/facture/card.php:5819]
16/11/2023
0 dol_print_date() called at [/var/www/dolibarr.17/core/lib/functions.lib.php:8058]
1 getCommonSubstitutionArray() called at [/var/www/dolibarr.17/core/tpl/card_presend.tpl.php:236]
2 include(/var/www/dolibarr.17/core/tpl/card_presend.tpl.php) called at [/var/www/dolibarr.17/compta/facture/card.php:5819]
That is, when FormMail->setSubstitFromObject()
is run, the returned substitution date is correct. In the second run, this function is not called and the returned date format gets wrong.
I tried to manually force the code in card_presend.tpl.php
to run FormMail->setSubstitFromObject()
every time just before getCommonSubstitutionArray()
is called, but somehow this does not work. Currently it resides in an if-case just before getCommonSubstitutionArray()
. Even when removing the if-clause, the function is not called during the second run.
I think this is the root cause for the bug, but right now I cannot get any further.
Now I added print "We're in card_presend.tpl.php<br>";
just before the call to FormMail->setSubstitFromObject()
and clicked "apply template again". This is the output:
We're in card_presend.tpl.php
2023-11-16
0 dol_print_date() called at [/var/www/dolibarr.17/core/lib/functions.lib.php:8058]
1 getCommonSubstitutionArray() called at [/var/www/dolibarr.17/core/class/html.formmail.class.php:1531]
2 FormMail->setSubstitFromObject() called at [/var/www/dolibarr.17/core/tpl/card_presend.tpl.php:234]
3 include(/var/www/dolibarr.17/core/tpl/card_presend.tpl.php) called at [/var/www/dolibarr.17/compta/facture/card.php:5819]
16/11/2023
0 dol_print_date() called at [/var/www/dolibarr.17/core/lib/functions.lib.php:8058]
1 getCommonSubstitutionArray() called at [/var/www/dolibarr.17/core/tpl/card_presend.tpl.php:237]
2 include(/var/www/dolibarr.17/core/tpl/card_presend.tpl.php) called at [/var/www/dolibarr.17/compta/facture/card.php:5819]
This means the first run is because of "Apply template". The second run comes from somewhere else, like the call is cached or similiar. This does not make sense to me but I hope it does for someone else.
This was an incredibly hard-to-find bug, but I have finally found the root cause.
The bug occurs because the "main.lang" is not loaded properly when Dolibarr switches to sv_SE during the substitution process. Adding a load("main") solves everything.
I will create a fix / PR shortly.
Bug
v15.0.0
The code in
htdocs/core/lib/functions.lib.php
somehow always returns in DMY-format even when our main.lang formats are defined as this:FormatDateShort=%Y-%m-%d FormatDateShortInput=%Y-%m-%d FormatDateShortJava=yyyy-MM-dd FormatDateShortJavaInput=yyyy-MM-dd FormatDateShortJQuery=yy-mm-dd FormatDateShortJQueryInput=yy-mm-dd FormatHourShortJQuery=tt:mm FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%Y-%m-%d FormatDateText=%Y-%m-%d FormatDateHourShort=%Y-%m-%d %H:%M FormatDateHourSecShort=%Y-%m-%d %I:%M:%S %p FormatDateHourTextShort=%d %b %Y, %H:%M FormatDateHourText=%d %B %Y, %H:%M
We use DATE_DUE_YMD in email templates for invoices, and for today's email it contains "10/02/2022" when it should be "2022-02-10".
Reproducable every time.
The email template looks like this:
Vi saknar betalning för faktura __REF__ med förfallodatum __DATE_DUE_YMD__. Kopia på fakturan finns bifogad.
Environment Version
15.0.0
Environment OS
No response
Environment Web server
No response
Environment PHP
No response
Environment Database
No response
Environment URL(s)
No response
Expected and actual behavior
It should respect the date-format specified in main.lang
Steps to reproduce the behavior
No response
Attached files
No response