dolibarr 21.0.3
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 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
32if (!defined('NOLOGIN')) {
33 define("NOLOGIN", 1); // This means this output page does not require to be logged.
34}
35if (!defined('NOCSRFCHECK')) {
36 define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
37}
38if (!defined('NOIPCHECK')) {
39 define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
40}
41if (!defined('NOBROWSERNOTIF')) {
42 define('NOBROWSERNOTIF', '1');
43}
44
45// For MultiCompany module.
46// Do not use GETPOST here, function is not defined and define must be done before including main.inc.php
47// Because 2 entities can have the same ref.
48$entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
49if (is_numeric($entity)) {
50 define("DOLENTITY", $entity);
51}
52
53// Load Dolibarr environment
54require '../../main.inc.php';
55require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
56require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
57require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
58require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
59require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
60require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
61
71// Load translation files
72$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", "members", "paybox", "stripe", "propal", "commercial"));
73
74// Security check
75// No check on module enabled. Done later according to $validpaymentmethod
76
77// Get parameters
78$action = GETPOST('action', 'aZ09');
79$cancel = GETPOST('cancel', 'alpha');
80$confirm = GETPOST('confirm', 'alpha');
81
82
83$refusepropal = GETPOST('refusepropal', 'alpha');
84$message = GETPOST('message', 'aZ09');
85
86// Input are:
87// type ('invoice','order','contractline'),
88// id (object id),
89// amount (required if id is empty),
90// tag (a free text, required if type is empty)
91// currency (iso code)
92
93$suffix = GETPOST("suffix", 'aZ09');
94$source = GETPOST("source", 'alpha');
95$ref = $REF = GETPOST("ref", 'alpha');
96$urlok = '';
97$urlko = '';
98
99
100if (empty($source)) {
101 $source = 'proposal';
102}
103if (!empty($refusepropal)) {
104 $action = "refusepropal";
105}
106
107// Define $urlwithroot
108//$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
109//$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
110$urlwithroot = DOL_MAIN_URL_ROOT; // This is to use same domain name than current. For Paypal payment, we can use internal URL like localhost.
111
112
113// Complete urls for post treatment
114$SECUREKEY = GETPOST("securekey"); // Secure key
115
116if (!empty($source)) {
117 $urlok .= 'source='.urlencode($source).'&';
118 $urlko .= 'source='.urlencode($source).'&';
119}
120if (!empty($REF)) {
121 $urlok .= 'ref='.urlencode($REF).'&';
122 $urlko .= 'ref='.urlencode($REF).'&';
123}
124if (!empty($SECUREKEY)) {
125 $urlok .= 'securekey='.urlencode($SECUREKEY).'&';
126 $urlko .= 'securekey='.urlencode($SECUREKEY).'&';
127}
128if (!empty($entity)) {
129 $urlok .= 'entity='.urlencode((string) ($entity)).'&';
130 $urlko .= 'entity='.urlencode((string) ($entity)).'&';
131}
132$urlok = preg_replace('/&$/', '', $urlok); // Remove last &
133$urlko = preg_replace('/&$/', '', $urlko); // Remove last &
134
135$creditor = $mysoc->name;
136
137$type = $source;
138if (!$action) {
139 if ($source && !$ref) {
140 httponly_accessforbidden($langs->trans('ErrorBadParameters')." - ref missing", 400, 1);
141 }
142}
143
144// Check securitykey
145$securekeyseed = '';
146if ($source == 'proposal') {
147 $securekeyseed = getDolGlobalString('PROPOSAL_ONLINE_SIGNATURE_SECURITY_TOKEN');
148} elseif ($source == 'contract') {
149 $securekeyseed = getDolGlobalString('CONTRACT_ONLINE_SIGNATURE_SECURITY_TOKEN');
150} elseif ($source == 'fichinter') {
151 $securekeyseed = getDolGlobalString('FICHINTER_ONLINE_SIGNATURE_SECURITY_TOKEN');
152} elseif ($source == 'societe_rib') {
153 $securekeyseed = getDolGlobalString('SOCIETE_RIB_ONLINE_SIGNATURE_SECURITY_TOKEN');
154}
155if (!dol_verifyHash($securekeyseed.$type.$ref.(isModEnabled('multicompany') ? $entity : ''), $SECUREKEY, '0')) {
156 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);
157}
158
159if ($source == 'proposal') {
160 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
161 $object = new Propal($db);
162 $result = $object->fetch(0, $ref, '', $entity);
163} elseif ($source == 'contract') {
164 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
165 $object = new Contrat($db);
166 $result = $object->fetch(0, $ref);
167} elseif ($source == 'fichinter') {
168 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
169 $object = new Fichinter($db);
170 $result = $object->fetch(0, $ref);
171} elseif ($source == 'societe_rib') {
172 require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
173 $object = new CompanyBankAccount($db);
174 $result = $object->fetch(0, $ref);
175} elseif ($source == 'expedition') {
176 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
177 $object = new Expedition($db);
178 $result = $object->fetch(0, $ref);
179} else {
180 httponly_accessforbidden($langs->trans('ErrorBadParameters')." - Bad value for source. Value not supported.", 400, 1);
181}
182
183// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
184$hookmanager->initHooks(array('onlinesign'));
185
186$error = 0;
187
188
189/*
190 * Actions
191 */
192
193if ($action == 'confirm_refusepropal' && $confirm == 'yes') { // Test on pemrission not required here. Public form. Security checked on the securekey and on mitigation
194 $db->begin();
195
196 $sql = "UPDATE ".MAIN_DB_PREFIX."propal";
197 $sql .= " SET fk_statut = ".((int) $object::STATUS_NOTSIGNED).", note_private = '".$db->escape($object->note_private)."', date_signature = '".$db->idate(dol_now())."'";
198 $sql .= " WHERE rowid = ".((int) $object->id);
199
200 dol_syslog(__FILE__, LOG_DEBUG);
201 $resql = $db->query($sql);
202 if (!$resql) {
203 $error++;
204 }
205
206 if (!$error) {
207 $db->commit();
208
209 $message = 'refused';
210 setEventMessages("PropalRefused", null, 'warnings');
211 if (method_exists($object, 'call_trigger')) {
212 // Online customer is not a user, so we use the use that validates the documents
213 $user = new User($db);
214 $user->fetch($object->user_validation_id);
215 $object->context = array('closedfromonlinesignature' => 'closedfromonlinesignature');
216 $result = $object->call_trigger('PROPAL_CLOSE_REFUSED', $user);
217 if ($result < 0) {
218 $error++;
219 }
220 }
221 } else {
222 $db->rollback();
223 }
224
225 $object->fetch(0, $ref);
226}
227
228// $action == "dosign" is handled later...
229
230
231/*
232 * View
233 */
234
235$form = new Form($db);
236
237$head = '';
238if (getDolGlobalString('MAIN_SIGN_CSS_URL')) {
239 $head = '<link rel="stylesheet" type="text/css" href="' . getDolGlobalString('MAIN_SIGN_CSS_URL').'?lang='.$langs->defaultlang.'">'."\n";
240}
241
242$conf->dol_hide_topmenu = 1;
243$conf->dol_hide_leftmenu = 1;
244
245$title = $langs->trans("OnlineSignature");
246
247$replacemainarea = (empty($conf->dol_hide_leftmenu) ? '<div>' : '').'<div>';
248llxHeader($head, $title, '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea, 1);
249
250htmlPrintOnlineHeader($mysoc, $langs, $suffix);
251
252if ($action == 'refusepropal') {
253 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);
254}
255
256// Check link validity for param 'source' to avoid use of the examples as value
257if (!empty($source) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', 'proposal_ref', ''))) {
258 $langs->load("errors");
259 dol_print_error_email('BADREFINONLINESIGNFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref));
260 // End of page
261 llxFooter();
262 $db->close();
263 exit;
264}
265
266print '<span id="dolpaymentspan"></span>'."\n";
267print '<div class="center">'."\n";
268print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
269print '<input type="hidden" name="token" value="'.newToken().'">'."\n";
270print '<input type="hidden" name="action" value="dosign">'."\n";
271print '<input type="hidden" name="tag" value="'.GETPOST("tag", 'alpha').'">'."\n";
272print '<input type="hidden" name="suffix" value="'.GETPOST("suffix", 'alpha').'">'."\n";
273print '<input type="hidden" name="securekey" value="'.$SECUREKEY.'">'."\n";
274print '<input type="hidden" name="entity" value="'.$entity.'" />';
275print '<input type="hidden" name="page_y" value="" />';
276print '<input type="hidden" name="source" value="'.$source.'" />';
277print '<input type="hidden" name="ref" value="'.$ref.'" />';
278print "\n";
279print '<!-- Form to sign -->'."\n";
280
281print '<table id="dolpublictable" summary="Payment form" class="center">'."\n";
282
283if ($source == 'proposal' && getDolGlobalString('PROPOSAL_IMAGE_PUBLIC_SIGN')) {
284 print '<div class="backimagepublicproposalsign">';
285 print '<img id="idPROPOSAL_IMAGE_PUBLIC_INTERFACE" src="' . getDolGlobalString('PROPOSAL_IMAGE_PUBLIC_SIGN').'">';
286 print '</div>';
287}
288
289// Output introduction text
290$text = '';
291if (getDolGlobalString('ONLINE_SIGN_NEWFORM_TEXT')) {
292 $reg = array();
293 if (preg_match('/^\‍((.*)\‍)$/', $conf->global->ONLINE_SIGN_NEWFORM_TEXT, $reg)) {
294 $text .= $langs->trans($reg[1])."<br>\n";
295 } else {
296 $text .= getDolGlobalString('ONLINE_SIGN_NEWFORM_TEXT') . "<br>\n";
297 }
298 $text = '<tr><td align="center"><br>'.$text.'<br></td></tr>'."\n";
299}
300if (empty($text)) {
301 if ($source == 'proposal') {
302 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageProposal", $mysoc->name).'</strong></td></tr>'."\n";
303 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromProposal", $creditor).'<br><br></td></tr>'."\n";
304 } elseif ($source == 'contract') {
305 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageContract", $mysoc->name).'</strong></td></tr>'."\n";
306 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromContract", $creditor).'<br><br></td></tr>'."\n";
307 } elseif ($source == 'fichinter') {
308 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageFichinter", $mysoc->name).'</strong></td></tr>'."\n";
309 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromFichinter", $creditor).'<br><br></td></tr>'."\n";
310 } elseif ($source == 'expedition') {
311 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageExpedition", $mysoc->name).'</strong></td></tr>'."\n";
312 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromExpedition", $creditor).'<br><br></td></tr>'."\n";
313 } else {
314 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePage".dol_ucfirst($source), $mysoc->name).'</strong></td></tr>'."\n";
315 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFrom".dol_ucfirst($source), $creditor).'<br><br></td></tr>'."\n";
316 }
317}
318print $text;
319
320// Output payment summary form
321print '<tr><td align="center">';
322print '<table with="100%" id="tablepublicpayment">';
323if ($source == 'proposal') {
324 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignProposal").' :</td></tr>'."\n";
325} elseif ($source == 'contract') {
326 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignContract").' :</td></tr>'."\n";
327} elseif ($source == 'fichinter') {
328 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignFichinter").' :</td></tr>'."\n";
329} elseif ($source == 'expedition') {
330 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignExpedition").' :</td></tr>'."\n";
331} else {
332 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSign".dol_ucfirst($source)).' :</td></tr>'."\n";
333}
334$found = false;
335$error = 0;
336
337// Signature on commercial proposal
338if ($source == 'proposal') {
339 $found = true;
340 $langs->load("proposal");
341
342 $result = $object->fetch_thirdparty($object->socid);
343
344 // Creditor
345 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
346 print '</td><td class="CTableRow2">';
347 print img_picto('', 'company', 'class="pictofixedwidth"');
348 print '<b>'.$creditor.'</b>';
349 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
350 print '</td></tr>'."\n";
351
352 // Debitor
353 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
354 print '</td><td class="CTableRow2">';
355 print img_picto('', 'company', 'class="pictofixedwidth"');
356 print '<b>'.$object->thirdparty->name.'</b>';
357 print '</td></tr>'."\n";
358
359 // Amount
360
361 $amount = '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
362 $amount .= '</td><td class="CTableRow2">';
363 $amount .= '<b>'.price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).'</b>';
364 if ($object->multicurrency_code != $conf->currency) {
365 $amount .= ' ('.price($object->multicurrency_total_ttc, 0, $langs, 1, -1, -1, $object->multicurrency_code).')';
366 }
367 $amount .= '</td></tr>'."\n";
368
369 // Call Hook amountPropalSign
370 $parameters = array('source' => $source);
371 $reshook = $hookmanager->executeHooks('amountPropalSign', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
372 if (empty($reshook)) {
373 $amount .= $hookmanager->resPrint;
374 } elseif ($reshook > 0) {
375 $amount = $hookmanager->resPrint;
376 }
377
378 print $amount;
379
380 // Object
381 $text = '<b>'.$langs->trans("SignatureProposalRef", $object->ref).'</b>';
382 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
383 print '</td><td class="CTableRow2">'.$text;
384
385 $last_main_doc_file = $object->last_main_doc;
386
387 if ($object->status == $object::STATUS_VALIDATED) {
388 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
389 // It seems document has never been generated, or was generated and then deleted.
390 // So we try to regenerate it with its default template.
391 $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.
392 $object->generateDocument($defaulttemplate, $langs);
393 }
394
395 $directdownloadlink = $object->getLastMainDocLink('proposal');
396 if ($directdownloadlink) {
397 print '<br><a href="'.$directdownloadlink.'">';
398 print img_mime($object->last_main_doc, '');
399 print $langs->trans("DownloadDocument").'</a>';
400 }
401 } else {
402 if ($object->status == $object::STATUS_NOTSIGNED) {
403 $directdownloadlink = $object->getLastMainDocLink('proposal');
404 if ($directdownloadlink) {
405 print '<br><a href="'.$directdownloadlink.'">';
406 print img_mime($last_main_doc_file, '');
407 print $langs->trans("DownloadDocument").'</a>';
408 }
409 } elseif ($object->status == $object::STATUS_SIGNED || $object->status == $object::STATUS_BILLED) {
410 if (preg_match('/_signed-(\d+)/', $last_main_doc_file)) { // If the last main doc has been signed
411 $last_main_doc_file_not_signed = preg_replace('/_signed-(\d+)/', '', $last_main_doc_file);
412
413 $datefilesigned = dol_filemtime($last_main_doc_file);
414 $datefilenotsigned = dol_filemtime($last_main_doc_file_not_signed);
415
416 if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) {
417 $directdownloadlink = $object->getLastMainDocLink('proposal');
418 if ($directdownloadlink) {
419 print '<br><a href="'.$directdownloadlink.'">';
420 print img_mime($object->last_main_doc, '');
421 print $langs->trans("DownloadDocument").'</a>';
422 }
423 }
424 }
425 }
426 }
427
428 print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
429 print '<input type="hidden" name="ref" value="'.$object->ref.'">';
430 print '</td></tr>'."\n";
431} elseif ($source == 'contract') { // Signature on contract
432 $found = true;
433 $langs->load("contract");
434
435 $result = $object->fetch_thirdparty($object->socid);
436
437 // Proposer
438 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
439 print '</td><td class="CTableRow2">';
440 print img_picto('', 'company', 'class="pictofixedwidth"');
441 print '<b>'.$creditor.'</b>';
442 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
443 print '</td></tr>'."\n";
444
445 // Target
446 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
447 print '</td><td class="CTableRow2">';
448 print img_picto('', 'company', 'class="pictofixedwidth"');
449 print '<b>'.$object->thirdparty->name.'</b>';
450 print '</td></tr>'."\n";
451
452 // Object
453 $text = '<b>'.$langs->trans("SignatureContractRef", $object->ref).'</b>';
454 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
455 print '</td><td class="CTableRow2">'.$text;
456
457 $last_main_doc_file = $object->last_main_doc;
458
459 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
460 // It seems document has never been generated, or was generated and then deleted.
461 // So we try to regenerate it with its default template.
462 $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.
463 $object->generateDocument($defaulttemplate, $langs);
464 }
465
466 $directdownloadlink = $object->getLastMainDocLink('contract');
467 if ($directdownloadlink) {
468 print '<br><a href="'.$directdownloadlink.'">';
469 print img_mime($object->last_main_doc, '');
470 if ($message == "signed") {
471 print $langs->trans("DownloadSignedDocument").'</a>';
472 } else {
473 print $langs->trans("DownloadDocument").'</a>';
474 }
475 }
476
477
478 print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
479 print '<input type="hidden" name="ref" value="'.$object->ref.'">';
480 print '</td></tr>'."\n";
481} elseif ($source == 'fichinter') {
482 // Signature on fichinter
483 $found = true;
484 $langs->load("interventions");
485
486 $result = $object->fetch_thirdparty($object->socid);
487
488 // Proposer
489 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
490 print '</td><td class="CTableRow2">';
491 print img_picto('', 'company', 'class="pictofixedwidth"');
492 print '<b>'.$creditor.'</b>';
493 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
494 print '</td></tr>'."\n";
495
496 // Target
497 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
498 print '</td><td class="CTableRow2">';
499 print img_picto('', 'company', 'class="pictofixedwidth"');
500 print '<b>'.$object->thirdparty->name.'</b>';
501 print '</td></tr>'."\n";
502
503 // Object
504 $text = '<b>'.$langs->trans("SignatureFichinterRef", $object->ref).'</b>';
505 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
506 print '</td><td class="CTableRow2">'.$text;
507
508 $last_main_doc_file = $object->last_main_doc;
509
510 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
511 // It seems document has never been generated, or was generated and then deleted.
512 // So we try to regenerate it with its default template.
513 $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.
514 $object->generateDocument($defaulttemplate, $langs);
515 }
516
517 $directdownloadlink = $object->getLastMainDocLink('fichinter');
518 if ($directdownloadlink) {
519 print '<br><a href="'.$directdownloadlink.'">';
520 print img_mime($object->last_main_doc, '');
521 if ($message == "signed") {
522 print $langs->trans("DownloadSignedDocument").'</a>';
523 } else {
524 print $langs->trans("DownloadDocument").'</a>';
525 }
526 }
527 print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
528 print '<input type="hidden" name="ref" value="'.$object->ref.'">';
529 print '</td></tr>'."\n";
530} elseif ($source == 'societe_rib') {
531 $found = true;
532 $langs->loadLangs(array("companies", "commercial", "withdrawals"));
533
534 $result = $object->fetch_thirdparty();
535
536 // Proposer
537 print '<tr class="CTableRow2"><td class="CTableRow2">' . $langs->trans("Proposer");
538 print '</td><td class="CTableRow2">';
539 print img_picto('', 'company', 'class="pictofixedwidth"');
540 print '<b>' . $creditor . '</b>';
541 print '<input type="hidden" name="creditor" value="' . $creditor . '">';
542 print '</td></tr>' . "\n";
543
544 // Target
545 print '<tr class="CTableRow2"><td class="CTableRow2">' . $langs->trans("ThirdParty");
546 print '</td><td class="CTableRow2">';
547 print img_picto('', 'company', 'class="pictofixedwidth"');
548 print '<b>' . $object->thirdparty->name . '</b>';
549 print '</td></tr>' . "\n";
550
551 // Object
552 $text = '<b>' . $langs->trans("Signature" . dol_ucfirst($source) . "Ref", $object->ref) . '</b>';
553 print '<tr class="CTableRow2"><td class="CTableRow2">' . $langs->trans("Designation");
554 print '</td><td class="CTableRow2">' . $text;
555
556 $last_main_doc_file = $object->last_main_doc;
557 $diroutput = $conf->societe->multidir_output[$object->thirdparty->entity].'/'
558 .dol_sanitizeFileName((string) $object->thirdparty->id).'/';
559 if ((empty($last_main_doc_file) ||
560 !dol_is_file($diroutput
561 .$langs->transnoentitiesnoconv("SepaMandateShort").' '.$object->id."-".dol_sanitizeFileName($object->rum).".pdf"))
562 && $message != "signed") {
563 // It seems document has never been generated, or was generated and then deleted.
564 // So we try to regenerate it with its default template.
565 //$defaulttemplate = 'sepamandate';
566 $defaulttemplate = getDolGlobalString("BANKADDON_PDF");
567
568 $object->setDocModel($user, $defaulttemplate);
569 $moreparams = array(
570 'use_companybankid' => $object->id,
571 'force_dir_output' => $diroutput
572 );
573 $result = $object->thirdparty->generateDocument($defaulttemplate, $langs, 0, 0, 0, $moreparams);
574 $object->last_main_doc = $object->thirdparty->last_main_doc;
575 }
576 $directdownloadlink = $object->getLastMainDocLink('company');
577 if ($directdownloadlink) {
578 print '<br><a href="'.$directdownloadlink.'">';
579 print img_mime($object->last_main_doc, '');
580 if ($message == "signed") {
581 print $langs->trans("DownloadSignedDocument").'</a>';
582 } else {
583 print $langs->trans("DownloadDocument").'</a>';
584 }
585 }
586} elseif ($source == 'expedition') {
587 // Signature on expedition
588 $found = true;
589 $langs->load("interventions");
590
591 $result = $object->fetch_thirdparty($object->socid);
592
593 // Proposer
594 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
595 print '</td><td class="CTableRow2">';
596 print img_picto('', 'company', 'class="pictofixedwidth"');
597 print '<b>'.$creditor.'</b>';
598 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
599 print '</td></tr>'."\n";
600
601 // Target
602 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
603 print '</td><td class="CTableRow2">';
604 print img_picto('', 'company', 'class="pictofixedwidth"');
605 print '<b>'.$object->thirdparty->name.'</b>';
606 print '</td></tr>'."\n";
607
608 // Object
609 $text = '<b>'.$langs->trans("SignatureFichinterRef", $object->ref).'</b>';
610 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
611 print '</td><td class="CTableRow2">'.$text;
612
613 $last_main_doc_file = $object->last_main_doc;
614 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
615 // It seems document has never been generated, or was generated and then deleted.
616 // So we try to regenerate it with its default template.
617 $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.
618 $object->generateDocument($defaulttemplate, $langs);
619 }
620 $directdownloadlink = $object->getLastMainDocLink('', 0, 0);
621 if ($directdownloadlink) {
622 print '<br><a href="'.$directdownloadlink.'">';
623 print img_mime($object->last_main_doc, '');
624 if ($message == "signed") {
625 print $langs->trans("DownloadSignedDocument").'</a>';
626 } else {
627 print $langs->trans("DownloadDocument").'</a>';
628 }
629 }
630 print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
631 print '<input type="hidden" name="ref" value="'.$object->ref.'">';
632 print '</td></tr>'."\n";
633} else {
634 $found = true;
635 $langs->load('companies');
636
637 if (!empty($object->socid) || !empty($object->fk_soc)) {
638 $result = $object->fetch_thirdparty();
639 }
640
641 // Proposer
642 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
643 print '</td><td class="CTableRow2">';
644 print img_picto('', 'company', 'class="pictofixedwidth"');
645 print '<b>'.$creditor.'</b>';
646 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
647 print '</td></tr>'."\n";
648
649 // Target
650 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
651 print '</td><td class="CTableRow2">';
652 print img_picto('', 'company', 'class="pictofixedwidth"');
653 print '<b>'.$object->thirdparty->name.'</b>';
654 print '</td></tr>'."\n";
655
656 // Object
657 $text = '<b>'.$langs->trans("Signature".dol_ucfirst($source)."Ref", $object->ref).'</b>';
658 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
659 print '</td><td class="CTableRow2">'.$text;
660
661 $last_main_doc_file = $object->last_main_doc;
662
663 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
664 // It seems document has never been generated, or was generated and then deleted.
665 // So we try to regenerate it with its default template.
666 $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.
667 $object->generateDocument($defaulttemplate, $langs);
668 }
669
670 $directdownloadlink = $object->getLastMainDocLink($source);
671 if ($directdownloadlink) {
672 print '<br><a href="'.$directdownloadlink.'">';
673 print img_mime($object->last_main_doc, '');
674 if ($message == "signed") {
675 print $langs->trans("DownloadSignedDocument").'</a>';
676 } else {
677 print $langs->trans("DownloadDocument").'</a>';
678 }
679 }
680}
681
682// Call Hook addFormSign
683$parameters = array('source' => $source);
684$reshook = $hookmanager->executeHooks('addFormSign', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
685
686if (!$found && !$mesg) {
687 $mesg = $langs->transnoentitiesnoconv("ErrorBadParameters");
688}
689
690if ($mesg) {
691 print '<tr><td class="center" colspan="2"><br><div class="warning">'.dol_escape_htmltag($mesg).'</div></td></tr>'."\n";
692}
693
694print '</table>'."\n";
695print "\n";
696
697if ($action != 'dosign') {
698 if ($found && !$error) {
699 // We are in a management option and no error
700 } else {
701 dol_print_error_email('ERRORNEWONLINESIGN');
702 }
703} else {
704 // Print
705}
706
707print '</td></tr>'."\n";
708print '<tr><td class="center">';
709
710
711if ($action == "dosign" && empty($cancel)) {
712 // Show the field to sign
713 print '<div class="tablepublicpayment">';
714 print '<input type="text" class="paddingleftonly marginleftonly paddingrightonly marginrightonly marginbottomonly borderbottom" id="name" placeholder="'.$langs->trans("Lastname").'" autofocus>';
715 print '<div id="signature" style="border:solid;"></div>';
716 print '</div>';
717 print '<input type="button" class="small noborderbottom cursorpointer buttonreset" id="clearsignature" value="'.$langs->trans("ClearSignature").'">';
718
719 // 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.
720 print '<div>';
721 print '<input type="button" class="button marginleftonly marginrightonly" id="signbutton" value="'.$langs->trans("Sign").'">';
722 print '<input type="submit" class="button butActionDelete marginleftonly marginrightonly" name="cancel" value="'.$langs->trans("Cancel").'">';
723 print '</div>';
724
725 // Add js code managed into the div #signature
726 $urltogo = $_SERVER["PHP_SELF"].'?ref='.urlencode($ref).'&source='.urlencode($source).'&message=signed&securekey='.urlencode($SECUREKEY).(isModEnabled('multicompany') ? '&entity='.(int) $entity : '');
727 print '<script language="JavaScript" type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jSignature/jSignature.js"></script>
728 <script type="text/javascript">
729 $(document).ready(function() {
730 $("#signature").jSignature({ color:"#000", lineWidth:0, '.(empty($conf->dol_optimize_smallscreen) ? '' : 'width: 280, ').'height: 180});
731
732 $("#signature").on("change",function(){
733 $("#clearsignature").css("display","");
734 $("#signbutton").attr("disabled",false);
735 if(!$._data($("#signbutton")[0], "events")){
736 $("#signbutton").on("click",function(){
737 console.log("We click on button sign");
738 document.body.style.cursor = \'wait\';
739 /* $("#signbutton").val(\''.dol_escape_js($langs->transnoentities('PleaseBePatient')).'\'); */
740 var signature = $("#signature").jSignature("getData", "image");
741 var name = document.getElementById("name").value;
742 $.ajax({
743 type: "POST",
744 url: \''.DOL_URL_ROOT.'/core/ajax/onlineSign.php\',
745 dataType: "text",
746 data: {
747 "action" : \'importSignature\',
748 "token" : \''.newToken().'\',
749 "signaturebase64" : signature,
750 "onlinesignname" : name,
751 "ref" : \''.dol_escape_js($REF).'\',
752 "securekey" : \''.dol_escape_js($SECUREKEY).'\',
753 "mode" : \''.dol_escape_js($source).'\',
754 "entity" : \''.dol_escape_js((string) $entity).'\',
755 },
756 success: function(response) {
757 if (response.trim() === "success") {
758 console.log("Success on saving signature");
759 window.location.replace(\''.dol_escape_js($urltogo).'\');
760 } else {
761 document.body.style.cursor = \'auto\';
762 console.error(response);
763 alert("Error on calling the core/ajax/onlineSign.php. See console log.");
764 }
765 },
766 error: function(response) {
767 document.body.style.cursor = \'auto\';
768 console.error(response);
769 alert("Error on calling the core/ajax/onlineSign.php. "+response.responseText);
770 }
771 });
772 });
773 }
774 });
775
776 $("#clearsignature").on("click",function(){
777 $("#signature").jSignature("clear");
778 $("#signbutton").attr("disabled",true);
779 // document.getElementById("onlinesignname").value = "";
780 });
781
782 $("#signbutton").attr("disabled",true);
783 });
784 </script>';
785} else {
786 if ($source == 'proposal') {
787 if ($object->status == $object::STATUS_SIGNED) {
788 print '<br>';
789 if ($message == 'signed') {
790 print img_picto('', 'check', '', 0, 0, 0, '', 'size2x').'<br>';
791 print '<span class="ok">'.$langs->trans("PropalSigned").'</span>';
792 } else {
793 print img_picto('', 'check', '', 0, 0, 0, '', 'size2x').'<br>';
794 print '<span class="ok">'.$langs->trans("PropalAlreadySigned").'</span>';
795 }
796 } elseif ($object->status == $object::STATUS_NOTSIGNED) {
797 print '<br>';
798 if ($message == 'refused') {
799 print img_picto('', 'cross', '', 0, 0, 0, '', 'size2x').'<br>';
800 print '<span class="ok">'.$langs->trans("PropalRefused").'</span>';
801 } else {
802 print img_picto('', 'cross', '', 0, 0, 0, '', 'size2x').'<br>';
803 print '<span class="warning">'.$langs->trans("PropalAlreadyRefused").'</span>';
804 }
805 } else {
806 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignPropal").'">';
807 print '<input name="refusepropal" type="submit" class="butActionDelete small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("RefusePropal").'">';
808 }
809 } elseif ($source == 'contract') {
810 if ($message == 'signed') {
811 print '<span class="ok">'.$langs->trans("ContractSigned").'</span>';
812 } else {
813 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignContract").'">';
814 }
815 } elseif ($source == 'fichinter') {
816 if ($message == 'signed') {
817 print '<span class="ok">'.$langs->trans("FichinterSigned").'</span>';
818 } else {
819 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignFichinter").'">';
820 }
821 } elseif ($source == 'expedition') {
822 if ($message == 'signed' || $object->signed_status == Expedition::$SIGNED_STATUSES['STATUS_SIGNED_SENDER']) {
823 print '<span class="ok">'.$langs->trans("ExpeditionSigned").'</span>';
824 } else {
825 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignExpedition").'">';
826 }
827 } else {
828 if ($message == 'signed') {
829 print '<span class="ok">'.$langs->trans(dol_ucfirst($source)."Signed").'</span>';
830 } else {
831 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("Sign".dol_ucfirst($source)).'">';
832 }
833 }
834}
835print '</td></tr>'."\n";
836print '</table>'."\n";
837
838print '</form>'."\n";
839print '</div>'."\n";
840print '<br>';
841
842
843htmlPrintOnlineFooter($mysoc, $langs);
844
845llxFooter('', 'public');
846
847$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
$object ref
Definition info.php:89
Class to manage bank accounts description of third parties.
Class to manage generation of HTML components Only common components must be here.
Class to manage proposals.
Class to manage Dolibarr users.
htmlPrintOnlineHeader($mysoc, $langs, $suffix='')
Show header of company in HTML public pages.
htmlPrintOnlineFooter($fromcompany, $langs, $addformmessage=0, $suffix='', $object=null)
Show footer of company in HTML public pages.
dol_filemtime($pathoffile)
Return time of a file.
dol_is_file($pathoffile)
Return if path is a file.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
dol_ucfirst($string, $encoding="UTF-8")
Convert first character of the first word of a string to upper.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_now($mode='auto')
Return date for now.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error_email($prefixcode, $errormessage='', $errormessages=array(), $morecss='error', $email='')
Show a public email and error code to contact if technical error.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:150
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:153
httponly_accessforbidden($message='1', $http_response_code=403, $stringalreadysanitized=0)
Show a message to say access is forbidden and stop program.
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons,...