dolibarr 25.0.0-alpha
html_cerfafr.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2006 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2012 Marcos García <marcosgdf@gmail.com>
6 * Copyright (C) 2014-2020 Alexandre Spangaro <aspangaro@open-dsi.fr>
7 * Copyright (C) 2015 Benoit Bruchard <benoitb21@gmail.com>
8 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2025 Frédéric France <frederic.france@free.fr>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
30require_once DOL_DOCUMENT_ROOT.'/core/modules/dons/modules_don.php';
31require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
32require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/functionsnumtoword.lib.php';
35
36
41{
47 public function __construct($db)
48 {
49 global $langs;
50
51 $this->db = $db;
52 $this->name = "cerfafr";
53 $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*04';
54
55 // Dimension page for size A4
56 $this->type = 'html';
57 }
58
59
65 public function isEnabled()
66 {
67 return true;
68 }
69
70
71 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
80 public function write_file($don, $outputlangs, $currency = '')
81 {
82 // phpcs:enable
83 global $user, $conf, $langs, $mysoc;
84
85 $now = dol_now();
86 $id = (!is_object($don) ? $don : '');
87
88 if (!is_object($outputlangs)) {
89 $outputlangs = $langs;
90 }
91
92 // Load traductions files required by page
93 $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "donations"));
94
95 $currency = !empty($currency) ? $currency : $conf->currency;
96
97 if (!empty($conf->don->dir_output)) {
98 // Definition of the object don (for upward compatibility)
99 if (!is_object($don)) {
100 $don = new Don($this->db);
101 $ret = $don->fetch($id);
102 $id = $don->id;
103 }
104
105 // Definition of $dir and $file
106 if (!empty($don->specimen)) {
107 $dir = $conf->don->dir_output;
108 $file = $dir."/SPECIMEN.html";
109 } else {
110 $donref = dol_sanitizeFileName((string) $don->ref);
111 $dir = $conf->don->dir_output."/".$donref;
112 $file = $dir."/".$donref.".html";
113 }
114
115 if (!file_exists($dir)) {
116 if (dol_mkdir($dir) < 0) {
117 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
118 return -1;
119 }
120 }
121
122 if (file_exists($dir)) {
123 $formclass = new Form($this->db);
124
125 // This is not the proper way to do it but $formclass->form_modes_reglement
126 // prints the translation instead of returning it
127 $formclass->load_cache_types_paiements();
128 // Don::fetch() stores the payment mode into mode_reglement_id. The modepaymentid property is only
129 // set by the create/update forms, so it is always empty when the document is built from a fetched
130 // donation and no payment mode checkbox was ever ticked on the receipt.
131 $modepaymentid = !empty($don->mode_reglement_id) ? $don->mode_reglement_id : $don->modepaymentid;
132 if ($modepaymentid) {
133 $paymentmode = !empty($formclass->cache_types_paiements[(int) $modepaymentid]['label']) ? $formclass->cache_types_paiements[$modepaymentid]['label'] : '';
134 } else {
135 $paymentmode = '';
136 }
137 $modepaymentcode = !empty($formclass->cache_types_paiements[(int) $modepaymentid]['code']) ? $formclass->cache_types_paiements[(int) $modepaymentid]['code'] : "";
138 if ($modepaymentcode == 'CHQ') {
139 $ModePaiement = '<td width="25%"><input type="checkbox"> Remise d\'espèces</td><td width="25%"><input type="checkbox" disabled="true" checked="checked"> Chèque</td><td width="50%"><input type="checkbox"> Virement, prélèvement, carte bancaire</td>';
140 } elseif ($modepaymentcode == 'LIQ') {
141 $ModePaiement = '<td width="25%"><input type="checkbox" checked="checked"> Remise d\'espèces</td><td width="25%"><input type="checkbox"> Chèque</td><td width="50%"><input type="checkbox"> Virement, prélèvement, carte bancaire</td>';
142 } elseif ($modepaymentcode == 'VIR' || $modepaymentcode == 'PRE' || $modepaymentcode == 'CB') {
143 $ModePaiement = '<td width="25%"><input type="checkbox"> Remise d\'espèces</td><td width="25%"><input type="checkbox"> Chèque</td><td width="50%"><input type="checkbox" checked="checked"> Virement, prélèvement, carte bancaire</td>';
144 } else {
145 $ModePaiement = '<td width="25%"><input type="checkbox"> Remise d\'espèces</td><td width="25%"><input type="checkbox"> Chèque</td><td width="50%"><input type="checkbox"> Virement, prélèvement, carte bancaire</td>';
146 }
147
148 /*
149 if (empty($don->societe))
150 {
151 $CodeDon = '<td width="33%"><input type="checkbox" disabled="true" checked="checked" > 200 du CGI</td><td width="33%"><input type="checkbox" disabled="true" > 238 bis du CGI</td><td width="33%"><input type="checkbox" disabled="true" > 978 du CGI</td>';
152 }
153 else
154 {
155 $CodeDon = '<td width="33%"><input type="checkbox" disabled="true" > 200 du CGI</td><td width="33%"><input type="checkbox" disabled="true" checked="checked" > 238 bis du CGI</td><td width="33%"><input type="checkbox" disabled="true" > 978 du CGI</td>';
156 }
157 */
158 // Donator identity.
159 // When option DONATION_USE_THIRDPARTIES is on, the donation form does not show the name/address
160 // inputs at all, so llx_don only holds fk_soc and every donator field stays empty. The receipt
161 // would then be issued without the mandatory identity of the donator, so fall back on the linked
162 // third party for each field left empty.
163 $donatorsociete = (string) $don->societe;
164 $donatorlastname = (string) $don->lastname;
165 $donatorfirstname = (string) $don->firstname;
166 $donatoraddress = (string) $don->address;
167 $donatorzip = (string) $don->zip;
168 $donatortown = (string) $don->town;
169
170 if (!empty($don->socid) && $don->socid > 0) {
171 $donatorthirdparty = new Societe($this->db);
172 if ($donatorthirdparty->fetch($don->socid) > 0) {
173 if (dol_strlen(trim($donatorsociete.$donatorlastname.$donatorfirstname)) == 0) {
174 // A third party holds a single name field, even for a private individual, so it goes
175 // to the "Name" cell of the form and the "Firstname" cell is left empty.
176 $donatorsociete = (string) $donatorthirdparty->name;
177 }
178 if (dol_strlen(trim($donatoraddress)) == 0) {
179 $donatoraddress = (string) $donatorthirdparty->address;
180 }
181 if (dol_strlen(trim($donatorzip)) == 0) {
182 $donatorzip = (string) $donatorthirdparty->zip;
183 }
184 if (dol_strlen(trim($donatortown)) == 0) {
185 $donatortown = (string) $donatorthirdparty->town;
186 }
187 } else {
188 dol_syslog("html_cerfafr::write_file Failed to load thirdparty ".$don->socid." linked to donation ".$don->id.", donator block will remain empty - ".$donatorthirdparty->error, LOG_ERR);
189 }
190 }
191
192 if (dol_strlen(trim($donatorsociete.$donatorlastname.$donatorfirstname)) == 0) {
193 dol_syslog("html_cerfafr::write_file No name found for the donator of donation ".$don->id.", the receipt will not be compliant", LOG_WARNING);
194 }
195
196 // Define contents
197 $donmodel = DOL_DOCUMENT_ROOT."/core/modules/dons/html_cerfafr.html";
198
199 $form = file_get_contents($donmodel);
200
201 // TODO Remove what was already included into getCommonSubstitutionArray / make_substitutions
202 $form = str_replace('__REF__', (string) $don->id, $form);
203 $form = str_replace('__DATE__', dol_print_date($don->date, 'day', false, $outputlangs), $form);
204 //$form = str_replace('__IP__',$user->ip,$form); // TODO $user->ip not exist
205 $form = str_replace('__AMOUNT__', price($don->amount), $form);
206 $form = str_replace('__AMOUNT_TEXT__', dol_convertToWord($don->amount, $outputlangs, $outputlangs->transnoentitiesnoconv("Currency".$currency), true), $form);
207
208 $form = str_replace('__DONATOR_FIRSTNAME__', dol_escape_htmltag($donatorfirstname), $form);
209 // The template concatenates __DONATOR_SOCIETE__ and __DONATOR_LASTNAME__ with no separator,
210 // so add a line break when both are filled in.
211 $donatorlastnameprefix = (dol_strlen(trim($donatorsociete)) > 0 && dol_strlen(trim($donatorlastname)) > 0) ? '<br>' : '';
212 $form = str_replace('__DONATOR_LASTNAME__', $donatorlastnameprefix.dol_escape_htmltag($donatorlastname), $form);
213 $form = str_replace('__DONATOR_SOCIETE__', dol_escape_htmltag($donatorsociete), $form);
214
215 $form = str_replace('__DONATOR_STATUT__', (string) $don->statut, $form);
216 $form = str_replace('__DONATOR_ADDRESS__', dol_nl2br(dol_escape_htmltag($donatoraddress, 0, 1)), $form);
217 $form = str_replace('__DONATOR_ZIP__', dol_escape_htmltag($donatorzip), $form);
218 $form = str_replace('__DONATOR_TOWN__', dol_escape_htmltag($donatortown), $form);
219
220 $form = str_replace('__PAYMENTMODE_LIB__ ', (string) $paymentmode, $form);
221 $form = str_replace('__NOW__', dol_print_date($now, 'day', false, $outputlangs), $form);
222 $form = str_replace('__DONATION_PAYMENT_MODE__', $ModePaiement, $form);
223 $form = str_replace('__DONATION_MESSAGE__', getDolGlobalString('DONATION_MESSAGE'), $form);
224
225 // Replace with a generic replacement feature '__(XXX)__' must become $outputlangs->trans('XXX')
226 $substitutionkey = getCommonSubstitutionArray($outputlangs, 0, null, $don);
227
228 $form = make_substitutions($form, $substitutionkey, $outputlangs);
229
230
231 $frencharticle = '';
232 if (preg_match('/fr/i', $outputlangs->defaultlang)) {
233 $frencharticle = '<font size="+1">Article 200, 238 bis et 978 du code général des impôts (CGI)</font>';
234 }
235 $form = str_replace('__FrenchArticle__', $frencharticle, $form);
236
237 $frencheligibility = '';
238 if (preg_match('/fr/i', $outputlangs->defaultlang)) {
239 $frencheligibility = 'Le bénéficiaire certifie sur l\'honneur que les dons et versements qu\'il reçoit ouvrent droit à la réduction d\'impôt prévue à l\'article :';
240 }
241 $form = str_replace('__FrenchEligibility__', $frencheligibility, $form);
242
243 $art200 = '';
244 if ($mysoc->country_code == 'FR') {
245 if (getDolGlobalInt('DONATION_ART200') >= 1) {
246 $art200 = '<input type="checkbox" disabled="true" checked="checked" >200 du CGI';
247 } else {
248 $art200 = '<input type="checkbox" disabled="true">200 du CGI';
249 }
250 }
251 $form = str_replace('__ARTICLE200__', $art200, $form);
252
253 $art238 = '';
254 if ($mysoc->country_code == 'FR') {
255 if (getDolGlobalInt('DONATION_ART238') >= 1) {
256 $art238 = '<input type="checkbox" disabled="true" checked="checked" >238 bis du CGI';
257 } else {
258 $art238 = '<input type="checkbox" disabled="true">238 bis du CGI';
259 }
260 }
261 $form = str_replace('__ARTICLE238__', $art238, $form);
262
263 $art978 = '';
264 if ($mysoc->country_code == 'FR') {
265 if (getDolGlobalInt('DONATION_ART978') >= 1) {
266 $art978 = '<input type="checkbox" disabled="true" checked="checked" >978 du CGI';
267 } else {
268 $art978 = '<input type="checkbox" disabled="true">978 du CGI';
269 }
270 }
271 $form = str_replace('__ARTICLE978__', $art978, $form);
272
273 // Save file on disk
274 dol_syslog("html_cerfafr::write_file $file");
275 $handle = fopen($file, "w");
276 fwrite($handle, $form);
277 fclose($handle);
278 dolChmod($file);
279
280 $this->result = array('fullpath' => $file);
281
282 return 1;
283 } else {
284 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
285 return 0;
286 }
287 } else {
288 $this->error = $langs->trans("ErrorConstantNotDefined", "DON_OUTPUTDIR");
289 return 0;
290 }
291 }
292}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
$propal type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition propal.php:280
Class to manage donations.
Definition don.class.php:41
Class to manage generation of HTML components Only common components must be here.
Parent class of subscription templates.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to generate document for subscriptions.
write_file($don, $outputlangs, $currency='')
Write the object to document file to disk.
isEnabled()
Return if a module can be used or not.
__construct($db)
Constructor.
global $mysoc
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_now($mode='gmt')
Return date for now.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
dol_convertToWord($num, $langs, $currency='', $centimes=false)
Function to return a number into a text.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140