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
28if (!defined('NOLOGIN')) {
29 define("NOLOGIN", 1); // This means this output page does not require to be logged.
30}
31if (!defined('NOCSRFCHECK')) {
32 define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
33}
34if (!defined('NOIPCHECK')) {
35 define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
36}
37if (!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));
45if (is_numeric($entity)) {
46 define("DOLENTITY", $entity);
47}
48
49// Load Dolibarr environment
50require '../../main.inc.php';
51require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
52require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
53require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
54require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
55require_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
86if (empty($source)) {
87 $source = 'proposal';
88}
89if (!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
102if (!empty($source)) {
103 $urlok .= 'source='.urlencode($source).'&';
104 $urlko .= 'source='.urlencode($source).'&';
105}
106if (!empty($REF)) {
107 $urlok .= 'ref='.urlencode($REF).'&';
108 $urlko .= 'ref='.urlencode($REF).'&';
109}
110if (!empty($SECUREKEY)) {
111 $urlok .= 'securekey='.urlencode($SECUREKEY).'&';
112 $urlko .= 'securekey='.urlencode($SECUREKEY).'&';
113}
114if (!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
125if (!$action) {
126 if ($source && !$ref) {
127 httponly_accessforbidden($langs->trans('ErrorBadParameters')." - ref missing", 400, 1);
128 }
129}
130
131// Check securitykey
132$securekeyseed = '';
133if ($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}
140if (!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
144if ($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
170if ($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 = '';
212if (!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>';
220llxHeader($head, $langs->trans("OnlineSignature"), '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea, 1);
221
222if ($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
227if (!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
236print '<span id="dolpaymentspan"></span>'."\n";
237print '<div class="center">'."\n";
238print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
239print '<input type="hidden" name="token" value="'.newToken().'">'."\n";
240print '<input type="hidden" name="action" value="dosign">'."\n";
241print '<input type="hidden" name="tag" value="'.GETPOST("tag", 'alpha').'">'."\n";
242print '<input type="hidden" name="suffix" value="'.GETPOST("suffix", 'alpha').'">'."\n";
243print '<input type="hidden" name="securekey" value="'.$SECUREKEY.'">'."\n";
244print '<input type="hidden" name="entity" value="'.$entity.'" />';
245print '<input type="hidden" name="page_y" value="" />';
246print "\n";
247print '<!-- Form to sign -->'."\n";
248
249print '<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;
256if (!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 = '';
265if (!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
273if ($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}
284if ($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 = '';
292if (!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}
301if (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}
313print $text;
314
315// Output payment summary form
316print '<tr><td align="center">';
317print '<table with="100%" id="tablepublicpayment">';
318if ($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
329if ($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
526if (!$found && !$mesg) {
527 $mesg = $langs->transnoentitiesnoconv("ErrorBadParameters");
528}
529
530if ($mesg) {
531 print '<tr><td class="center" colspan="2"><br><div class="warning">'.dol_escape_htmltag($mesg).'</div></td></tr>'."\n";
532}
533
534print '</table>'."\n";
535print "\n";
536
537if ($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
547print '</td></tr>'."\n";
548print '<tr><td class="center">';
549
550
551if ($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}
650print '</td></tr>'."\n";
651print '</table>'."\n";
652print '</form>'."\n";
653print '</div>'."\n";
654print '<br>';
655
656
657htmlPrintOnlineFooter($mysoc, $langs);
658
659llxFooter('', '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
$object ref
Definition info.php:78
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.
htmlPrintOnlineFooter($fromcompany, $langs, $addformmessage=0, $suffix='', $object=null)
Show footer of company in HTML pages.
dol_filemtime($pathoffile)
Return time of a file.
dol_is_file($pathoffile)
Return if path is a file.
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.
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.