27 if (!defined(
'NOLOGIN')) {
30 if (!defined(
'NOCSRFCHECK')) {
31 define(
"NOCSRFCHECK", 1);
33 if (!defined(
'NOIPCHECK')) {
34 define(
'NOIPCHECK',
'1');
36 if (!defined(
'NOBROWSERNOTIF')) {
37 define(
'NOBROWSERNOTIF',
'1');
43 $entity = (!empty($_GET[
'entity']) ? (int) $_GET[
'entity'] : (!empty($_POST[
'entity']) ? (int) $_POST[
'entity'] : 1));
44 if (is_numeric($entity)) {
45 define(
"DOLENTITY", $entity);
48 require
'../../main.inc.php';
49 require_once DOL_DOCUMENT_ROOT.
'/core/lib/company.lib.php';
50 require_once DOL_DOCUMENT_ROOT.
'/core/lib/payments.lib.php';
51 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
52 require_once DOL_DOCUMENT_ROOT.
'/core/lib/functions2.lib.php';
53 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
56 $langs->loadLangs(array(
"main",
"other",
"dict",
"bills",
"companies",
"errors",
"members",
"paybox",
"propal"));
62 $action =
GETPOST(
'action',
'aZ09');
63 $cancel =
GETPOST(
'cancel',
'alpha');
64 $confirm =
GETPOST(
'confirm',
'alpha');
67 $refusepropal =
GETPOST(
'refusepropal',
'alpha');
68 $message =
GETPOST(
'message',
'aZ09');
77 $suffix =
GETPOST(
"suffix",
'aZ09');
78 $source =
GETPOST(
"source",
'alpha');
79 $ref = $REF =
GETPOST(
"ref",
'alpha');
86 if ($source && !$ref) {
87 print $langs->trans(
'ErrorBadParameters').
" - ref missing";
91 if (!empty($refusepropal)) {
92 $action =
"refusepropal";
98 $urlwithroot = DOL_MAIN_URL_ROOT;
102 $SECUREKEY =
GETPOST(
"securekey");
104 if (!empty($source)) {
105 $urlok .=
'source='.urlencode($source).
'&';
106 $urlko .=
'source='.urlencode($source).
'&';
109 $urlok .=
'ref='.urlencode($REF).
'&';
110 $urlko .=
'ref='.urlencode($REF).
'&';
112 if (!empty($SECUREKEY)) {
113 $urlok .=
'securekey='.urlencode($SECUREKEY).
'&';
114 $urlko .=
'securekey='.urlencode($SECUREKEY).
'&';
116 if (!empty($entity)) {
117 $urlok .=
'entity='.urlencode($entity).
'&';
118 $urlko .=
'entity='.urlencode($entity).
'&';
120 $urlok = preg_replace(
'/&$/',
'', $urlok);
121 $urlko = preg_replace(
'/&$/',
'', $urlko);
123 $creditor = $mysoc->name;
126 if ($source ==
'proposal') {
127 require_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
128 $object =
new Propal($db);
129 $result= $object->fetch(0, $ref,
'', $entity);
138 if ($source ==
'proposal') {
139 $securekeyseed = $conf->global->PROPOSAL_ONLINE_SIGNATURE_SECURITY_TOKEN;
142 if (!
dol_verifyHash($securekeyseed.$type.$ref.(empty($conf->multicompany->enabled) ?
'' : $entity), $SECUREKEY,
'0')) {
143 http_response_code(403);
144 print
'Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).
' does not match expected value for ref='.
dol_escape_htmltag($ref);
153 if ($action ==
'confirm_refusepropal' && $confirm ==
'yes') {
156 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
157 $sql .=
" SET fk_statut = ".((int) $object::STATUS_NOTSIGNED).
", note_private = '".$db->escape($object->note_private).
"', date_signature='".$db->idate(
dol_now()).
"'";
158 $sql .=
" WHERE rowid = ".((int) $object->id);
161 $resql = $db->query($sql);
169 $message =
'refused';
171 if (method_exists($object,
'call_trigger')) {
173 $user =
new User($db);
174 $user->fetch($object->user_valid_id);
175 $result = $object->call_trigger(
'PROPAL_CLOSE_REFUSED', $user);
184 $object->fetch(0, $ref);
194 if (!empty($conf->global->MAIN_SIGN_CSS_URL)) {
195 $head =
'<link rel="stylesheet" type="text/css" href="'.$conf->global->MAIN_SIGN_CSS_URL.
'?lang='.$langs->defaultlang.
'">'.
"\n";
198 $conf->dol_hide_topmenu = 1;
199 $conf->dol_hide_leftmenu = 1;
201 $replacemainarea = (empty($conf->dol_hide_leftmenu) ?
'<div>' :
'').
'<div>';
202 llxHeader($head, $langs->trans(
"OnlineSignature"),
'',
'', 0, 0,
'',
'',
'',
'onlinepaymentbody', $replacemainarea, 1);
204 if ($action ==
'refusepropal') {
205 print
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?ref='.urlencode($ref).
'&securekey='.urlencode($SECUREKEY).($conf->multicompany->enabled?
'&entity='.$entity:
''), $langs->trans(
'RefusePropal'), $langs->trans(
'ConfirmRefusePropal', $object->ref),
'confirm_refusepropal',
'',
'', 1);
209 if (!empty($source) && in_array($ref, array(
'member_ref',
'contractline_ref',
'invoice_ref',
'order_ref',
'proposal_ref',
''))) {
210 $langs->load(
"errors");
211 dol_print_error_email(
'BADREFINONLINESIGNFORM', $langs->trans(
"ErrorBadLinkSourceSetButBadValueForRef", $source, $ref));
218 print
'<span id="dolpaymentspan"></span>'.
"\n";
219 print
'<div class="center">'.
"\n";
220 print
'<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER[
"PHP_SELF"].
'" method="POST">'.
"\n";
221 print
'<input type="hidden" name="token" value="'.newToken().
'">'.
"\n";
222 print
'<input type="hidden" name="action" value="dosign">'.
"\n";
223 print
'<input type="hidden" name="tag" value="'.GETPOST(
"tag",
'alpha').
'">'.
"\n";
224 print
'<input type="hidden" name="suffix" value="'.GETPOST(
"suffix",
'alpha').
'">'.
"\n";
225 print
'<input type="hidden" name="securekey" value="'.$SECUREKEY.
'">'.
"\n";
226 print
'<input type="hidden" name="entity" value="'.$entity.
'" />';
227 print
'<input type="hidden" name="page_y" value="" />';
229 print
'<!-- Form to sign -->'.
"\n";
231 print
'<table id="dolpublictable" summary="Payment form" class="center">'.
"\n";
235 $logosmall = $mysoc->logo_small;
236 $logo = $mysoc->logo;
237 $paramlogo =
'ONLINE_SIGN_LOGO_'.$suffix;
238 if (!empty($conf->global->$paramlogo)) {
239 $logosmall = $conf->global->$paramlogo;
240 } elseif (!empty($conf->global->ONLINE_SIGN_LOGO)) {
241 $logosmall = $conf->global->ONLINE_SIGN_LOGO;
247 if (!empty($logosmall) && is_readable($conf->mycompany->dir_output.
'/logos/thumbs/'.$logosmall)) {
248 $urllogo = DOL_URL_ROOT.
'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.
'&file='.urlencode(
'logos/thumbs/'.$logosmall);
249 $urllogofull = $dolibarr_main_url_root.
'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.
'&file='.urlencode(
'logos/thumbs/'.$logosmall);
250 } elseif (!empty($logo) && is_readable($conf->mycompany->dir_output.
'/logos/'.$logo)) {
251 $urllogo = DOL_URL_ROOT.
'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.
'&file='.urlencode(
'logos/'.$logo);
252 $urllogofull = $dolibarr_main_url_root.
'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.
'&file='.urlencode(
'logos/'.$logo);
256 print
'<div class="backgreypublicpayment">';
257 print
'<div class="logopublicpayment">';
258 print
'<img id="dolpaymentlogo" src="'.$urllogo.
'"';
261 if (empty($conf->global->MAIN_HIDE_POWERED_BY)) {
262 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>';
266 if ($source ==
'proposal' && !empty($conf->global->PROPOSAL_IMAGE_PUBLIC_SIGN)) {
267 print
'<div class="backimagepublicproposalsign">';
268 print
'<img id="idPROPOSAL_IMAGE_PUBLIC_INTERFACE" src="'.$conf->global->PROPOSAL_IMAGE_PUBLIC_SIGN.
'">';
274 if (!empty($conf->global->ONLINE_SIGN_NEWFORM_TEXT)) {
276 if (preg_match(
'/^\((.*)\)$/', $conf->global->ONLINE_SIGN_NEWFORM_TEXT, $reg)) {
277 $text .= $langs->trans($reg[1]).
"<br>\n";
279 $text .= $conf->global->ONLINE_SIGN_NEWFORM_TEXT.
"<br>\n";
281 $text =
'<tr><td align="center"><br>'.$text.
'<br></td></tr>'.
"\n";
284 $text .=
'<tr><td class="textpublicpayment"><br><strong>'.$langs->trans(
"WelcomeOnOnlineSignaturePage", $mysoc->name).
'</strong></td></tr>'.
"\n";
285 $text .=
'<tr><td class="textpublicpayment opacitymedium">'.$langs->trans(
"ThisScreenAllowsYouToSignDocFrom", $creditor).
'<br><br></td></tr>'.
"\n";
290 print
'<tr><td align="center">';
291 print
'<table with="100%" id="tablepublicpayment">';
292 print
'<tr><td align="left" colspan="2" class="opacitymedium">'.$langs->trans(
"ThisIsInformationOnDocumentToSign").
' :</td></tr>'.
"\n";
298 if ($source ==
'proposal') {
300 $langs->load(
"proposal");
302 $result = $object->fetch_thirdparty($object->socid);
305 print
'<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans(
"Creditor");
306 print
'</td><td class="CTableRow2">';
307 print
img_picto(
'',
'company',
'class="pictofixedwidth"');
308 print
'<b>'.$creditor.
'</b>';
309 print
'<input type="hidden" name="creditor" value="'.$creditor.
'">';
310 print
'</td></tr>'.
"\n";
313 print
'<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans(
"ThirdParty");
314 print
'</td><td class="CTableRow2">';
315 print
img_picto(
'',
'company',
'class="pictofixedwidth"');
316 print
'<b>'.$object->thirdparty->name.
'</b>';
317 print
'</td></tr>'.
"\n";
320 print
'<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans(
"Amount");
321 print
'</td><td class="CTableRow2">';
322 print
'<b>'.price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).
'</b>';
323 print
'</td></tr>'.
"\n";
326 $text =
'<b>'.$langs->trans(
"SignatureProposalRef", $object->ref).
'</b>';
327 print
'<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans(
"Designation");
328 print
'</td><td class="CTableRow2">'.$text;
330 $last_main_doc_file = $object->last_main_doc;
332 if ($object->status == $object::STATUS_VALIDATED) {
333 if (empty($last_main_doc_file) || !
dol_is_file(DOL_DATA_ROOT.
'/'.$object->last_main_doc)) {
336 $defaulttemplate =
'';
337 $object->generateDocument($defaulttemplate, $langs);
340 $directdownloadlink = $object->getLastMainDocLink(
'proposal');
341 if ($directdownloadlink) {
342 print
'<br><a href="'.$directdownloadlink.
'">';
343 print
img_mime($object->last_main_doc,
'');
344 print $langs->trans(
"DownloadDocument").
'</a>';
347 if ($object->status == $object::STATUS_NOTSIGNED) {
348 $directdownloadlink = $object->getLastMainDocLink(
'proposal');
349 if ($directdownloadlink) {
350 print
'<br><a href="'.$directdownloadlink.
'">';
351 print
img_mime($last_main_doc_file,
'');
352 print $langs->trans(
"DownloadDocument").
'</a>';
354 } elseif ($object->status == $object::STATUS_SIGNED || $object->status == $object::STATUS_BILLED) {
355 if (preg_match(
'/_signed-(\d+)/', $last_main_doc_file)) {
356 $last_main_doc_file_not_signed = preg_replace(
'/_signed-(\d+)/',
'', $last_main_doc_file);
359 $datefilenotsigned =
dol_filemtime($last_main_doc_file_not_signed);
361 if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) {
362 $directdownloadlink = $object->getLastMainDocLink(
'proposal');
363 if ($directdownloadlink) {
364 print
'<br><a href="'.$directdownloadlink.
'">';
365 print
img_mime($object->last_main_doc,
'');
366 print $langs->trans(
"DownloadDocument").
'</a>';
373 print
'<input type="hidden" name="source" value="'.GETPOST(
"source",
'alpha').
'">';
374 print
'<input type="hidden" name="ref" value="'.$object->ref.
'">';
375 print
'</td></tr>'.
"\n";
380 if (!$found && !$mesg) {
381 $mesg = $langs->transnoentitiesnoconv(
"ErrorBadParameters");
385 print
'<tr><td class="center" colspan="2"><br><div class="warning">'.dol_escape_htmltag($mesg).
'</div></td></tr>'.
"\n";
388 print
'</table>'.
"\n";
391 if ($action !=
'dosign') {
392 if ($found && !$error) {
401 print
'</td></tr>'.
"\n";
402 print
'<tr><td class="center">';
405 if ($action ==
"dosign" && empty($cancel)) {
406 print
'<div class="tablepublicpayment">';
407 print
'<input type="button" class="buttonDelete small" id="clearsignature" value="'.$langs->trans(
"ClearSignature").
'">';
408 print
'<div id="signature" style="border:solid;"></div>';
411 print
'<input type="button" class="button" id="signbutton" value="'.$langs->trans(
"Sign").
'">';
412 print
'<input type="submit" class="button" name="cancel" value="'.$langs->trans(
"Cancel").
'">';
415 print
'<script language="JavaScript" type="text/javascript" src="'.DOL_URL_ROOT.
'/includes/jquery/plugins/jSignature/jSignature.js"></script>
416 <script type="text/javascript">
417 $(document).ready(function() {
418 $("#signature").jSignature({ color:"#000", lineWidth:4, '.(empty($conf->dol_optimize_smallscreen) ?
'' :
'width: 280, ' ).
'height: 180});
420 $("#signature").on("change",function(){
421 $("#clearsignature").css("display","");
422 $("#signbutton").attr("disabled",false);
423 if(!$._data($("#signbutton")[0], "events")){
424 $("#signbutton").on("click",function(){
425 var signature = $("#signature").jSignature("getData", "image");
428 url: "'.DOL_URL_ROOT.
'/core/ajax/onlineSign.php",
431 "action" : "importSignature",
432 "signaturebase64" : signature,
434 "securekey" : \
''.dol_escape_js($SECUREKEY).
'\',
435 "mode" : \
''.dol_escape_htmltag($source).
'\',
436 "entity" : \
''.dol_escape_htmltag($entity).
'\',
438 success:
function(response) {
439 if(response ==
"success"){
440 console.log(
"Success on saving signature");
441 window.location.replace(
"'.$_SERVER["PHP_SELF
"].'?ref='.urlencode($ref).'&message=signed&securekey='.urlencode($SECUREKEY).($conf->multicompany->enabled?'&entity='.$entity:'').'");
443 console.error(response);
451 $(
"#clearsignature").on(
"click",
function(){
452 $(
"#signature").jSignature(
"clear");
453 $(
"#signbutton").attr(
"disabled",
true);
456 $(
"#signbutton").attr(
"disabled",
true);
460 if ($source == 'proposal
') {
461 if ($object->status == $object::STATUS_SIGNED) {
463 if ($message == 'signed') {
464 print '<span
class=
"ok">
'.$langs->trans("PropalSigned").'</span>
';
466 print '<span
class=
"ok">
'.$langs->trans("PropalAlreadySigned").'</span>
';
468 } elseif ($object->status == $object::STATUS_NOTSIGNED) {
470 if ($message == 'refused
') {
471 print '<span
class=
"ok">
'.$langs->trans("PropalRefused").'</span>
';
473 print '<span
class=
"warning">
'.$langs->trans("PropalAlreadyRefused").'</span>
';
476 print '<input
type=
"submit" class=
"butAction small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value=
"'.$langs->trans("SignPropal
").'">
';
477 print '<input
name=
"refusepropal" type=
"submit" class=
"butActionDelete small wraponsmartphone marginbottomonly marginleftonly marginrightonly reposition" value=
"'.$langs->trans("RefusePropal
").'">
';
481 print '</td></tr>
'."\n";
482 print '</table>
'."\n";
483 print '</form>
'."\n";
488 htmlPrintOnlinePaymentFooter($mysoc, $langs);
490 llxFooter('', 'public');