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