dolibarr 25.0.0-alpha
blockedlog.lib.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
3 * Copyright (C) 2018 Destailleur Laurent <eldy@users.sourceforge.net>
4 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5 * Copyright (C) 2026 Frédéric France <frederic.france@free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27include_once DOL_DOCUMENT_ROOT.'/blockedlog/versionmod.inc.php';
28
29
36{
37 $versionbadge = constant('DOLCERT_VERSION');
38
39 // Protection if we used a past old version not yet certified, we change version shown.
40 if (!constant('CERTIF_LNE')) { // Hard coded in version
41 // $versionbadge = preg_replace('/^(\d)\./', '\1b.', $versionbadge); // Not yet required.
42 }
43
44 if (constant('DOLCERT_NAME') != 'BlockedLog') { // Can add a prefix namevefore version text for clarity.
45 $versionbadge = constant('DOLCERT_NAME').'-'.$versionbadge;
46 }
47
48 return $versionbadge;
49}
50
51
58function blockedlogadmin_prepare_head($withtabsetup)
59{
60 global $db, $langs, $conf, $mysoc;
61
62 $langs->load("blockedlog");
63
64 require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
65
66 $param = '';
67 $param .= ($withtabsetup? "?withtab=".$withtabsetup : "");
68 $param .= (GETPOST('origin') ? ($param ? '&' : '?').'origin='.GETPOST('origin') : '');
69
70 $h = 0;
71 $head = array();
72
73 if (!userIsTaxAuditor()) {
74 $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/registration.php".$param;
75 $head[$h][1] = $langs->trans("UserRegistration");
76 $head[$h][2] = 'registration';
77 $h++;
78 }
79
80 if (!userIsTaxAuditor()) {
81 $b = new BlockedLog($db);
82 $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/blockedlog_list.php".$param;
83 $head[$h][1] = $langs->trans("BrowseBlockedLog");
84 if ($b->alreadyUsed()) {
85 $head[$h][1] .= (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') ? '<span class="badge marginleftonlyshort">...</span>' : '');
86 }
87 $head[$h][2] = 'fingerprints';
88 $h++;
89 }
90
91 $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/blockedlog_archives.php".$param;
92 $head[$h][1] = $langs->trans("Archives");
93 // Add badge on nb of files
94 $block_static = new BlockedLog($db);
95 $upload_dir = getMultidirOutput($block_static, 'blockedlog').'/archives';
96 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
97 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
98 $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
99 $nbLinks = 0;
100 if (($nbFiles + $nbLinks) > 0) {
101 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.($nbFiles + $nbLinks).'</span>';
102 }
103 $head[$h][2] = 'archives';
104 $h++;
105
106 if (userIsTaxAuditor()) {
107 $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/blockedlog_control.php".$param;
108 $head[$h][1] = $langs->trans("OtherControl");
109 $head[$h][2] = 'control';
110 $h++;
111 }
112
113 if ($mysoc->country_code == 'FR') {
114 $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/documentation.php".$param;
115 $head[$h][1] = $langs->trans("Documentation");
116 $head[$h][2] = 'documentation';
117 $h++;
118 }
119
120 if ($withtabsetup && !userIsTaxAuditor()) {
121 $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/blockedlog.php".$param;
122 $head[$h][1] = $langs->trans("TechnicalInformation");
123 $head[$h][2] = 'technicalinfo';
124 $h++;
125 }
126
127
128 $object = new stdClass();
129
130 // Show more tabs from modules
131 // Entries must be declared in modules descriptor with line
132 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
133 // $this->tabs = array('entity:-tabname); to remove a tab
134 complete_head_from_modules($conf, $langs, $object, $head, $h, 'blockedlog');
135
136 complete_head_from_modules($conf, $langs, $object, $head, $h, 'blockedlog', 'remove');
137
138 return $head;
139}
140
141
149{
150 global $mysoc;
151
152 $companyname = getDolGlobalString('BLOCKEDLOG_REGISTRATION_NAME', $mysoc->name);
153 $companyemail = getDolGlobalString('BLOCKEDLOG_REGISTRATION_EMAIL', $mysoc->email);
154 $companycountrycode = $mysoc->country_code;
155 $companyidprof1 = getDolGlobalString('MAIN_INFO_SIREN', $mysoc->idprof1);
156 $companyidprof2 = getDolGlobalString('MAIN_INFO_SIRET', $mysoc->idprof2);
157 //$companytel = getDolGlobalString('BLOCKEDLOG_REGISTRATION_TEL', $mysoc->phone);
158
159 if (empty($companyname) || empty($companycountrycode) || empty($companyidprof1) || empty($companyidprof2) || empty($companyemail)) {
160 return false;
161 }
162 /*
163 $providerset = getDolGlobalString('MAIN_INFO_ITPROVIDER_NAME'); // Can be 'myself'
164
165 if (empty($providerset)) {
166 return false;
167 }
168 */
169
170 return true;
171}
172
173
180{
181 return isRegistrationDataSaved() && (bool) getDolGlobalString('MAIN_FIRST_REGISTRATION_OK_DATE');
182}
183
184
191function getHashUniqueIdOfRegistration($algo = 'sha256')
192{
193 global $conf;
194
195 return dol_hash('dolibarr'.$conf->file->instance_unique_id.($conf->entity > 1 ? $conf->entity : ''), $algo, 1);
196}
197
198
209function isALNEQualifiedVersion($ignoredev = 0, $ignoremodule = 0)
210{
211 global $mysoc;
212
213 // For Dev/Debug purpose: Constant set by developer to force all LNE restrictions even if country is not France so we can test them on any dev instance.
214 // Note that you can force, with this option, the enabling of the LNE restrictions, but there is no way to force the disabling of the LNE restriction.
215 if (defined('CERTIF_LNE') && (int) constant('CERTIF_LNE') === 2) {
216 return 'CERTIF_LNE_IS_2';
217 }
218
219 if (!$ignoredev && preg_match('/\-/', DOL_VERSION)) { // This is not a stable version (dev version), it can't be the certified versions.
220 return '';
221 }
222 if ($mysoc->country_code != 'FR') {
223 return '';
224 }
225 if (!defined('CERTIF_LNE') || (int) constant('CERTIF_LNE') === 0) {
226 return '';
227 }
228 if (!$ignoremodule && !isModEnabled('blockedlog')) {
229 return '';
230 }
231
232 // All conditions are ok to become a LNE certified version
233 return ($ignoredev ? '' : 'NOT_BETA+').'FR+CERTIF_LNE_IS_1'.($ignoremodule ? '' : '+MODENABLED');
234}
235
236
245function isALNERunningVersion($blockedlogtestalreadydone = 0, $blockedlogmodulealreadydone = 0)
246{
247 // For Debug help: Constant CERTIF_LNE can be set 2 by developers get mode 1 compliant with dev env.
248 // Note that you can force, with this constant, the enabling of the restrictions,
249 // but there is no way to force the disabling of a restriction.
250 if (defined('CERTIF_LNE') && (int) constant('CERTIF_LNE') === 2 // Value is 2 for debug purpose to enable restriction except https for dev env.
251 && ($blockedlogmodulealreadydone || isModEnabled('blockedlog'))
252 && ($blockedlogtestalreadydone || isBlockedLogUsed())) {
253 return true;
254 }
255 if (defined('CERTIF_LNE') && (int) constant('CERTIF_LNE') === 1 // Value is 1 when version is certified
256 && ($blockedlogmodulealreadydone || isModEnabled('blockedlog'))
257 && ($blockedlogtestalreadydone || isBlockedLogUsed())) {
258 return true;
259 }
260
261 return false;
262}
263
270function isBlockedLogUsed($ignoresystem = 0)
271{
272 global $conf, $db;
273
274 $result = true; // by default restrictions are on, so we can't disable them
275
276 // Note: if module on, we suppose it is used, if not, we check in case of it was disabled.
277 if (!isModEnabled('blockedlog')) {
278 // Test the cache key
279 if (array_key_exists('isblockedlogused', $conf->cache)) {
280 return $conf->cache['isblockedlogused'.$ignoresystem];
281 }
282
283 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog";
284 $sql .= " WHERE entity = ".((int) $conf->entity); // Sharing entity in blocked log will never be allowed
285 if ($ignoresystem) {
286 $sql .= " AND action NOT IN ('MODULE_SET', 'MODULE_RESET')";
287 }
288 $sql .= $db->plimit(1);
289
290 $resql = $db->query($sql);
291 if ($resql !== false) {
292 $obj = $db->fetch_object($resql);
293 if (!$obj) {
294 $result = false;
295 }
296 } else {
298 }
299
300 $conf->cache['isblockedlogused'.$ignoresystem] = $result;
301 }
302
303 dol_syslog("isBlockedLogUsed: ignoresystem=".$ignoresystem." returns ".(string) $result);
304
305 return $result;
306}
307
308
320function pdfCertifMentionblockedLog(&$pdf, $outputlangs, $seller, $default_font_size, &$posy, $pdftemplate)
321{
322 $result = 0;
323
324 if (in_array($seller->country_code, array('FR'))) {
325 $outputlangs->load("blockedlog");
326 $blockedlog_mention = '';
327
328 $isalne = isALNEQualifiedVersion(); // If necessary, we could replace with "if isALNERunningVersion()"
329 if ($isalne == 'CERTIF_LNE_IS_2') {
330 $blockedlog_mention = $outputlangs->transnoentitiesnoconv("InvoiceGeneratedWithLNECandidatePOSSystem");
331 } elseif ($isalne) {
332 $blockedlog_mention = $outputlangs->transnoentitiesnoconv("InvoiceGeneratedWithLNECertifiedPOSSystem");
333 }
334
335 if ($blockedlog_mention) {
336 $pdf->SetFont('', '', $default_font_size - 2);
337 $pdf->SetXY($pdftemplate->marge_gauche, $posy);
338 $pdf->MultiCell(100, 3, $blockedlog_mention, 0, 'L', false);
339 $posy = $pdf->GetY();
340 $result = 1;
341 }
342 }
343
344 return $result;
345}
346
360function sumAmountsForUnalterableEvent($block, &$refinvoicefound, &$totalhtamount, &$totalvatamount, &$totalamount, &$total_ht, &$total_vat, &$total_ttc)
361{
362 if ($block->action == 'BILL_VALIDATE') {
363 $total_ht = $block->object_data->total_ht;
364 $total_vat = $block->object_data->total_tva;
365 $total_ttc = $block->object_data->total_ttc;
366
367 // Init to avoid warnings if not initialized yet
368 if (!isset($totalamount[$block->action][$block->module_source])) {
369 $totalhtamount[$block->action][$block->module_source] = 0;
370 $totalvatamount[$block->action][$block->module_source] = 0;
371 $totalamount[$block->action][$block->module_source] = 0;
372 }
373
374 // We add total for the invoice if "invoice validate event" not yet met.
375 // If we already met the event for this object, we keep only first one but this should not happen because edition of validated invoice is not allowed on secured versions.
376 if (empty($refinvoicefound[$block->ref_object])) {
377 $totalhtamount[$block->action][$block->module_source] += $total_ht;
378 $totalvatamount[$block->action][$block->module_source] += $total_vat;
379 $totalamount[$block->action][$block->module_source] += $total_ttc;
380 }
381 $refinvoicefound[$block->ref_object] = 1;
382 } elseif ($block->action == 'PAYMENT_CUSTOMER_CREATE' || $block->action == 'PAYMENT_CUSTOMER_DELETE') {
383 $total_ht = $block->object_data->amount;
384 $total_vat = 0;
385 $total_ttc = $block->object_data->amount;
386
387 //$actionkey = $block->action;
388 $actionkey = 'PAYMENT_CUSTOMER';
389
390 // Init to avoid warnings if not initialized yet
391 if (!isset($totalamount[$actionkey][$block->module_source])) {
392 $totalhtamount[$actionkey][$block->module_source] = 0;
393 $totalvatamount[$actionkey][$block->module_source] = 0;
394 $totalamount[$actionkey][$block->module_source] = 0;
395 }
396
397 $totalhtamount[$actionkey][$block->module_source] += $total_ht;
398 $totalvatamount[$actionkey][$block->module_source] += $total_vat;
399 $totalamount[$actionkey][$block->module_source] += $total_ttc;
400 } else {
401 $total_ttc = $block->amounts;
402 }
403
404 return 1;
405}
406
407
417function callApiToGetObfuscationKey($idprof1, $registrationnumber, $force = false)
418{
419 global $mysoc, $conf;
420
421 $obfuscationkey = 'ERROR';
422
423 if (empty($idprof1)) {
424 dol_syslog("callApiToGetObfuscationKey was called with empty idprof1", LOG_DEBUG);
425 return 'ERROR callApiToGetObfuscationKey was called with empty idprof1';
426 }
427
428 //if ((isALNERunningVersion(1) || $force) && $mysoc->country_code == 'FR') {
429 $url_for_ping = getDolGlobalString('MAIN_URL_FOR_PING', "https://ping.dolibarr.org/");
430
431 $algo = 'sha256';
432 $hash_unique_id = getHashUniqueIdOfRegistration($algo); // The hash of the unique IDof instance
433
434 $t = microtime(true);
435 $micro = sprintf("%06d", (int) (($t - floor($t)) * 1000000));
436
437 $data = '';
438 $data .= 'hash_algo=dol_hash-'.urlencode($algo);
439 $data .= '&hash_unique_id='.urlencode($hash_unique_id);
440 $data .= '&action=dolibarrgetkeyobfuscation';
441 $data .= '&datesys='.urlencode(dol_print_date(dol_now('gmt'), 'standard', 'gmt').'.'.$micro);
442 $data .= '&version='.(float) DOL_VERSION;
443 $data .= '&version_full='.urlencode(DOL_VERSION);
444 $data .= '&versionblockedlog='.(float) getBlockedLogVersionToShow();
445 $data .= '&versionblockedlog_full='.urlencode(getBlockedLogVersionToShow());
446
447 $data .= '&entity='.(int) $conf->entity;
448
449 $data .= '&company_idprof1='.urlencode(dol_sanitizeKeyCode($idprof1));
450 $data .= '&registrationnumber='.urlencode(dol_sanitizeKeyCode($registrationnumber));
451
452 $addheaders = array();
453 $timeoutconnect = 3;
454 $timeoutresponse = 3;
455
456 dol_syslog("callApiToGetObfuscationKey call remote URL idprod1=".dol_sanitizeKeyCode($idprof1), LOG_DEBUG);
457 dol_syslog("callApiToGetObfuscationKey call remote URL idprod1=".dol_sanitizeKeyCode($idprof1), LOG_DEBUG, 0, '_dolibarrgetkeyobfuscation');
458
459 include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
460 try {
461 $tmpresult = getURLContent($url_for_ping, 'POST', $data, 1, $addheaders, array('https'), 0, -1, $timeoutconnect, $timeoutresponse, array());
462 usleep(10000);
463
464 // Add a warning in log in case of error
465 if ($tmpresult['http_code'] == 0 && !empty($tmpresult['curl_error_msg'])) {
466 $logerrormessage = 'Error: '.$tmpresult['curl_error_msg'];
467 $obfuscationkey .= ' '.$tmpresult['curl_error_msg'];
468 dol_syslog("callApiToGetObfuscationKey result error when getting obfuscation key: ".$logerrormessage, LOG_WARNING);
469 dol_syslog("callApiToGetObfuscationKey result error when getting obfuscation key: ".$logerrormessage, LOG_WARNING, 0, '_dolibarrgetkeyobfuscation');
470 } elseif ($tmpresult['http_code'] != 200) {
471 $logerrormessage = 'Error: '.$tmpresult['http_code'].' '.$tmpresult['content'];
472 $obfuscationkey .= ' '.$tmpresult['http_code'].' '.$tmpresult['content'];
473 dol_syslog("callApiToGetObfuscationKey result error when getting obfuscation key: ".$logerrormessage, LOG_WARNING);
474 dol_syslog("callApiToGetObfuscationKey result error when getting obfuscation key: ".$logerrormessage, LOG_WARNING, 0, '_dolibarrgetkeyobfuscation');
475 } else {
476 $reg = array();
477 if (preg_match('/(DOLOBFUSCKEY.*)/', $tmpresult['content'], $reg)) { // gitleaks:allow $tmpresult['content'] may contains text comments before the line 'DOLOBFUSCKEY1...,DOLOBFUSCKEY2...'
478 $obfuscationkey = $reg[1];
479 dol_syslog("callApiToGetObfuscationKey we got the remote obfuscation key", LOG_DEBUG);
480 dol_syslog("callApiToGetObfuscationKey we got the remote obfuscation key", LOG_DEBUG, 0, '_dolibarrgetkeyobfuscation');
481 } else {
482 $obfuscationkey .= ' '.$tmpresult['content'];
483 dol_syslog("callApiToGetObfuscationKey result error when getting obfuscation key: ".$tmpresult['content'], LOG_WARNING);
484 dol_syslog("callApiToGetObfuscationKey result error when getting obfuscation key: ".$tmpresult['content'], LOG_WARNING, 0, '_dolibarrgetkeyobfuscation');
485 }
486 }
487 } catch (Exception $e) {
488 $obfuscationkey .= ' '.$e->getMessage();
489 dol_syslog("callApiToGetObfuscationKey result error ".$e->getMessage(), LOG_ERR);
490 dol_syslog("callApiToGetObfuscationKey result error ".$e->getMessage(), LOG_ERR, 0, '_dolibarrgetkeyobfuscation');
491 }
492
493 return $obfuscationkey;
494}
495
496
509/*
510function callApiToPushCounter($id, $signature, $datecreation, $test, $previousid, $previoussignature, $previousdatecreation)
511{
512 global $mysoc, $conf;
513
514 if (isALNERunningVersion(1) && $mysoc->country_code == 'FR') {
515 // Push last rowid + signature to remote dolibarr server
516 // TODO Do it only for selected events: BILL_VALIDATE ?
517
518 // Code here is similar to the one into printCodeForPing(), except that message code/properties/fields may differ.
519 $url_for_ping = getDolGlobalString('MAIN_URL_FOR_PING', "https://ping.dolibarr.org/");
520
521 $algo = 'sha256';
522 $hash_unique_id = getHashUniqueIdOfRegistration($algo); // The hash of the unique IDof instance
523
524 $t = microtime(true);
525 $micro = sprintf("%06d", (int) (($t - floor($t)) * 1000000));
526
527 $data = '';
528 $data .= 'hash_algo=dol_hash-'.urlencode($algo);
529 $data .= '&hash_unique_id='.urlencode($hash_unique_id);
530 $data .= '&action=dolibarrpushcounter';
531 $data .= '&datesys='.urlencode(dol_print_date(dol_now('gmt'), 'standard', 'gmt').'.'.$micro);
532 $data .= '&version='.(float) DOL_VERSION;
533 $data .= '&version_full='.urlencode(DOL_VERSION);
534 $data .= '&versionblockedlog='.(float) getBlockedLogVersionToShow();
535 $data .= '&versionblockedlog_full='.urlencode(getBlockedLogVersionToShow());
536
537 $data .= '&entity='.(int) $conf->entity;
538
539 $data .= '&lastrowid='.(int) $id;
540 $data .= '&lastsignature='.urlencode($signature);
541 $data .= '&lastdatecreation='.urlencode(dol_print_date($datecreation, 'standard', 'gmt'));
542 $data .= '&previousrowid='.(int) $previousid;
543 $data .= '&previoussignature='.urlencode($previoussignature);
544 $data .= '&previousdatecreation='.urlencode(dol_print_date($previousdatecreation, 'standard', 'gmt'));
545 if ($test) {
546 $data .= '&test=1';
547 }
548
549 $addheaders = array();
550 $timeoutconnect = 1;
551 $timeoutresponse = 1;
552
553 $conf->global->BLOCKEDLOG_RANDOMRANGE_FOR_TRACKING = 1; // Force probability to 1
554
555 // Probability will be between 1/10 by default and 1/1 if const BLOCKEDLOG_RANDOMRANGE_FOR_TRACKING is set to 1. Can't be lower than 1/10.
556 $BLOCKEDLOG_RANDOMRANGE_FOR_TRACKING = min(10, getDolGlobalInt('BLOCKEDLOG_RANDOMRANGE_FOR_TRACKING', 10));
557 $random = 1;
558 //$BLOCKEDLOG_RANDOMRANGE_FOR_TRACKING = 1; // To force track at every call
559 if ($BLOCKEDLOG_RANDOMRANGE_FOR_TRACKING > 1) {
560 $random = random_int(1, (int) $BLOCKEDLOG_RANDOMRANGE_FOR_TRACKING);
561 }
562
563 if ($random == 1) { // 1 chance on BLOCKEDLOG_RANDOMRANGE_FOR_TRACKING
564 dol_syslog("callApiToPushCounter create Record is selected to be remotely pushed for tracking", LOG_DEBUG);
565
566 include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
567 try {
568 $tmpresult = getURLContent($url_for_ping, 'POST', $data, 1, $addheaders, array('https'), 0, -1, $timeoutconnect, $timeoutresponse, array(), '_dolibarrpushcounter');
569 usleep(1000);
570
571 // Add a warning in log in case of error
572 if ($tmpresult['http_code'] != 200) {
573 $logerrormessage = 'Error: '.$tmpresult['http_code'].' '.$tmpresult['content'];
574 dol_syslog("callApiToPushCounter create Error when pushing track info: ".$logerrormessage, LOG_WARNING);
575 }
576 } catch (Exception $e) {
577 dol_syslog("callApiToPushCounter create Error ".$e->getMessage(), LOG_ERR);
578 }
579 } else {
580 dol_syslog("callApiToPushCounter create Record is NOT selected to be remotely pushed for tracking", LOG_DEBUG);
581 }
582
583 return 1;
584 }
585
586 return 0;
587}
588*/
589
590
599{
600 global $user;
601
602 return (((getDolGlobalString('BLOCKEDLOG_FOR_TAX_AUDITOR') && $user->socid) || getDolGlobalString('BLOCKEDLOG_FOR_TAX_AUDITOR') == '2') ? 1 : 0);
603}
604
605
606
619function pdfWriteBlockedLogSignature(&$pdf, $outputlangs, $page_height, $object, &$w, &$posx, &$posy)
620{
621 global $db;
622
623 // Transaction ID
624 if (isALNERunningVersion() && isModEnabled('blockedlog')) {
625 if ($object->status > $object::STATUS_DRAFT) {
626 $unalterablelogid = 'UNDEFINED'; // By default
627
628 $sql = "SELECT signature FROM ".MAIN_DB_PREFIX."blockedlog";
629 $sql .= " WHERE action = 'BILL_VALIDATE' AND element = 'facture' AND ref_object = '".$db->escape($object->ref)."'";
630 $sql .= $db->order('rowid', 'DESC');
631 $sql .= $db->plimit(1);
632
633 $resql = $db->query($sql);
634 if ($resql) {
635 $obj = $db->fetch_object($resql);
636 if ($obj) {
637 $unalterablelogid = $obj->signature;
638 }
639 }
640
641 if ($unalterablelogid != 'UNDEFINED') {
642 $pdf->SetXY($posx, $posy);
643 $pdf->SetTextColor(0, 0, 60);
644 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("SignatureID")." : ".dol_trunc(strtoupper($unalterablelogid), 10), '', 'R');
645 $posy += 3;
646 }
647
648 $isADuplicata = ($object->pos_print_counter >= 2);
649 if ($isADuplicata) {
650 $pdf->SetXY($posx, $posy);
651 $pdf->SetTextColor(0, 0, 60);
652 $pdf->MultiCell($w, 3, '*** '.$outputlangs->trans("DUPLICATA").(getDolGlobalString('TAKEPOS_SHOW_PRINT_COUNTER_ON_RECEIPT') ? ' (no '.($object->pos_print_counter - 1).')' : '').' ***', '', 'R');
653 $posy += 3;
654 }
655 }
656
657 if ($object->status == $object::STATUS_DRAFT) {
658 $pdf->SetXY($posx, $posy);
659 $pdf->SetTextColor(0, 0, 60);
660 $pdf->MultiCell($w, 3, '*** '.strtoupper($outputlangs->trans("TemporaryReceipt")).' ***', '', 'R');
661 $posy += 3;
662 }
663 }
664}
665
666
667
674{
675 global $conf, $db, $langs, $mysoc;
676
677 include_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
678
679 $blocklog_static = new BlockedLog($db);
680
681 // Loop on all entities found in llx_blockedlog
682 $listofentities = array();
683 $sql = "SELECT DISTINCT entity FROM ".MAIN_DB_PREFIX."blockedlog";
684 $resql = $db->query($sql);
685 if ($resql) {
686 while ($obj = $db->fetch_object($resql)) {
687 $listofentities[] = $obj->entity;
688 }
689 } else {
690 print '<tr class="trforrunsql"><td colspan="4">';
691 print '<b>'.$langs->trans('InitEndFlagFile')."</b>:\n";
692 print 'Error: Failed to get list of entities in blockedlog table';
693 print '</td></tr>';
694 return -1;
695 }
696
697 foreach ($listofentities as $entity) {
698 print '<tr class="trforrunsql"><td colspan="4">';
699 print '<b>'.$langs->trans('InitEndFlagFile')." (entity = ".$entity.")</b>:\n";
700
701 // Load the data of company (country, ...). Erase current one so this function can be used by migration script only.
702 $conf->setEntityValues($db, $entity);
703 $mysoc = new Societe($db);
704 $mysoc->setMysoc($conf);
705
706 $maxid = 0;
707 $sql = "SELECT MAX(rowid) as maxid FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity = ".((int) $entity);
708 $resql = $db->query($sql);
709 if ($resql) {
710 $obj = $db->fetch_object($resql);
711 if ($obj) {
712 $maxid = $obj->maxid;
713 }
714 } else {
715 print 'Error: Failed to get max id of blockedlog table';
716 print '</td></tr>';
717 return -1;
718 }
719
720 $blocklog_static->fetch($maxid);
721
722 $lockfile = $blocklog_static->getEndOfChainFlagFile();
723
724 // Lock acquired, we can now write the new .end file
725 $stringtowrite = 'BLOCKEDLOGHEAD '.$blocklog_static->id." ".dol_print_date($blocklog_static->date_creation, 'dayhourrfc', 'gmt')." ".(string) $blocklog_static->signature;
726
727 if (isALNERunningVersion(1) && $mysoc->country_code == 'FR') {
728 $remoteobfuscationkey = $blocklog_static->getObfuscationKey();
729 if (empty($remoteobfuscationkey)) {
730 print "Error: Failed to get the remote obfuscation key. We can't record the end of chain flag file so we abort the transaction.";
731 print '</td></tr>';
732 return -1;
733 }
734
735 $stringtowriteencoded = dolEncrypt($stringtowrite, $remoteobfuscationkey, '', '', 'dolobfuscationv1-'.$mysoc->idprof1.'-'.$blocklog_static->id);
736 } else {
737 $stringtowriteencoded = dolEncrypt($stringtowrite, '', '', '', 'dolcrypt-'.$mysoc->idprof1.'-'.$blocklog_static->id);
738 }
739
740 // Update or create the .end flag file.
741 if (defined('BLOCKEDLOG_END_FLAG_IN_A_FILE')) {
742 $lockhandle = fopen($lockfile, 'w+');
743 if ($lockhandle) {
744 if (fwrite($lockhandle, $stringtowriteencoded."\n") === false) {
745 print "Cannot write to the blockedlog .end file ".$lockfile;
746 print '</td></tr>';
747 return -1;
748 }
749
750 fclose($lockhandle); // Remove the lock
751 dolChmod($lockfile);
752 } else {
753 print "Cannot open for writing the blockedlog .end file ".$lockfile;
754 print '</td></tr>';
755 return -1;
756 }
757 } else {
758 $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
759 $sql .= " WHERE name = '".$db->escape(basename($lockfile))."' AND entity = ".((int) $conf->entity);
760 $resql = $db->query($sql);
761
762 $sql = "INSERT INTO ".MAIN_DB_PREFIX."const(name, value, type, visible, note, entity)";
763 $sql .= " VALUES('".$db->escape(basename($lockfile))."', '".$db->escape($stringtowriteencoded)."', 'chaine', 0, 'Blockedlog end of chain flag', ".((int) $conf->entity).")";
764 $resql = $db->query($sql);
765 if (!$resql) {
766 print "Cannot open for writing the blockedlog .end file ".basename($lockfile);
767 print '</td></tr>';
768 return -1;
769 }
770 }
771
772 print $langs->trans("Done");
773 print '</td></tr>';
774 }
775
776 return 1;
777}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
migrate_blockedlog_add_end_file()
Migrate an old database to add the .end flag.
sumAmountsForUnalterableEvent($block, &$refinvoicefound, &$totalhtamount, &$totalvatamount, &$totalamount, &$total_ht, &$total_vat, &$total_ttc)
sumAmountsForUnalterableEvent
getBlockedLogVersionToShow()
Define head array for tabs of blockedlog tools setup pages.
pdfWriteBlockedLogSignature(&$pdf, $outputlangs, $page_height, $object, &$w, &$posx, &$posy)
Add some information from the blockedlog module.
isALNEQualifiedVersion($ignoredev=0, $ignoremodule=0)
Return if the version is a candidate version to get the LNE certification and if the prerequisites ar...
isRegistrationDataSaved()
Return if the KYC mandatory parameters are set Must be the same fields than the one defined as mandat...
userIsTaxAuditor()
Call remote API service to push the last counter and signature.
pdfCertifMentionblockedLog(&$pdf, $outputlangs, $seller, $default_font_size, &$posy, $pdftemplate)
Add legal mention.
isBlockedLogUsed($ignoresystem=0)
Return if the blocked log was already used to block some events.
blockedlogadmin_prepare_head($withtabsetup)
Define head array for tabs of blockedlog tools setup pages.
isRegistrationDataSavedAndPushed()
Return if the KYC mandatory parameters are set AND pushed/registered centralized server.
getHashUniqueIdOfRegistration($algo='sha256')
Return a hash unique identifier of the registration (used to identify the registration of instance wi...
isALNERunningVersion($blockedlogtestalreadydone=0, $blockedlogmodulealreadydone=0)
Return if the application is executed with the LNE requirements on.
callApiToGetObfuscationKey($idprof1, $registrationnumber, $force=false)
Call remote API service to get the obfuscation key.
Class to manage Blocked Log.
Class to manage third parties objects (customers, suppliers, prospects...)
global $mysoc
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:65
dol_now($mode='gmt')
Return date for now.
dolChmod($filepath, $newmask='')
Change mod of a file.
getMultidirOutput($object, $module='', $forobject=0, $mode='output')
Return the full path of the directory where a module (or an object of a module) stores its files.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '...' if string larger than length.
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_sanitizeKeyCode($str)
Clean a string to use it as a key or code.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1, $timeoutconnect=0, $timeoutresponse=0, $otherCurlOptions=array(), $morelogsuffix='')
Function to get a content from an URL (use proxy if proxy defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
dol_hash($chain, $type='0', $nosalt=0, $mode=0)
Returns a hash (non reversible encryption) of a string.
dolEncrypt($chain, $key='', $ciphering='', $forceseed='', $obfuscationmode='dolcrypt')
Encode a string with a symmetric encryption.