dolibarr  19.0.0-dev
newonlinesign.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2006-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2009-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2023 anthony Berton <anthony.berton@bb2a.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  */
20 
28 if (!defined('NOLOGIN')) {
29  define("NOLOGIN", 1); // This means this output page does not require to be logged.
30 }
31 if (!defined('NOCSRFCHECK')) {
32  define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
33 }
34 if (!defined('NOIPCHECK')) {
35  define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
36 }
37 if (!defined('NOBROWSERNOTIF')) {
38  define('NOBROWSERNOTIF', '1');
39 }
40 
41 // For MultiCompany module.
42 // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php
43 // Because 2 entities can have the same ref.
44 $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
45 if (is_numeric($entity)) {
46  define("DOLENTITY", $entity);
47 }
48 
49 // Load Dolibarr environment
50 require '../../main.inc.php';
51 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
52 require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
53 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
54 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
55 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
56 
57 // Load translation files
58 $langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", "members", "paybox", "propal", "commercial"));
59 
60 // Security check
61 // No check on module enabled. Done later according to $validpaymentmethod
62 
63 // Get parameters
64 $action = GETPOST('action', 'aZ09');
65 $cancel = GETPOST('cancel', 'alpha');
66 $confirm = GETPOST('confirm', 'alpha');
67 
68 
69 $refusepropal = GETPOST('refusepropal', 'alpha');
70 $message = GETPOST('message', 'aZ09');
71 
72 // Input are:
73 // type ('invoice','order','contractline'),
74 // id (object id),
75 // amount (required if id is empty),
76 // tag (a free text, required if type is empty)
77 // currency (iso code)
78 
79 $suffix = GETPOST("suffix", 'aZ09');
80 $source = GETPOST("source", 'alpha');
81 $ref = $REF = GETPOST("ref", 'alpha');
82 $urlok = '';
83 $urlko = '';
84 
85 
86 if (empty($source)) {
87  $source = 'proposal';
88 }
89 if (!empty($refusepropal)) {
90  $action = "refusepropal";
91 }
92 
93 // Define $urlwithroot
94 //$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
95 //$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
96 $urlwithroot = DOL_MAIN_URL_ROOT; // This is to use same domain name than current. For Paypal payment, we can use internal URL like localhost.
97 
98 
99 // Complete urls for post treatment
100 $SECUREKEY = GETPOST("securekey"); // Secure key
101 
102 if (!empty($source)) {
103  $urlok .= 'source='.urlencode($source).'&';
104  $urlko .= 'source='.urlencode($source).'&';
105 }
106 if (!empty($REF)) {
107  $urlok .= 'ref='.urlencode($REF).'&';
108  $urlko .= 'ref='.urlencode($REF).'&';
109 }
110 if (!empty($SECUREKEY)) {
111  $urlok .= 'securekey='.urlencode($SECUREKEY).'&';
112  $urlko .= 'securekey='.urlencode($SECUREKEY).'&';
113 }
114 if (!empty($entity)) {
115  $urlok .= 'entity='.urlencode($entity).'&';
116  $urlko .= 'entity='.urlencode($entity).'&';
117 }
118 $urlok = preg_replace('/&$/', '', $urlok); // Remove last &
119 $urlko = preg_replace('/&$/', '', $urlko); // Remove last &
120 
121 $creditor = $mysoc->name;
122 
123 $type = $source;
124 
125 if (!$action) {
126  if ($source && !$ref) {
127  httponly_accessforbidden($langs->trans('ErrorBadParameters')." - ref missing", 400, 1);
128  }
129 }
130 
131 // Check securitykey
132 $securekeyseed = '';
133 if ($source == 'proposal') {
134  $securekeyseed = getDolGlobalString('PROPOSAL_ONLINE_SIGNATURE_SECURITY_TOKEN');
135 } elseif ($source == 'contract') {
136  $securekeyseed = getDolGlobalString('CONTRACT_ONLINE_SIGNATURE_SECURITY_TOKEN');
137 } elseif ($source == 'fichinter') {
138  $securekeyseed = getDolGlobalString('FICHINTER_ONLINE_SIGNATURE_SECURITY_TOKEN');
139 }
140 if (!dol_verifyHash($securekeyseed.$type.$ref.(isModEnabled('multicompany') ? $entity : ''), $SECUREKEY, '0')) {
141  httponly_accessforbidden('Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).' does not match expected value for ref='.dol_escape_htmltag($ref), 403, 1);
142 }
143 
144 if ($source == 'proposal') {
145  require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
146  $object = new Propal($db);
147  $result= $object->fetch(0, $ref, '', $entity);
148 } elseif ($source == 'contract') {
149  require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
150  $object = new Contrat($db);
151  $result= $object->fetch(0, $ref);
152 } elseif ($source == 'fichinter') {
153  require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
154  $object = new Fichinter($db);
155  $result= $object->fetch(0, $ref);
156 } else {
157  httponly_accessforbidden($langs->trans('ErrorBadParameters')." - Bad value for source", 400, 1);
158 }
159 
160 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
161 $hookmanager->initHooks(array('onlinesign'));
162 
163 $error = 0;
164 
165 
166 /*
167  * Actions
168  */
169 
170 if ($action == 'confirm_refusepropal' && $confirm == 'yes') {
171  $db->begin();
172 
173  $sql = "UPDATE ".MAIN_DB_PREFIX."propal";
174  $sql .= " SET fk_statut = ".((int) $object::STATUS_NOTSIGNED).", note_private = '".$db->escape($object->note_private)."', date_signature='".$db->idate(dol_now())."'";
175  $sql .= " WHERE rowid = ".((int) $object->id);
176 
177  dol_syslog(__METHOD__, LOG_DEBUG);
178  $resql = $db->query($sql);
179  if (!$resql) {
180  $error++;
181  }
182 
183  if (!$error) {
184  $db->commit();
185 
186  $message = 'refused';
187  setEventMessages("PropalRefused", null, 'warnings');
188  if (method_exists($object, 'call_trigger')) {
189  // Online customer is not a user, so we use the use that validates the documents
190  $user = new User($db);
191  $user->fetch($object->user_valid_id);
192  $object->context = array('closedfromonlinesignature' => 'closedfromonlinesignature');
193  $result = $object->call_trigger('PROPAL_CLOSE_REFUSED', $user);
194  if ($result < 0) {
195  $error++;
196  }
197  }
198  } else {
199  $db->rollback();
200  }
201 
202  $object->fetch(0, $ref);
203 }
204 
205 
206 /*
207  * View
208  */
209 
210 $form = new Form($db);
211 $head = '';
212 if (!empty($conf->global->MAIN_SIGN_CSS_URL)) {
213  $head = '<link rel="stylesheet" type="text/css" href="'.$conf->global->MAIN_SIGN_CSS_URL.'?lang='.$langs->defaultlang.'">'."\n";
214 }
215 
216 $conf->dol_hide_topmenu = 1;
217 $conf->dol_hide_leftmenu = 1;
218 
219 $replacemainarea = (empty($conf->dol_hide_leftmenu) ? '<div>' : '').'<div>';
220 llxHeader($head, $langs->trans("OnlineSignature"), '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea, 1);
221 
222 if ($action == 'refusepropal') {
223  print $form->formconfirm($_SERVER["PHP_SELF"].'?ref='.urlencode($ref).'&securekey='.urlencode($SECUREKEY).(isModEnabled('multicompany')?'&entity='.$entity:''), $langs->trans('RefusePropal'), $langs->trans('ConfirmRefusePropal', $object->ref), 'confirm_refusepropal', '', '', 1);
224 }
225 
226 // Check link validity for param 'source' to avoid use of the examples as value
227 if (!empty($source) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', 'proposal_ref', ''))) {
228  $langs->load("errors");
229  dol_print_error_email('BADREFINONLINESIGNFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref));
230  // End of page
231  llxFooter();
232  $db->close();
233  exit;
234 }
235 
236 print '<span id="dolpaymentspan"></span>'."\n";
237 print '<div class="center">'."\n";
238 print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
239 print '<input type="hidden" name="token" value="'.newToken().'">'."\n";
240 print '<input type="hidden" name="action" value="dosign">'."\n";
241 print '<input type="hidden" name="tag" value="'.GETPOST("tag", 'alpha').'">'."\n";
242 print '<input type="hidden" name="suffix" value="'.GETPOST("suffix", 'alpha').'">'."\n";
243 print '<input type="hidden" name="securekey" value="'.$SECUREKEY.'">'."\n";
244 print '<input type="hidden" name="entity" value="'.$entity.'" />';
245 print '<input type="hidden" name="page_y" value="" />';
246 print "\n";
247 print '<!-- Form to sign -->'."\n";
248 
249 print '<table id="dolpublictable" summary="Payment form" class="center">'."\n";
250 
251 // Show logo (search order: logo defined by ONLINE_SIGN_LOGO_suffix, then ONLINE_SIGN_LOGO_, then small company logo, large company logo, theme logo, common logo)
252 // Define logo and logosmall
253 $logosmall = $mysoc->logo_small;
254 $logo = $mysoc->logo;
255 $paramlogo = 'ONLINE_SIGN_LOGO_'.$suffix;
256 if (!empty($conf->global->$paramlogo)) {
257  $logosmall = $conf->global->$paramlogo;
258 } elseif (!empty($conf->global->ONLINE_SIGN_LOGO)) {
259  $logosmall = $conf->global->ONLINE_SIGN_LOGO;
260 }
261 //print '<!-- Show logo (logosmall='.$logosmall.' logo='.$logo.') -->'."\n";
262 // Define urllogo
263 $urllogo = '';
264 $urllogofull = '';
265 if (!empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall)) {
266  $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/thumbs/'.$logosmall);
267  $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall);
268 } elseif (!empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo)) {
269  $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/'.$logo);
270  $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo);
271 }
272 // Output html code for logo
273 if ($urllogo) {
274  print '<div class="backgreypublicpayment">';
275  print '<div class="logopublicpayment">';
276  print '<img id="dolpaymentlogo" src="'.$urllogo.'"';
277  print '>';
278  print '</div>';
279  if (empty($conf->global->MAIN_HIDE_POWERED_BY)) {
280  print '<div class="poweredbypublicpayment opacitymedium right"><a class="poweredbyhref" href="https://www.dolibarr.org?utm_medium=website&utm_source=poweredby" target="dolibarr" rel="noopener">'.$langs->trans("PoweredBy").'<br><img class="poweredbyimg" src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.svg" width="80px"></a></div>';
281  }
282  print '</div>';
283 }
284 if ($source == 'proposal' && !empty($conf->global->PROPOSAL_IMAGE_PUBLIC_SIGN)) {
285  print '<div class="backimagepublicproposalsign">';
286  print '<img id="idPROPOSAL_IMAGE_PUBLIC_INTERFACE" src="'.$conf->global->PROPOSAL_IMAGE_PUBLIC_SIGN.'">';
287  print '</div>';
288 }
289 
290 // Output introduction text
291 $text = '';
292 if (!empty($conf->global->ONLINE_SIGN_NEWFORM_TEXT)) {
293  $reg = array();
294  if (preg_match('/^\‍((.*)\‍)$/', $conf->global->ONLINE_SIGN_NEWFORM_TEXT, $reg)) {
295  $text .= $langs->trans($reg[1])."<br>\n";
296  } else {
297  $text .= $conf->global->ONLINE_SIGN_NEWFORM_TEXT."<br>\n";
298  }
299  $text = '<tr><td align="center"><br>'.$text.'<br></td></tr>'."\n";
300 }
301 if (empty($text)) {
302  if ($source == 'proposal') {
303  $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageProposal", $mysoc->name).'</strong></td></tr>'."\n";
304  $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromProposal", $creditor).'<br><br></td></tr>'."\n";
305  } elseif ($source == 'contract') {
306  $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageContract", $mysoc->name).'</strong></td></tr>'."\n";
307  $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromContract", $creditor).'<br><br></td></tr>'."\n";
308  } elseif ($source == 'fichinter') {
309  $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageFichinter", $mysoc->name).'</strong></td></tr>'."\n";
310  $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromFichinter", $creditor).'<br><br></td></tr>'."\n";
311  }
312 }
313 print $text;
314 
315 // Output payment summary form
316 print '<tr><td align="center">';
317 print '<table with="100%" id="tablepublicpayment">';
318 if ($source == 'proposal') {
319  print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignProposal").' :</td></tr>'."\n";
320 } elseif ($source == 'contract') {
321  print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignContract").' :</td></tr>'."\n";
322 } elseif ($source == 'fichinter') {
323  print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignFichinter").' :</td></tr>'."\n";
324 }
325 $found = false;
326 $error = 0;
327 
328 // Signature on commercial proposal
329 if ($source == 'proposal') {
330  $found = true;
331  $langs->load("proposal");
332 
333  $result = $object->fetch_thirdparty($object->socid);
334 
335  // Creditor
336  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
337  print '</td><td class="CTableRow2">';
338  print img_picto('', 'company', 'class="pictofixedwidth"');
339  print '<b>'.$creditor.'</b>';
340  print '<input type="hidden" name="creditor" value="'.$creditor.'">';
341  print '</td></tr>'."\n";
342 
343  // Debitor
344  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
345  print '</td><td class="CTableRow2">';
346  print img_picto('', 'company', 'class="pictofixedwidth"');
347  print '<b>'.$object->thirdparty->name.'</b>';
348  print '</td></tr>'."\n";
349 
350  // Amount
351  $amount = '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
352  $amount .= '</td><td class="CTableRow2">';
353  $amount .= '<b>'.price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).'</b>';
354  $amount .= '</td></tr>'."\n";
355 
356  // Call Hook amountPropalSign
357  $parameters = array('source' => $source);
358  $reshook = $hookmanager->executeHooks('amountPropalSign', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
359  if (empty($reshook)) {
360  $amount .= $hookmanager->resPrint;
361  } elseif ($reshook > 0) {
362  $amount = $hookmanager->resPrint;
363  }
364 
365  print $amount;
366 
367  // Object
368  $text = '<b>'.$langs->trans("SignatureProposalRef", $object->ref).'</b>';
369  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
370  print '</td><td class="CTableRow2">'.$text;
371 
372  $last_main_doc_file = $object->last_main_doc;
373 
374  if ($object->status == $object::STATUS_VALIDATED) {
375  if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
376  // It seems document has never been generated, or was generated and then deleted.
377  // So we try to regenerate it with its default template.
378  $defaulttemplate = ''; // We force the use an empty string instead of $object->model_pdf to be sure to use a "main" default template and not the last one used.
379  $object->generateDocument($defaulttemplate, $langs);
380  }
381 
382  $directdownloadlink = $object->getLastMainDocLink('proposal');
383  if ($directdownloadlink) {
384  print '<br><a href="'.$directdownloadlink.'">';
385  print img_mime($object->last_main_doc, '');
386  print $langs->trans("DownloadDocument").'</a>';
387  }
388  } else {
389  if ($object->status == $object::STATUS_NOTSIGNED) {
390  $directdownloadlink = $object->getLastMainDocLink('proposal');
391  if ($directdownloadlink) {
392  print '<br><a href="'.$directdownloadlink.'">';
393  print img_mime($last_main_doc_file, '');
394  print $langs->trans("DownloadDocument").'</a>';
395  }
396  } elseif ($object->status == $object::STATUS_SIGNED || $object->status == $object::STATUS_BILLED) {
397  if (preg_match('/_signed-(\d+)/', $last_main_doc_file)) { // If the last main doc has been signed
398  $last_main_doc_file_not_signed = preg_replace('/_signed-(\d+)/', '', $last_main_doc_file);
399 
400  $datefilesigned = dol_filemtime($last_main_doc_file);
401  $datefilenotsigned = dol_filemtime($last_main_doc_file_not_signed);
402 
403  if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) {
404  $directdownloadlink = $object->getLastMainDocLink('proposal');
405  if ($directdownloadlink) {
406  print '<br><a href="'.$directdownloadlink.'">';
407  print img_mime($object->last_main_doc, '');
408  print $langs->trans("DownloadDocument").'</a>';
409  }
410  }
411  }
412  }
413  }
414 
415  print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
416  print '<input type="hidden" name="ref" value="'.$object->ref.'">';
417  print '</td></tr>'."\n";
418 } elseif ($source == 'contract') { // Signature on contract
419  $found = true;
420  $langs->load("contract");
421 
422  $result = $object->fetch_thirdparty($object->socid);
423 
424  // Proposer
425  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
426  print '</td><td class="CTableRow2">';
427  print img_picto('', 'company', 'class="pictofixedwidth"');
428  print '<b>'.$creditor.'</b>';
429  print '<input type="hidden" name="creditor" value="'.$creditor.'">';
430  print '</td></tr>'."\n";
431 
432  // Target
433  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
434  print '</td><td class="CTableRow2">';
435  print img_picto('', 'company', 'class="pictofixedwidth"');
436  print '<b>'.$object->thirdparty->name.'</b>';
437  print '</td></tr>'."\n";
438 
439  // Object
440  $text = '<b>'.$langs->trans("SignatureContractRef", $object->ref).'</b>';
441  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
442  print '</td><td class="CTableRow2">'.$text;
443 
444  $last_main_doc_file = $object->last_main_doc;
445 
446  if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
447  // It seems document has never been generated, or was generated and then deleted.
448  // So we try to regenerate it with its default template.
449  $defaulttemplate = ''; // We force the use an empty string instead of $object->model_pdf to be sure to use a "main" default template and not the last one used.
450  $object->generateDocument($defaulttemplate, $langs);
451  }
452 
453  $directdownloadlink = $object->getLastMainDocLink('contract');
454  if ($directdownloadlink) {
455  print '<br><a href="'.$directdownloadlink.'">';
456  print img_mime($object->last_main_doc, '');
457  if ($message == "signed") {
458  print $langs->trans("DownloadSignedDocument").'</a>';
459  } else {
460  print $langs->trans("DownloadDocument").'</a>';
461  }
462  }
463 
464 
465  print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
466  print '<input type="hidden" name="ref" value="'.$object->ref.'">';
467  print '</td></tr>'."\n";
468 } elseif ($source == 'fichinter') { // Signature on fichinter
469  $found = true;
470  $langs->load("fichinter");
471 
472  $result = $object->fetch_thirdparty($object->socid);
473 
474  // Proposer
475  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
476  print '</td><td class="CTableRow2">';
477  print img_picto('', 'company', 'class="pictofixedwidth"');
478  print '<b>'.$creditor.'</b>';
479  print '<input type="hidden" name="creditor" value="'.$creditor.'">';
480  print '</td></tr>'."\n";
481 
482  // Target
483  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
484  print '</td><td class="CTableRow2">';
485  print img_picto('', 'company', 'class="pictofixedwidth"');
486  print '<b>'.$object->thirdparty->name.'</b>';
487  print '</td></tr>'."\n";
488 
489  // Object
490  $text = '<b>'.$langs->trans("SignatureFichinterRef", $object->ref).'</b>';
491  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
492  print '</td><td class="CTableRow2">'.$text;
493 
494  $last_main_doc_file = $object->last_main_doc;
495 
496  if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
497  // It seems document has never been generated, or was generated and then deleted.
498  // So we try to regenerate it with its default template.
499  $defaulttemplate = ''; // We force the use an empty string instead of $object->model_pdf to be sure to use a "main" default template and not the last one used.
500  $object->generateDocument($defaulttemplate, $langs);
501  }
502 
503  $directdownloadlink = $object->getLastMainDocLink('fichinter');
504  if ($directdownloadlink) {
505  print '<br><a href="'.$directdownloadlink.'">';
506  print img_mime($object->last_main_doc, '');
507  if ($message == "signed") {
508  print $langs->trans("DownloadSignedDocument").'</a>';
509  } else {
510  print $langs->trans("DownloadDocument").'</a>';
511  }
512  }
513  print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
514  print '<input type="hidden" name="ref" value="'.$object->ref.'">';
515  print '</td></tr>'."\n";
516 }
517 
518 // Call Hook addFormSign
519 $parameters = array('source' => $source);
520 $reshook = $hookmanager->executeHooks('addFormSign', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
521 
522 if (!$found && !$mesg) {
523  $mesg = $langs->transnoentitiesnoconv("ErrorBadParameters");
524 }
525 
526 if ($mesg) {
527  print '<tr><td class="center" colspan="2"><br><div class="warning">'.dol_escape_htmltag($mesg).'</div></td></tr>'."\n";
528 }
529 
530 print '</table>'."\n";
531 print "\n";
532 
533 if ($action != 'dosign') {
534  if ($found && !$error) {
535  // We are in a management option and no error
536  } else {
537  dol_print_error_email('ERRORNEWONLINESIGN');
538  }
539 } else {
540  // Print
541 }
542 
543 print '</td></tr>'."\n";
544 print '<tr><td class="center">';
545 
546 
547 if ($action == "dosign" && empty($cancel)) {
548  print '<div class="tablepublicpayment">';
549  print '<input type="button" class="buttonDelete small" id="clearsignature" value="'.$langs->trans("ClearSignature").'">';
550  print '<input type="text" class="paddingleftonly marginleftonly paddingrightonly marginrightonly" id="name" placeholder="'.$langs->trans("Lastname").'">';
551  print '<div id="signature" style="border:solid;"></div>';
552  print '</div>';
553  // Do not use class="reposition" here: It breaks the submit and there is a message on top to say it's ok, so going back top is better.
554  print '<input type="button" class="button" id="signbutton" value="'.$langs->trans("Sign").'">';
555  print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
556 
557  // Add js code managed into the div #signature
558  print '<script language="JavaScript" type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jSignature/jSignature.js"></script>
559  <script type="text/javascript">
560  $(document).ready(function() {
561  $("#signature").jSignature({ color:"#000", lineWidth:0, '.(empty($conf->dol_optimize_smallscreen) ? '' : 'width: 280, ' ).'height: 180});
562 
563  $("#signature").on("change",function(){
564  $("#clearsignature").css("display","");
565  $("#signbutton").attr("disabled",false);
566  if(!$._data($("#signbutton")[0], "events")){
567  $("#signbutton").on("click",function(){
568  console.log("We click on button sign");
569  $("#signbutton").val(\''.dol_escape_js($langs->transnoentities('PleaseBePatient')).'\');
570  var signature = $("#signature").jSignature("getData", "image");
571  var name = document.getElementById("name").value;
572  $.ajax({
573  type: "POST",
574  url: "'.DOL_URL_ROOT.'/core/ajax/onlineSign.php",
575  dataType: "text",
576  data: {
577  "action" : "importSignature",
578  "token" : \''.newToken().'\',
579  "signaturebase64" : signature,
580  "onlinesignname" : name,
581  "ref" : \''.dol_escape_js($REF).'\',
582  "securekey" : \''.dol_escape_js($SECUREKEY).'\',
583  "mode" : \''.dol_escape_htmltag($source).'\',
584  "entity" : \''.dol_escape_htmltag($entity).'\',
585  },
586  success: function(response) {
587  if(response == "success"){
588  console.log("Success on saving signature");
589  window.location.replace("'.$_SERVER["PHP_SELF"].'?ref='.urlencode($ref).'&source='.urlencode($source).'&message=signed&securekey='.urlencode($SECUREKEY).(isModEnabled('multicompany')?'&entity='.$entity:'').'");
590  }else{
591  console.error(response);
592  }
593  },
594  });
595  });
596  }
597  });
598 
599  $("#clearsignature").on("click",function(){
600  $("#signature").jSignature("clear");
601  $("#signbutton").attr("disabled",true);
602  // document.getElementById("onlinesignname").value = "";
603  });
604 
605  $("#signbutton").attr("disabled",true);
606  });
607  </script>';
608 } else {
609  if ($source == 'proposal') {
610  if ($object->status == $object::STATUS_SIGNED) {
611  print '<br>';
612  if ($message == 'signed') {
613  print img_picto('', 'check', '', false, 0, 0, '', 'size2x').'<br>';
614  print '<span class="ok">'.$langs->trans("PropalSigned").'</span>';
615  } else {
616  print img_picto('', 'check', '', false, 0, 0, '', 'size2x').'<br>';
617  print '<span class="ok">'.$langs->trans("PropalAlreadySigned").'</span>';
618  }
619  } elseif ($object->status == $object::STATUS_NOTSIGNED) {
620  print '<br>';
621  if ($message == 'refused') {
622  print img_picto('', 'cross', '', false, 0, 0, '', 'size2x').'<br>';
623  print '<span class="ok">'.$langs->trans("PropalRefused").'</span>';
624  } else {
625  print img_picto('', 'cross', '', false, 0, 0, '', 'size2x').'<br>';
626  print '<span class="warning">'.$langs->trans("PropalAlreadyRefused").'</span>';
627  }
628  } else {
629  print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignPropal").'">';
630  print '<input name="refusepropal" type="submit" class="butActionDelete small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("RefusePropal").'">';
631  }
632  } elseif ($source == 'contract') {
633  if ($message == 'signed') {
634  print '<span class="ok">'.$langs->trans("ContractSigned").'</span>';
635  } else {
636  print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignContract").'">';
637  }
638  } elseif ($source == 'fichinter') {
639  if ($message == 'signed') {
640  print '<span class="ok">'.$langs->trans("FichinterSigned").'</span>';
641  } else {
642  print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignFichinter").'">';
643  }
644  }
645 }
646 print '</td></tr>'."\n";
647 print '</table>'."\n";
648 print '</form>'."\n";
649 print '</div>'."\n";
650 print '<br>';
651 
652 
653 htmlPrintOnlineFooter($mysoc, $langs);
654 
655 llxFooter('', 'public');
656 
657 $db->close();
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage contracts.
Class to manage interventions.
Class to manage generation of HTML components Only common components must be here.
Class to manage proposals.
Class to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_filemtime($pathoffile)
Return time of a file.
Definition: files.lib.php:599
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:483
dol_now($mode='auto')
Return date for now.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error_email($prefixcode, $errormessage='', $errormessages=array(), $morecss='error', $email='')
Show a public email and error code to contact if technical error.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:123
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons,...
httponly_accessforbidden($message=1, $http_response_code=403, $stringalreadysanitized=0)
Show a message to say access is forbidden and stop program.