dolibarr  18.0.6
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 
352  $amount = '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
353  $amount .= '</td><td class="CTableRow2">';
354  $amount .= '<b>'.price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).'</b>';
355  if ($object->multicurrency_code != $conf->currency) {
356  $amount .= ' ('.price($object->multicurrency_total_ttc, 0, $langs, 1, -1, -1, $object->multicurrency_code).')';
357  }
358  $amount .= '</td></tr>'."\n";
359 
360  // Call Hook amountPropalSign
361  $parameters = array('source' => $source);
362  $reshook = $hookmanager->executeHooks('amountPropalSign', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
363  if (empty($reshook)) {
364  $amount .= $hookmanager->resPrint;
365  } elseif ($reshook > 0) {
366  $amount = $hookmanager->resPrint;
367  }
368 
369  print $amount;
370 
371  // Object
372  $text = '<b>'.$langs->trans("SignatureProposalRef", $object->ref).'</b>';
373  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
374  print '</td><td class="CTableRow2">'.$text;
375 
376  $last_main_doc_file = $object->last_main_doc;
377 
378  if ($object->status == $object::STATUS_VALIDATED) {
379  if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
380  // It seems document has never been generated, or was generated and then deleted.
381  // So we try to regenerate it with its default template.
382  $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.
383  $object->generateDocument($defaulttemplate, $langs);
384  }
385 
386  $directdownloadlink = $object->getLastMainDocLink('proposal');
387  if ($directdownloadlink) {
388  print '<br><a href="'.$directdownloadlink.'">';
389  print img_mime($object->last_main_doc, '');
390  print $langs->trans("DownloadDocument").'</a>';
391  }
392  } else {
393  if ($object->status == $object::STATUS_NOTSIGNED) {
394  $directdownloadlink = $object->getLastMainDocLink('proposal');
395  if ($directdownloadlink) {
396  print '<br><a href="'.$directdownloadlink.'">';
397  print img_mime($last_main_doc_file, '');
398  print $langs->trans("DownloadDocument").'</a>';
399  }
400  } elseif ($object->status == $object::STATUS_SIGNED || $object->status == $object::STATUS_BILLED) {
401  if (preg_match('/_signed-(\d+)/', $last_main_doc_file)) { // If the last main doc has been signed
402  $last_main_doc_file_not_signed = preg_replace('/_signed-(\d+)/', '', $last_main_doc_file);
403 
404  $datefilesigned = dol_filemtime($last_main_doc_file);
405  $datefilenotsigned = dol_filemtime($last_main_doc_file_not_signed);
406 
407  if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) {
408  $directdownloadlink = $object->getLastMainDocLink('proposal');
409  if ($directdownloadlink) {
410  print '<br><a href="'.$directdownloadlink.'">';
411  print img_mime($object->last_main_doc, '');
412  print $langs->trans("DownloadDocument").'</a>';
413  }
414  }
415  }
416  }
417  }
418 
419  print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
420  print '<input type="hidden" name="ref" value="'.$object->ref.'">';
421  print '</td></tr>'."\n";
422 } elseif ($source == 'contract') { // Signature on contract
423  $found = true;
424  $langs->load("contract");
425 
426  $result = $object->fetch_thirdparty($object->socid);
427 
428  // Proposer
429  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
430  print '</td><td class="CTableRow2">';
431  print img_picto('', 'company', 'class="pictofixedwidth"');
432  print '<b>'.$creditor.'</b>';
433  print '<input type="hidden" name="creditor" value="'.$creditor.'">';
434  print '</td></tr>'."\n";
435 
436  // Target
437  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
438  print '</td><td class="CTableRow2">';
439  print img_picto('', 'company', 'class="pictofixedwidth"');
440  print '<b>'.$object->thirdparty->name.'</b>';
441  print '</td></tr>'."\n";
442 
443  // Object
444  $text = '<b>'.$langs->trans("SignatureContractRef", $object->ref).'</b>';
445  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
446  print '</td><td class="CTableRow2">'.$text;
447 
448  $last_main_doc_file = $object->last_main_doc;
449 
450  if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
451  // It seems document has never been generated, or was generated and then deleted.
452  // So we try to regenerate it with its default template.
453  $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.
454  $object->generateDocument($defaulttemplate, $langs);
455  }
456 
457  $directdownloadlink = $object->getLastMainDocLink('contract');
458  if ($directdownloadlink) {
459  print '<br><a href="'.$directdownloadlink.'">';
460  print img_mime($object->last_main_doc, '');
461  if ($message == "signed") {
462  print $langs->trans("DownloadSignedDocument").'</a>';
463  } else {
464  print $langs->trans("DownloadDocument").'</a>';
465  }
466  }
467 
468 
469  print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
470  print '<input type="hidden" name="ref" value="'.$object->ref.'">';
471  print '</td></tr>'."\n";
472 } elseif ($source == 'fichinter') { // Signature on fichinter
473  $found = true;
474  $langs->load("fichinter");
475 
476  $result = $object->fetch_thirdparty($object->socid);
477 
478  // Proposer
479  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
480  print '</td><td class="CTableRow2">';
481  print img_picto('', 'company', 'class="pictofixedwidth"');
482  print '<b>'.$creditor.'</b>';
483  print '<input type="hidden" name="creditor" value="'.$creditor.'">';
484  print '</td></tr>'."\n";
485 
486  // Target
487  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
488  print '</td><td class="CTableRow2">';
489  print img_picto('', 'company', 'class="pictofixedwidth"');
490  print '<b>'.$object->thirdparty->name.'</b>';
491  print '</td></tr>'."\n";
492 
493  // Object
494  $text = '<b>'.$langs->trans("SignatureFichinterRef", $object->ref).'</b>';
495  print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
496  print '</td><td class="CTableRow2">'.$text;
497 
498  $last_main_doc_file = $object->last_main_doc;
499 
500  if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
501  // It seems document has never been generated, or was generated and then deleted.
502  // So we try to regenerate it with its default template.
503  $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.
504  $object->generateDocument($defaulttemplate, $langs);
505  }
506 
507  $directdownloadlink = $object->getLastMainDocLink('fichinter');
508  if ($directdownloadlink) {
509  print '<br><a href="'.$directdownloadlink.'">';
510  print img_mime($object->last_main_doc, '');
511  if ($message == "signed") {
512  print $langs->trans("DownloadSignedDocument").'</a>';
513  } else {
514  print $langs->trans("DownloadDocument").'</a>';
515  }
516  }
517  print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
518  print '<input type="hidden" name="ref" value="'.$object->ref.'">';
519  print '</td></tr>'."\n";
520 }
521 
522 // Call Hook addFormSign
523 $parameters = array('source' => $source);
524 $reshook = $hookmanager->executeHooks('addFormSign', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
525 
526 if (!$found && !$mesg) {
527  $mesg = $langs->transnoentitiesnoconv("ErrorBadParameters");
528 }
529 
530 if ($mesg) {
531  print '<tr><td class="center" colspan="2"><br><div class="warning">'.dol_escape_htmltag($mesg).'</div></td></tr>'."\n";
532 }
533 
534 print '</table>'."\n";
535 print "\n";
536 
537 if ($action != 'dosign') {
538  if ($found && !$error) {
539  // We are in a management option and no error
540  } else {
541  dol_print_error_email('ERRORNEWONLINESIGN');
542  }
543 } else {
544  // Print
545 }
546 
547 print '</td></tr>'."\n";
548 print '<tr><td class="center">';
549 
550 
551 if ($action == "dosign" && empty($cancel)) {
552  print '<div class="tablepublicpayment">';
553  print '<input type="button" class="buttonDelete small" id="clearsignature" value="'.$langs->trans("ClearSignature").'">';
554  print '<input type="text" class="paddingleftonly marginleftonly paddingrightonly marginrightonly" id="name" placeholder="'.$langs->trans("Lastname").'">';
555  print '<div id="signature" style="border:solid;"></div>';
556  print '</div>';
557  // 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.
558  print '<input type="button" class="button" id="signbutton" value="'.$langs->trans("Sign").'">';
559  print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
560 
561  // Add js code managed into the div #signature
562  print '<script language="JavaScript" type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jSignature/jSignature.js"></script>
563  <script type="text/javascript">
564  $(document).ready(function() {
565  $("#signature").jSignature({ color:"#000", lineWidth:0, '.(empty($conf->dol_optimize_smallscreen) ? '' : 'width: 280, ' ).'height: 180});
566 
567  $("#signature").on("change",function(){
568  $("#clearsignature").css("display","");
569  $("#signbutton").attr("disabled",false);
570  if(!$._data($("#signbutton")[0], "events")){
571  $("#signbutton").on("click",function(){
572  console.log("We click on button sign");
573  $("#signbutton").val(\''.dol_escape_js($langs->transnoentities('PleaseBePatient')).'\');
574  var signature = $("#signature").jSignature("getData", "image");
575  var name = document.getElementById("name").value;
576  $.ajax({
577  type: "POST",
578  url: "'.DOL_URL_ROOT.'/core/ajax/onlineSign.php",
579  dataType: "text",
580  data: {
581  "action" : "importSignature",
582  "token" : \''.newToken().'\',
583  "signaturebase64" : signature,
584  "onlinesignname" : name,
585  "ref" : \''.dol_escape_js($REF).'\',
586  "securekey" : \''.dol_escape_js($SECUREKEY).'\',
587  "mode" : \''.dol_escape_htmltag($source).'\',
588  "entity" : \''.dol_escape_htmltag($entity).'\',
589  },
590  success: function(response) {
591  if(response == "success"){
592  console.log("Success on saving signature");
593  window.location.replace("'.$_SERVER["PHP_SELF"].'?ref='.urlencode($ref).'&source='.urlencode($source).'&message=signed&securekey='.urlencode($SECUREKEY).(isModEnabled('multicompany')?'&entity='.$entity:'').'");
594  }else{
595  console.error(response);
596  }
597  },
598  });
599  });
600  }
601  });
602 
603  $("#clearsignature").on("click",function(){
604  $("#signature").jSignature("clear");
605  $("#signbutton").attr("disabled",true);
606  // document.getElementById("onlinesignname").value = "";
607  });
608 
609  $("#signbutton").attr("disabled",true);
610  });
611  </script>';
612 } else {
613  if ($source == 'proposal') {
614  if ($object->status == $object::STATUS_SIGNED) {
615  print '<br>';
616  if ($message == 'signed') {
617  print img_picto('', 'check', '', false, 0, 0, '', 'size2x').'<br>';
618  print '<span class="ok">'.$langs->trans("PropalSigned").'</span>';
619  } else {
620  print img_picto('', 'check', '', false, 0, 0, '', 'size2x').'<br>';
621  print '<span class="ok">'.$langs->trans("PropalAlreadySigned").'</span>';
622  }
623  } elseif ($object->status == $object::STATUS_NOTSIGNED) {
624  print '<br>';
625  if ($message == 'refused') {
626  print img_picto('', 'cross', '', false, 0, 0, '', 'size2x').'<br>';
627  print '<span class="ok">'.$langs->trans("PropalRefused").'</span>';
628  } else {
629  print img_picto('', 'cross', '', false, 0, 0, '', 'size2x').'<br>';
630  print '<span class="warning">'.$langs->trans("PropalAlreadyRefused").'</span>';
631  }
632  } else {
633  print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignPropal").'">';
634  print '<input name="refusepropal" type="submit" class="butActionDelete small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("RefusePropal").'">';
635  }
636  } elseif ($source == 'contract') {
637  if ($message == 'signed') {
638  print '<span class="ok">'.$langs->trans("ContractSigned").'</span>';
639  } else {
640  print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignContract").'">';
641  }
642  } elseif ($source == 'fichinter') {
643  if ($message == 'signed') {
644  print '<span class="ok">'.$langs->trans("FichinterSigned").'</span>';
645  } else {
646  print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignFichinter").'">';
647  }
648  }
649 }
650 print '</td></tr>'."\n";
651 print '</table>'."\n";
652 print '</form>'."\n";
653 print '</div>'."\n";
654 print '<br>';
655 
656 
657 htmlPrintOnlineFooter($mysoc, $langs);
658 
659 llxFooter('', 'public');
660 
661 $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.