dolibarr 20.0.0
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 technical object to manage hooks of page. Note that conf->hooks_modules contains 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') {
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 (!empty($conf->global->$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("fichinter");
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("fichinter");
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 print '<script language="JavaScript" type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jSignature/jSignature.js"></script>
743 <script type="text/javascript">
744 $(document).ready(function() {
745 $("#signature").jSignature({ color:"#000", lineWidth:0, '.(empty($conf->dol_optimize_smallscreen) ? '' : 'width: 280, ').'height: 180});
746
747 $("#signature").on("change",function(){
748 $("#clearsignature").css("display","");
749 $("#signbutton").attr("disabled",false);
750 if(!$._data($("#signbutton")[0], "events")){
751 $("#signbutton").on("click",function(){
752 console.log("We click on button sign");
753 document.body.style.cursor = \'wait\';
754 /* $("#signbutton").val(\''.dol_escape_js($langs->transnoentities('PleaseBePatient')).'\'); */
755 var signature = $("#signature").jSignature("getData", "image");
756 var name = document.getElementById("name").value;
757 $.ajax({
758 type: "POST",
759 url: "'.DOL_URL_ROOT.'/core/ajax/onlineSign.php",
760 dataType: "text",
761 data: {
762 "action" : "importSignature",
763 "token" : \''.newToken().'\',
764 "signaturebase64" : signature,
765 "onlinesignname" : name,
766 "ref" : \''.dol_escape_js($REF).'\',
767 "securekey" : \''.dol_escape_js($SECUREKEY).'\',
768 "mode" : \''.dol_escape_htmltag($source).'\',
769 "entity" : \''.dol_escape_htmltag($entity).'\',
770 },
771 success: function(response) {
772 if (response.trim() === "success") {
773 console.log("Success on saving signature");
774 window.location.replace("'.$_SERVER["PHP_SELF"].'?ref='.urlencode($ref).'&source='.urlencode($source).'&message=signed&securekey='.urlencode($SECUREKEY).(isModEnabled('multicompany') ? '&entity='.(int) $entity : '').'");
775 } else {
776 document.body.style.cursor = \'auto\';
777 console.error(response);
778 alert("Error on calling the core/ajax/onlineSign.php. See console log.");
779 }
780 },
781 error: function(response) {
782 document.body.style.cursor = \'auto\';
783 console.error(response);
784 alert("Error on calling the core/ajax/onlineSign.php. "+response.responseText);
785 }
786 });
787 });
788 }
789 });
790
791 $("#clearsignature").on("click",function(){
792 $("#signature").jSignature("clear");
793 $("#signbutton").attr("disabled",true);
794 // document.getElementById("onlinesignname").value = "";
795 });
796
797 $("#signbutton").attr("disabled",true);
798 });
799 </script>';
800} else {
801 if ($source == 'proposal') {
802 if ($object->status == $object::STATUS_SIGNED) {
803 print '<br>';
804 if ($message == 'signed') {
805 print img_picto('', 'check', '', false, 0, 0, '', 'size2x').'<br>';
806 print '<span class="ok">'.$langs->trans("PropalSigned").'</span>';
807 } else {
808 print img_picto('', 'check', '', false, 0, 0, '', 'size2x').'<br>';
809 print '<span class="ok">'.$langs->trans("PropalAlreadySigned").'</span>';
810 }
811 } elseif ($object->status == $object::STATUS_NOTSIGNED) {
812 print '<br>';
813 if ($message == 'refused') {
814 print img_picto('', 'cross', '', false, 0, 0, '', 'size2x').'<br>';
815 print '<span class="ok">'.$langs->trans("PropalRefused").'</span>';
816 } else {
817 print img_picto('', 'cross', '', false, 0, 0, '', 'size2x').'<br>';
818 print '<span class="warning">'.$langs->trans("PropalAlreadyRefused").'</span>';
819 }
820 } else {
821 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignPropal").'">';
822 print '<input name="refusepropal" type="submit" class="butActionDelete small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("RefusePropal").'">';
823 }
824 } elseif ($source == 'contract') {
825 if ($message == 'signed') {
826 print '<span class="ok">'.$langs->trans("ContractSigned").'</span>';
827 } else {
828 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignContract").'">';
829 }
830 } elseif ($source == 'fichinter') {
831 if ($message == 'signed') {
832 print '<span class="ok">'.$langs->trans("FichinterSigned").'</span>';
833 } else {
834 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignFichinter").'">';
835 }
836 } elseif ($source == 'expedition') {
837 if ($message == 'signed' || $object->signed_status == Expedition::STATUS_SIGNED) {
838 print '<span class="ok">'.$langs->trans("ExpeditionSigned").'</span>';
839 } else {
840 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("SignExpedition").'">';
841 }
842 } else {
843 if ($message == 'signed') {
844 print '<span class="ok">'.$langs->trans(dol_ucfirst($source)."Signed").'</span>';
845 } else {
846 print '<input type="submit" class="butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value="'.$langs->trans("Sign".dol_ucfirst($source)).'">';
847 }
848 }
849}
850print '</td></tr>'."\n";
851print '</table>'."\n";
852print '</form>'."\n";
853print '</div>'."\n";
854print '<br>';
855
856
857htmlPrintOnlineFooter($mysoc, $langs);
858
859llxFooter('', 'public');
860
861$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()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
$object ref
Definition info.php:79
Class to manage bank accounts description of third parties.
Class to manage contracts.
Class to manage shipments.
const STATUS_SIGNED
Signed status.
Class to manage interventions.
Class to manage generation of HTML components Only common components must be here.
Class to manage proposals.
Class to manage Dolibarr users.
htmlPrintOnlineFooter($fromcompany, $langs, $addformmessage=0, $suffix='', $object=null)
Show footer of company in HTML pages.
dol_filemtime($pathoffile)
Return time of a file.
dol_is_file($pathoffile)
Return if path is a file.
dol_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.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error_email($prefixcode, $errormessage='', $errormessages=array(), $morecss='error', $email='')
Show a public email and error code to contact if technical error.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php: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,...