dolibarr 21.0.0-beta
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$head = '';
237if (getDolGlobalString('MAIN_SIGN_CSS_URL')) {
238 $head = '<link rel="stylesheet" type="text/css" href="' . getDolGlobalString('MAIN_SIGN_CSS_URL').'?lang='.$langs->defaultlang.'">'."\n";
239}
240
241$conf->dol_hide_topmenu = 1;
242$conf->dol_hide_leftmenu = 1;
243
244$replacemainarea = (empty($conf->dol_hide_leftmenu) ? '<div>' : '').'<div>';
245llxHeader($head, $langs->trans("OnlineSignature"), '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea, 1);
246
247if ($action == 'refusepropal') {
248 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);
249}
250
251// Check link validity for param 'source' to avoid use of the examples as value
252if (!empty($source) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', 'proposal_ref', ''))) {
253 $langs->load("errors");
254 dol_print_error_email('BADREFINONLINESIGNFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref));
255 // End of page
256 llxFooter();
257 $db->close();
258 exit;
259}
260
261print '<span id="dolpaymentspan"></span>'."\n";
262print '<div class="center">'."\n";
263print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
264print '<input type="hidden" name="token" value="'.newToken().'">'."\n";
265print '<input type="hidden" name="action" value="dosign">'."\n";
266print '<input type="hidden" name="tag" value="'.GETPOST("tag", 'alpha').'">'."\n";
267print '<input type="hidden" name="suffix" value="'.GETPOST("suffix", 'alpha').'">'."\n";
268print '<input type="hidden" name="securekey" value="'.$SECUREKEY.'">'."\n";
269print '<input type="hidden" name="entity" value="'.$entity.'" />';
270print '<input type="hidden" name="page_y" value="" />';
271print '<input type="hidden" name="source" value="'.$source.'" />';
272print '<input type="hidden" name="ref" value="'.$ref.'" />';
273print "\n";
274print '<!-- Form to sign -->'."\n";
275
276print '<table id="dolpublictable" summary="Payment form" class="center">'."\n";
277
278// 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)
279// Define logo and logosmall
280$logosmall = $mysoc->logo_small;
281$logo = $mysoc->logo;
282$paramlogo = 'ONLINE_SIGN_LOGO_'.$suffix;
283if (getDolGlobalString($paramlogo)) {
284 $logosmall = getDolGlobalString($paramlogo);
285} elseif (getDolGlobalString('ONLINE_SIGN_LOGO')) {
286 $logosmall = getDolGlobalString('ONLINE_SIGN_LOGO');
287}
288//print '<!-- Show logo (logosmall='.$logosmall.' logo='.$logo.') -->'."\n";
289// Define urllogo
290$urllogo = '';
291$urllogofull = '';
292if (!empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall)) {
293 $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/thumbs/'.$logosmall);
294 $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall);
295} elseif (!empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo)) {
296 $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/'.$logo);
297 $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo);
298}
299// Output html code for logo
300if ($urllogo) {
301 print '<div class="backgreypublicpayment">';
302 print '<div class="logopublicpayment">';
303 print '<img id="dolpaymentlogo" src="'.$urllogo.'"';
304 print '>';
305 print '</div>';
306 if (!getDolGlobalString('MAIN_HIDE_POWERED_BY')) {
307 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>';
308 }
309 print '</div>';
310}
311if ($source == 'proposal' && getDolGlobalString('PROPOSAL_IMAGE_PUBLIC_SIGN')) {
312 print '<div class="backimagepublicproposalsign">';
313 print '<img id="idPROPOSAL_IMAGE_PUBLIC_INTERFACE" src="' . getDolGlobalString('PROPOSAL_IMAGE_PUBLIC_SIGN').'">';
314 print '</div>';
315}
316
317// Output introduction text
318$text = '';
319if (getDolGlobalString('ONLINE_SIGN_NEWFORM_TEXT')) {
320 $reg = array();
321 if (preg_match('/^\‍((.*)\‍)$/', $conf->global->ONLINE_SIGN_NEWFORM_TEXT, $reg)) {
322 $text .= $langs->trans($reg[1])."<br>\n";
323 } else {
324 $text .= getDolGlobalString('ONLINE_SIGN_NEWFORM_TEXT') . "<br>\n";
325 }
326 $text = '<tr><td align="center"><br>'.$text.'<br></td></tr>'."\n";
327}
328if (empty($text)) {
329 if ($source == 'proposal') {
330 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageProposal", $mysoc->name).'</strong></td></tr>'."\n";
331 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromProposal", $creditor).'<br><br></td></tr>'."\n";
332 } elseif ($source == 'contract') {
333 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageContract", $mysoc->name).'</strong></td></tr>'."\n";
334 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromContract", $creditor).'<br><br></td></tr>'."\n";
335 } elseif ($source == 'fichinter') {
336 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageFichinter", $mysoc->name).'</strong></td></tr>'."\n";
337 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromFichinter", $creditor).'<br><br></td></tr>'."\n";
338 } elseif ($source == 'expedition') {
339 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePageExpedition", $mysoc->name).'</strong></td></tr>'."\n";
340 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFromExpedition", $creditor).'<br><br></td></tr>'."\n";
341 } else {
342 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePage".dol_ucfirst($source), $mysoc->name).'</strong></td></tr>'."\n";
343 $text .= '<tr><td class="textpublicpayment opacitymedium">'.$langs->trans("ThisScreenAllowsYouToSignDocFrom".dol_ucfirst($source), $creditor).'<br><br></td></tr>'."\n";
344 }
345}
346print $text;
347
348// Output payment summary form
349print '<tr><td align="center">';
350print '<table with="100%" id="tablepublicpayment">';
351if ($source == 'proposal') {
352 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignProposal").' :</td></tr>'."\n";
353} elseif ($source == 'contract') {
354 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignContract").' :</td></tr>'."\n";
355} elseif ($source == 'fichinter') {
356 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignFichinter").' :</td></tr>'."\n";
357} elseif ($source == 'expedition') {
358 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSignExpedition").' :</td></tr>'."\n";
359} else {
360 print '<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans("ThisIsInformationOnDocumentToSign".dol_ucfirst($source)).' :</td></tr>'."\n";
361}
362$found = false;
363$error = 0;
364
365// Signature on commercial proposal
366if ($source == 'proposal') {
367 $found = true;
368 $langs->load("proposal");
369
370 $result = $object->fetch_thirdparty($object->socid);
371
372 // Creditor
373 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
374 print '</td><td class="CTableRow2">';
375 print img_picto('', 'company', 'class="pictofixedwidth"');
376 print '<b>'.$creditor.'</b>';
377 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
378 print '</td></tr>'."\n";
379
380 // Debitor
381 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
382 print '</td><td class="CTableRow2">';
383 print img_picto('', 'company', 'class="pictofixedwidth"');
384 print '<b>'.$object->thirdparty->name.'</b>';
385 print '</td></tr>'."\n";
386
387 // Amount
388
389 $amount = '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
390 $amount .= '</td><td class="CTableRow2">';
391 $amount .= '<b>'.price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).'</b>';
392 if ($object->multicurrency_code != $conf->currency) {
393 $amount .= ' ('.price($object->multicurrency_total_ttc, 0, $langs, 1, -1, -1, $object->multicurrency_code).')';
394 }
395 $amount .= '</td></tr>'."\n";
396
397 // Call Hook amountPropalSign
398 $parameters = array('source' => $source);
399 $reshook = $hookmanager->executeHooks('amountPropalSign', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
400 if (empty($reshook)) {
401 $amount .= $hookmanager->resPrint;
402 } elseif ($reshook > 0) {
403 $amount = $hookmanager->resPrint;
404 }
405
406 print $amount;
407
408 // Object
409 $text = '<b>'.$langs->trans("SignatureProposalRef", $object->ref).'</b>';
410 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
411 print '</td><td class="CTableRow2">'.$text;
412
413 $last_main_doc_file = $object->last_main_doc;
414
415 if ($object->status == $object::STATUS_VALIDATED) {
416 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
417 // It seems document has never been generated, or was generated and then deleted.
418 // So we try to regenerate it with its default template.
419 $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.
420 $object->generateDocument($defaulttemplate, $langs);
421 }
422
423 $directdownloadlink = $object->getLastMainDocLink('proposal');
424 if ($directdownloadlink) {
425 print '<br><a href="'.$directdownloadlink.'">';
426 print img_mime($object->last_main_doc, '');
427 print $langs->trans("DownloadDocument").'</a>';
428 }
429 } else {
430 if ($object->status == $object::STATUS_NOTSIGNED) {
431 $directdownloadlink = $object->getLastMainDocLink('proposal');
432 if ($directdownloadlink) {
433 print '<br><a href="'.$directdownloadlink.'">';
434 print img_mime($last_main_doc_file, '');
435 print $langs->trans("DownloadDocument").'</a>';
436 }
437 } elseif ($object->status == $object::STATUS_SIGNED || $object->status == $object::STATUS_BILLED) {
438 if (preg_match('/_signed-(\d+)/', $last_main_doc_file)) { // If the last main doc has been signed
439 $last_main_doc_file_not_signed = preg_replace('/_signed-(\d+)/', '', $last_main_doc_file);
440
441 $datefilesigned = dol_filemtime($last_main_doc_file);
442 $datefilenotsigned = dol_filemtime($last_main_doc_file_not_signed);
443
444 if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) {
445 $directdownloadlink = $object->getLastMainDocLink('proposal');
446 if ($directdownloadlink) {
447 print '<br><a href="'.$directdownloadlink.'">';
448 print img_mime($object->last_main_doc, '');
449 print $langs->trans("DownloadDocument").'</a>';
450 }
451 }
452 }
453 }
454 }
455
456 print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
457 print '<input type="hidden" name="ref" value="'.$object->ref.'">';
458 print '</td></tr>'."\n";
459} elseif ($source == 'contract') { // Signature on contract
460 $found = true;
461 $langs->load("contract");
462
463 $result = $object->fetch_thirdparty($object->socid);
464
465 // Proposer
466 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
467 print '</td><td class="CTableRow2">';
468 print img_picto('', 'company', 'class="pictofixedwidth"');
469 print '<b>'.$creditor.'</b>';
470 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
471 print '</td></tr>'."\n";
472
473 // Target
474 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
475 print '</td><td class="CTableRow2">';
476 print img_picto('', 'company', 'class="pictofixedwidth"');
477 print '<b>'.$object->thirdparty->name.'</b>';
478 print '</td></tr>'."\n";
479
480 // Object
481 $text = '<b>'.$langs->trans("SignatureContractRef", $object->ref).'</b>';
482 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
483 print '</td><td class="CTableRow2">'.$text;
484
485 $last_main_doc_file = $object->last_main_doc;
486
487 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
488 // It seems document has never been generated, or was generated and then deleted.
489 // So we try to regenerate it with its default template.
490 $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.
491 $object->generateDocument($defaulttemplate, $langs);
492 }
493
494 $directdownloadlink = $object->getLastMainDocLink('contract');
495 if ($directdownloadlink) {
496 print '<br><a href="'.$directdownloadlink.'">';
497 print img_mime($object->last_main_doc, '');
498 if ($message == "signed") {
499 print $langs->trans("DownloadSignedDocument").'</a>';
500 } else {
501 print $langs->trans("DownloadDocument").'</a>';
502 }
503 }
504
505
506 print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
507 print '<input type="hidden" name="ref" value="'.$object->ref.'">';
508 print '</td></tr>'."\n";
509} elseif ($source == 'fichinter') {
510 // Signature on fichinter
511 $found = true;
512 $langs->load("interventions");
513
514 $result = $object->fetch_thirdparty($object->socid);
515
516 // Proposer
517 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
518 print '</td><td class="CTableRow2">';
519 print img_picto('', 'company', 'class="pictofixedwidth"');
520 print '<b>'.$creditor.'</b>';
521 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
522 print '</td></tr>'."\n";
523
524 // Target
525 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
526 print '</td><td class="CTableRow2">';
527 print img_picto('', 'company', 'class="pictofixedwidth"');
528 print '<b>'.$object->thirdparty->name.'</b>';
529 print '</td></tr>'."\n";
530
531 // Object
532 $text = '<b>'.$langs->trans("SignatureFichinterRef", $object->ref).'</b>';
533 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
534 print '</td><td class="CTableRow2">'.$text;
535
536 $last_main_doc_file = $object->last_main_doc;
537
538 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
539 // It seems document has never been generated, or was generated and then deleted.
540 // So we try to regenerate it with its default template.
541 $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.
542 $object->generateDocument($defaulttemplate, $langs);
543 }
544
545 $directdownloadlink = $object->getLastMainDocLink('fichinter');
546 if ($directdownloadlink) {
547 print '<br><a href="'.$directdownloadlink.'">';
548 print img_mime($object->last_main_doc, '');
549 if ($message == "signed") {
550 print $langs->trans("DownloadSignedDocument").'</a>';
551 } else {
552 print $langs->trans("DownloadDocument").'</a>';
553 }
554 }
555 print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
556 print '<input type="hidden" name="ref" value="'.$object->ref.'">';
557 print '</td></tr>'."\n";
558} elseif ($source == 'societe_rib') {
559 $found = true;
560 $langs->loadLangs(array("companies", "commercial", "withdrawals"));
561
562 $result = $object->fetch_thirdparty();
563
564 // Proposer
565 print '<tr class="CTableRow2"><td class="CTableRow2">' . $langs->trans("Proposer");
566 print '</td><td class="CTableRow2">';
567 print img_picto('', 'company', 'class="pictofixedwidth"');
568 print '<b>' . $creditor . '</b>';
569 print '<input type="hidden" name="creditor" value="' . $creditor . '">';
570 print '</td></tr>' . "\n";
571
572 // Target
573 print '<tr class="CTableRow2"><td class="CTableRow2">' . $langs->trans("ThirdParty");
574 print '</td><td class="CTableRow2">';
575 print img_picto('', 'company', 'class="pictofixedwidth"');
576 print '<b>' . $object->thirdparty->name . '</b>';
577 print '</td></tr>' . "\n";
578
579 // Object
580 $text = '<b>' . $langs->trans("Signature" . dol_ucfirst($source) . "Ref", $object->ref) . '</b>';
581 print '<tr class="CTableRow2"><td class="CTableRow2">' . $langs->trans("Designation");
582 print '</td><td class="CTableRow2">' . $text;
583
584 $last_main_doc_file = $object->last_main_doc;
585 $diroutput = $conf->societe->multidir_output[$object->thirdparty->entity].'/'
586 .dol_sanitizeFileName((string) $object->thirdparty->id).'/';
587 if ((empty($last_main_doc_file) ||
588 !dol_is_file($diroutput
589 .$langs->transnoentitiesnoconv("SepaMandateShort").' '.$object->id."-".dol_sanitizeFileName($object->rum).".pdf"))
590 && $message != "signed") {
591 // It seems document has never been generated, or was generated and then deleted.
592 // So we try to regenerate it with its default template.
593 //$defaulttemplate = 'sepamandate';
594 $defaulttemplate = getDolGlobalString("BANKADDON_PDF");
595
596 $object->setDocModel($user, $defaulttemplate);
597 $moreparams = array(
598 'use_companybankid' => $object->id,
599 'force_dir_output' => $diroutput
600 );
601 $result = $object->thirdparty->generateDocument($defaulttemplate, $langs, 0, 0, 0, $moreparams);
602 $object->last_main_doc = $object->thirdparty->last_main_doc;
603 }
604 $directdownloadlink = $object->getLastMainDocLink('company');
605 if ($directdownloadlink) {
606 print '<br><a href="'.$directdownloadlink.'">';
607 print img_mime($object->last_main_doc, '');
608 if ($message == "signed") {
609 print $langs->trans("DownloadSignedDocument").'</a>';
610 } else {
611 print $langs->trans("DownloadDocument").'</a>';
612 }
613 }
614} elseif ($source == 'expedition') {
615 // Signature on expedition
616 $found = true;
617 $langs->load("interventions");
618
619 $result = $object->fetch_thirdparty($object->socid);
620
621 // Proposer
622 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
623 print '</td><td class="CTableRow2">';
624 print img_picto('', 'company', 'class="pictofixedwidth"');
625 print '<b>'.$creditor.'</b>';
626 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
627 print '</td></tr>'."\n";
628
629 // Target
630 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
631 print '</td><td class="CTableRow2">';
632 print img_picto('', 'company', 'class="pictofixedwidth"');
633 print '<b>'.$object->thirdparty->name.'</b>';
634 print '</td></tr>'."\n";
635
636 // Object
637 $text = '<b>'.$langs->trans("SignatureFichinterRef", $object->ref).'</b>';
638 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
639 print '</td><td class="CTableRow2">'.$text;
640
641 $last_main_doc_file = $object->last_main_doc;
642 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
643 // It seems document has never been generated, or was generated and then deleted.
644 // So we try to regenerate it with its default template.
645 $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.
646 $object->generateDocument($defaulttemplate, $langs);
647 }
648 $directdownloadlink = $object->getLastMainDocLink('', 0, 0);
649 if ($directdownloadlink) {
650 print '<br><a href="'.$directdownloadlink.'">';
651 print img_mime($object->last_main_doc, '');
652 if ($message == "signed") {
653 print $langs->trans("DownloadSignedDocument").'</a>';
654 } else {
655 print $langs->trans("DownloadDocument").'</a>';
656 }
657 }
658 print '<input type="hidden" name="source" value="'.GETPOST("source", 'alpha').'">';
659 print '<input type="hidden" name="ref" value="'.$object->ref.'">';
660 print '</td></tr>'."\n";
661} else {
662 $found = true;
663 $langs->load('companies');
664
665 if (!empty($object->socid) || !empty($object->fk_soc)) {
666 $result = $object->fetch_thirdparty();
667 }
668
669 // Proposer
670 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Proposer");
671 print '</td><td class="CTableRow2">';
672 print img_picto('', 'company', 'class="pictofixedwidth"');
673 print '<b>'.$creditor.'</b>';
674 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
675 print '</td></tr>'."\n";
676
677 // Target
678 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
679 print '</td><td class="CTableRow2">';
680 print img_picto('', 'company', 'class="pictofixedwidth"');
681 print '<b>'.$object->thirdparty->name.'</b>';
682 print '</td></tr>'."\n";
683
684 // Object
685 $text = '<b>'.$langs->trans("Signature".dol_ucfirst($source)."Ref", $object->ref).'</b>';
686 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
687 print '</td><td class="CTableRow2">'.$text;
688
689 $last_main_doc_file = $object->last_main_doc;
690
691 if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
692 // It seems document has never been generated, or was generated and then deleted.
693 // So we try to regenerate it with its default template.
694 $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.
695 $object->generateDocument($defaulttemplate, $langs);
696 }
697
698 $directdownloadlink = $object->getLastMainDocLink($source);
699 if ($directdownloadlink) {
700 print '<br><a href="'.$directdownloadlink.'">';
701 print img_mime($object->last_main_doc, '');
702 if ($message == "signed") {
703 print $langs->trans("DownloadSignedDocument").'</a>';
704 } else {
705 print $langs->trans("DownloadDocument").'</a>';
706 }
707 }
708}
709
710// Call Hook addFormSign
711$parameters = array('source' => $source);
712$reshook = $hookmanager->executeHooks('addFormSign', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
713
714if (!$found && !$mesg) {
715 $mesg = $langs->transnoentitiesnoconv("ErrorBadParameters");
716}
717
718if ($mesg) {
719 print '<tr><td class="center" colspan="2"><br><div class="warning">'.dol_escape_htmltag($mesg).'</div></td></tr>'."\n";
720}
721
722print '</table>'."\n";
723print "\n";
724
725if ($action != 'dosign') {
726 if ($found && !$error) {
727 // We are in a management option and no error
728 } else {
729 dol_print_error_email('ERRORNEWONLINESIGN');
730 }
731} else {
732 // Print
733}
734
735print '</td></tr>'."\n";
736print '<tr><td class="center">';
737
738
739if ($action == "dosign" && empty($cancel)) {
740 // Show the field to sign
741 print '<div class="tablepublicpayment">';
742 print '<input type="text" class="paddingleftonly marginleftonly paddingrightonly marginrightonly marginbottomonly borderbottom" id="name" placeholder="'.$langs->trans("Lastname").'" autofocus>';
743 print '<div id="signature" style="border:solid;"></div>';
744 print '</div>';
745 print '<input type="button" class="small noborderbottom cursorpointer buttonreset" id="clearsignature" value="'.$langs->trans("ClearSignature").'">';
746
747 // 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.
748 print '<div>';
749 print '<input type="button" class="button marginleftonly marginrightonly" id="signbutton" value="'.$langs->trans("Sign").'">';
750 print '<input type="submit" class="button butActionDelete marginleftonly marginrightonly" name="cancel" value="'.$langs->trans("Cancel").'">';
751 print '</div>';
752
753 // Add js code managed into the div #signature
754 $urltogo = $_SERVER["PHP_SELF"].'?ref='.urlencode($ref).'&source='.urlencode($source).'&message=signed&securekey='.urlencode($SECUREKEY).(isModEnabled('multicompany') ? '&entity='.(int) $entity : '');
755 print '<script language="JavaScript" type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jSignature/jSignature.js"></script>
756 <script type="text/javascript">
757 $(document).ready(function() {
758 $("#signature").jSignature({ color:"#000", lineWidth:0, '.(empty($conf->dol_optimize_smallscreen) ? '' : 'width: 280, ').'height: 180});
759
760 $("#signature").on("change",function(){
761 $("#clearsignature").css("display","");
762 $("#signbutton").attr("disabled",false);
763 if(!$._data($("#signbutton")[0], "events")){
764 $("#signbutton").on("click",function(){
765 console.log("We click on button sign");
766 document.body.style.cursor = \'wait\';
767 /* $("#signbutton").val(\''.dol_escape_js($langs->transnoentities('PleaseBePatient')).'\'); */
768 var signature = $("#signature").jSignature("getData", "image");
769 var name = document.getElementById("name").value;
770 $.ajax({
771 type: "POST",
772 url: \''.DOL_URL_ROOT.'/core/ajax/onlineSign.php\',
773 dataType: "text",
774 data: {
775 "action" : \'importSignature\',
776 "token" : \''.newToken().'\',
777 "signaturebase64" : signature,
778 "onlinesignname" : name,
779 "ref" : \''.dol_escape_js($REF).'\',
780 "securekey" : \''.dol_escape_js($SECUREKEY).'\',
781 "mode" : \''.dol_escape_js($source).'\',
782 "entity" : \''.dol_escape_js((string) $entity).'\',
783 },
784 success: function(response) {
785 if (response.trim() === "success") {
786 console.log("Success on saving signature");
787 window.location.replace(\''.dol_escape_js($urltogo).'\');
788 } else {
789 document.body.style.cursor = \'auto\';
790 console.error(response);
791 alert("Error on calling the core/ajax/onlineSign.php. See console log.");
792 }
793 },
794 error: function(response) {
795 document.body.style.cursor = \'auto\';
796 console.error(response);
797 alert("Error on calling the core/ajax/onlineSign.php. "+response.responseText);
798 }
799 });
800 });
801 }
802 });
803
804 $("#clearsignature").on("click",function(){
805 $("#signature").jSignature("clear");
806 $("#signbutton").attr("disabled",true);
807 // document.getElementById("onlinesignname").value = "";
808 });
809
810 $("#signbutton").attr("disabled",true);
811 });
812 </script>';
813} else {
814 if ($source == 'proposal') {
815 if ($object->status == $object::STATUS_SIGNED) {
816 print '<br>';
817 if ($message == 'signed') {
818 print img_picto('', 'check', '', 0, 0, 0, '', 'size2x').'<br>';
819 print '<span class="ok">'.$langs->trans("PropalSigned").'</span>';
820 } else {
821 print img_picto('', 'check', '', 0, 0, 0, '', 'size2x').'<br>';
822 print '<span class="ok">'.$langs->trans("PropalAlreadySigned").'</span>';
823 }
824 } elseif ($object->status == $object::STATUS_NOTSIGNED) {
825 print '<br>';
826 if ($message == 'refused') {
827 print img_picto('', 'cross', '', 0, 0, 0, '', 'size2x').'<br>';
828 print '<span class="ok">'.$langs->trans("PropalRefused").'</span>';
829 } else {
830 print img_picto('', 'cross', '', 0, 0, 0, '', 'size2x').'<br>';
831 print '<span class="warning">'.$langs->trans("PropalAlreadyRefused").'</span>';
832 }
833 } else {
834 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignPropal").'">';
835 print '<input name="refusepropal" type="submit" class="butActionDelete small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("RefusePropal").'">';
836 }
837 } elseif ($source == 'contract') {
838 if ($message == 'signed') {
839 print '<span class="ok">'.$langs->trans("ContractSigned").'</span>';
840 } else {
841 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignContract").'">';
842 }
843 } elseif ($source == 'fichinter') {
844 if ($message == 'signed') {
845 print '<span class="ok">'.$langs->trans("FichinterSigned").'</span>';
846 } else {
847 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignFichinter").'">';
848 }
849 } elseif ($source == 'expedition') {
850 if ($message == 'signed' || $object->signed_status == Expedition::$SIGNED_STATUSES['STATUS_SIGNED_SENDER']) {
851 print '<span class="ok">'.$langs->trans("ExpeditionSigned").'</span>';
852 } else {
853 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignExpedition").'">';
854 }
855 } else {
856 if ($message == 'signed') {
857 print '<span class="ok">'.$langs->trans(dol_ucfirst($source)."Signed").'</span>';
858 } else {
859 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("Sign".dol_ucfirst($source)).'">';
860 }
861 }
862}
863print '</td></tr>'."\n";
864print '</table>'."\n";
865print '</form>'."\n";
866print '</div>'."\n";
867print '<br>';
868
869
870htmlPrintOnlineFooter($mysoc, $langs);
871
872llxFooter('', 'public');
873
874$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
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.
htmlPrintOnlineFooter($fromcompany, $langs, $addformmessage=0, $suffix='', $object=null)
Show footer of company in HTML pages.
llxFooter()
Footer empty.
Definition document.php:107
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)
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)
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:149
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:152
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,...