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