28require_once
'../main.inc.php';
36require_once DOL_DOCUMENT_ROOT.
'/core/class/html.form.class.php';
37require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
38require_once DOL_DOCUMENT_ROOT.
'/ai/class/ai.class.php';
39require_once DOL_DOCUMENT_ROOT.
'/societe/class/societe.class.php';
40require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
41require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.facture.class.php';
43$langs->loadLangs(array(
"main",
"exports",
"other"));
45$action =
GETPOST(
'action',
'aZ09');
46$modulepart =
GETPOST(
'modulepart',
'aZ09');
52$upload_dir =
$conf->user->dir_temp.
'/import';
57$originalfilename = $file;
58$uid = $thiid = $pid = $erid = $salid = 0;
60if (preg_match(
'/-uid([\d+])/', $file, $reg)) {
62 $originalfilename = preg_replace(
'/-uid\d+/',
'', $originalfilename);
64if (preg_match(
'/-thiid([\d+])/', $file, $reg)) {
66 $originalfilename = preg_replace(
'/-thiid\d+/',
'', $originalfilename);
68if (preg_match(
'/-pid([\d+])/', $file, $reg)) {
70 $originalfilename = preg_replace(
'/-pid\d+/',
'', $originalfilename);
72if (preg_match(
'/-erid([\d+])/', $file, $reg)) {
74 $originalfilename = preg_replace(
'/-erid\d+/',
'', $originalfilename);
76if (preg_match(
'/-salid([\d+])/', $file, $reg)) {
78 $originalfilename = preg_replace(
'/-salid\d+/',
'', $originalfilename);
80$originalfilename = preg_replace(
'/^upload_page-[a-z_]+-/',
'', $originalfilename);
96 header(
"Location: ".$urlforuploadpage);
100if ($action ==
'uploadfile') {
102 print
'Error, modulepart param is empty';
109 $module = $arrayobject[
'module'];
110 $element = $arrayobject[
'element'];
111 $dir_output = $arrayobject[
'dir_output'];
112 $dir_temp = $arrayobject[
'dir_temp'];
114 $permlevel1 =
'read';
116 $fileprefix =
'unknown';
117 if (in_array($modulepart, array(
'fournisseur',
'invoice_supplier'))) {
118 $permlevel1 =
'facture';
119 $permlevel2 =
'read';
121 } elseif ($modulepart ==
'expensereport') {
122 $fileprefix =
'upload_page-'.$modulepart.
'-uid'.$user->id.
'-erid'.(
GETPOSTINT(
'userexpensereportid') > 0 ?
GETPOSTINT(
'userexpensereportid') : 0).
'-pid'.(
GETPOSTINT(
'search_prodid') > 0 ?
GETPOSTINT(
'search_prodid') : 0);
123 } elseif ($modulepart ==
'salaries') {
124 $fileprefix =
'upload_page-'.$modulepart.
'-uid'.$user->id.
'-salid'.(
GETPOSTINT(
'usersalaryid') > 0 ?
GETPOSTINT(
'usersalaryid') : 0);
128 $permissiontoadd = $user->hasRight(
$module, $permlevel1, $permlevel2);
130 $permissiontoadd = $user->hasRight(
$module, $permlevel1);
132 $forceFullTextIndexation =
'0';
135 if (!empty($_FILES[
'userfile'][
'name'])) {
136 $fullnewname = $fileprefix.
'-'.$_FILES[
'userfile'][
'name'];
137 $_FILES[
'userfile'][
'name'] = $fullnewname;
142 include DOL_DOCUMENT_ROOT.
'/core/actions_linkedfiles.inc.php';
149 $ajaxFileUrl = DOL_URL_ROOT.
'/core/ajax/ajaxuploadpage.php?file='.urlencode($fullnewname);
162$form =
new Form($db);
178$title = $langs->trans(
"UploadFile");
182$arrayofcss = array();
184llxHeader(
'', $title, $help_url,
'', 0, 0, $arrayofjs, $arrayofcss,
'',
'mod-upload page-card');
186print
load_fiche_titre(
'',
'',
'', 0,
'',
'',
'<h2>'.img_picto(
'',
'upload').
' '.$title.
'</h2>');
190$hookmanager->initHooks(array(
'uploadform'));
198 $uploadform =
'<div class="display-flex">';
201 $prodtext = $langs->trans(
"RefOrLabel");
203 $langs->load(
"bills");
205 <div id="supplierinvoice" class="flex-item flex-item-uploadfile">'.img_picto(
'',
'bill',
'class="fa-2x"').
'<br>
206 <div>'.$langs->trans(
"SupplierInvoice").
'<br><br>';
212 $uploadform .= img_picto(
'',
'company',
'class="pictofixedwidth"');
213 $uploadform .= $form->select_company($socid,
'socid',
'(statut:=:0)', $langs->transnoentitiesnoconv(
"Supplier"), 0, 0, array(), 0,
'maxwidth200 disableautoopen');
215 $uploadform .=
'<br>';
218 $uploadform .= img_picto(
'',
'product',
'class="pictofixedwidth"');
219 $uploadform .= $form->select_produits_fournisseurs(0, $prodid,
'prodid',
'',
'', array(), 1, 1,
'maxwidth200 disableautoopen', $prodtext, 1);
221 $uploadform .=
'<br>';
224 <small class="opacitymedium">'.$langs->trans(
"OrClickToSelectAFile").
'...</small>
231 $langs->load(
"expensereport");
233 <div id="userexpensereport" class="flex-item flex-item-uploadfile">'.img_picto(
'',
'expensereport',
'class="fa-2x"').
'<br>
234 <div>'.$langs->trans(
"ExpenseReport").
'<br><br>';
236 $uploadform .= img_picto(
'',
'user',
'class="pictofixedwidth"');
238 $uploadform .= $form->select_dolusers(
GETPOSTINT(
'userexpensereportid') > 0 ?
GETPOSTINT(
'userexpensereportid') : $user->id,
'userexpensereportid', $langs->transnoentitiesnoconv(
"User"), null, 0,
'hierarchyme',
'',
'', 0, 0,
'', 0,
'',
'maxwidth200 disableautoopen', 1);
241 $uploadform .=
'<br>';
243 $uploadform .= img_picto(
'',
'invoice',
'class="pictofixedwidth"');
244 $uploadform .= $form->select_type_fees(
GETPOSTINT(
'feetypeid') > 0 ?
GETPOSTINT(
'feetypeid') : -1,
'feetypeid', $langs->transnoentitiesnoconv(
"TypeFees"),
'maxwidth200 disableautoopen', 1, 1);
246 $uploadform .=
'<br>';
249 <small class="opacitymedium">'.$langs->trans(
"OrClickToSelectAFile").
'...</small>
257 $langs->load(
"salaries");
259 <div id="userpayroll" class="flex-item flex-item-uploadfile">'.img_picto(
'',
'salary',
'class="fa-2x"').
'<br>
260 <div>'.$langs->trans(
"UserPaySlip").
'<br><br>';
262 $uploadform .= img_picto(
'',
'user',
'class="pictofixedwidth"');
263 $uploadform .= $form->select_dolusers(
GETPOSTINT(
'usersalaryid') > 0 ?
GETPOSTINT(
'usersalaryid') : $user->id,
'usersalaryid', $langs->transnoentitiesnoconv(
"Employee"), null, 0,
'hierarchyme',
'',
'', 0, 0,
'', 0,
'',
'maxwidth200 disableautoopen', 1);
265 $uploadform .=
'<br>';
268 <small class="opacitymedium">'.$langs->trans(
"OrClickToSelectAFile").
'...</small>
275 $langs->load(
"taxes");
277 <div id="userpayroll" class="flex-item flex-item-uploadfile">'.img_picto(
'',
'invoice',
'class="fa-2x"').
'<br>
278 <div>'.$langs->trans(
"SocialContribution").
'<br><br>';
280 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formsocialcontrib.class.php';
283 $uploadform .= img_picto(
'',
'invoice',
'class="pictofixedwidth"');
284 $uploadform .= $formsocialcontrib->select_type_socialcontrib(
GETPOST(
'socialcontrib',
'alpha') ?
GETPOSTINT(
'socialcontrib') : -1,
'socialcontrib', $langs->transnoentities(
"TypeContrib"), 0, 0,
'minwidth150 maxwidth200 disableautoopen', 0, 1);
286 $uploadform .=
'<br>';
288 $uploadform .= img_picto(
'',
'user',
'class="pictofixedwidth"');
289 $uploadform .= $form->select_dolusers(
GETPOSTINT(
'usertaxid') > 0 ?
GETPOSTINT(
'usertaxid') : -1,
'usertaxid', $langs->transnoentitiesnoconv(
"Employee"), null, 0,
'hierarchyme',
'',
'', 0, 0,
'', 0,
'',
'maxwidth200 disableautoopen', 1);
292 <small class="opacitymedium">'.$langs->trans(
"OrClickToSelectAFile").
'...</small>
297 $uploadform .=
'</div>';
303$parameters = array(
'uploadform' => $uploadform);
304$reshook = $hookmanager->executeHooks(
'printUploadForm', $parameters);
305if (empty($reshook)) {
306 $uploadform .= $hookmanager->resPrint;
308 $uploadform = $hookmanager->resPrint;
311$uploadform .=
'<br>';
314if ($action ==
'uploadfile' || $action ==
'showsummary') {
315 print
'<b>'.$langs->trans(
"ImportingFile", $originalfilename).
'</b><br>';
318 print
'<div class="'.($action ==
'showsummary' ?
'green' :
'neutral').
'" style="padding-left: 20px; padding-right: 20px;">';
320 print
'<div class="marginbottom">';
321 if ($action ==
'showsummary') {
322 print $langs->trans(
"AIProcessingDone", $ai->getApiService());
324 print $langs->trans(
"AIProcessingPleaseWait", $ai->getApiService()).
'...';
329 print
'<div class="progress" title="80%">
330 <div class="progress-bar" role="progressbar" style="width: '.($action ==
'showsummary' ?
'100' :
'0').
'%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
336 if (!empty($ajaxFileUrl)) {
338 $(document).ready(function() {
339 console.log(\'Call ajaxFileUrl: '.dol_escape_js($ajaxFileUrl).
'\');
341 url: \
''.dol_escape_js($ajaxFileUrl).
'\',
344 beforeSend:
function() {
345 $(
".progress-bar").css(
"width",
"25%");
347 success:
function(data, textStatus, jqXHR) {
348 if (jqXHR.status === 200) {
350 console.log(
"Fill the #ajax-result with json result");
352 $(
"#ajax-result").val(JSON.stringify(data,
null, 2));
353 $(
".progress-bar").css(
"width",
"100%");
359 $(
"#ajax-result-message").html(
"<div class=\"ok\">Your file has been analyzed by the AI service.</div>");
360 $(
"#form-result-submit").show();
362 console.log(
"We received an error");
365 $(
"#ajax-result-message").html(
"<div class=\"error\">Error: HTTP status " + jqXHR.status +
"</div>");
368 error:
function(jqXHR, textStatus, errorThrown) {
370 console.log(
"We received an error");
371 $(
"#ajax-result-message").html(
"<div class=\"error\">Error: " + (jqXHR.responseText || errorThrown ||
"Unknown error") +
"</div>");
372 $(
".progress-bar").css(
"width",
"100%");
379 // Example of JSON result when importing a supplier PDF invoice
383 "invoice_number": "MSTRL-API-1234-001",
384 "invoice_reference": "Pro - Annual",
385 "issue_date": "2026-08-21",
386 "due_date": "2026-08-21",
389 "description": "0 jours"
391 "organization": "MyBigCompany"
394 "name": "Mistral AI SAS",
396 "street": "15, rue des Halles",
397 "postal_code": "75001",
401 "vat_number": "FR95952418325",
403 "siren": "952 418 325",
404 "capital": "19,189.04 €",
407 "email": "no-reply@mistral.ai",
408 "contact_url": "https://help.mistral.ai/en"
411 "name": "MyBigCompany",
413 "street": "1 rue de la paix",
414 "postal_code": "75000",
418 "vat_number": "FR012345678901",
419 "email": "contact@mybigcompany.com"
423 "description": "Fee for use- August",
424 "service": "Pro - Annual",
428 "total_excluding_tax": 143.9,
429 "total_including_tax": 172.68,
430 "period_start": "2026-08-21",
431 "period_end": "2027-08-20"
435 "subtotal_excluding_tax": 143.9,
439 "description": "EU FR Standard (20.0% sur 143,90 €)"
441 "total_including_tax": 172.68
444 "due_date": "2026-08-21",
445 "amount_due": 172.68,
452 "content": "Mistral AI - SAS au capital de 19,189.04€ - 952 418 325 R.C.S. Paris"
456 "content": "For any inquiry, please refer to https://help.mistral.ai/en"
463 print '<form
class=
"" id=
"form-result" method=
"POST">
';
464 print '<input
type=
"hidden" name=
"token" value=
"'.newToken().'">
';
465 print '<input
type=
"hidden" name=
"action" value=
"showsummary">
';
466 print '<input
type=
"hidden" name=
"modulepart" value=
"'.$modulepart.'">
';
467 print '<input
type=
"hidden" name=
"socid" value=
"'.$socid.'">
';
468 print '<input
type=
"hidden" name=
"prodid" value=
"'.$prodid.'">
';
469 print '<input
type=
"hidden" name=
"originalfilename" value=
"'.$fullnewname.'">
';
470 print '<input
type=
"hidden" name=
"jsonstring" id=
"ajax-result" value=
"jsonstringtoreplace">
'; // Fill by the ajax answer
471 print '<div
id=
"ajax-result-message"></div>
';
472 if ($action == 'uploadfile
') {
474 print '<input
type=
"submit" name=
"form-result-submit" id=
"form-result-submit" class=
"button" value=
"'.$langs->trans("Next
").'">
'; // TODO Hide.
476 print '</form>
'."\n";
480if ($action == 'showsummary
') {
481 print '<form
class=
"" id=
"summary-result" method=
"POST">
';
482 print '<input
type=
"hidden" name=
"token" value=
"'.newToken().'">
';
483 print '<input
type=
"hidden" name=
"action" value=
"addobject">
';
484 print '<input
type=
"hidden" name=
"modulepart" value=
"'.$modulepart.'">
';
485 print '<input
type=
"hidden" name=
"originalfilename" value=
"'.$fullnewname.'">
';
486 print '<input
type=
"hidden" name=
"jsonstring" id=
"ajax-result" value=
"'.GETPOST('jsonstring', 'restricthtml').'">
';
487 print '<div
id=
"ajax-result-message"></div>
';
490 print load_fiche_titre('Summary
', '', 'upload
');
492 print '<div
class=
"neutral">
';
494 print '<input
type=
"hidden" name=
"token" value=
"'.newToken().'">
';
498 $json = json_decode(GETPOST('jsonstring
', 'restricthtml
'), true);
499 } catch (Exception $e) {
500 print 'Failed to decode the result of the AI service. Error:
'.$e->getMessage();
502 print 'Result:
'.GETPOST('jsonstring
', 'restricthtml
');
507 if ($modulepart == 'invoice_supplier
') {
508 // Parse JSON to get information for an invoice
509 $invoiceindoc = $ai->decodeJsonIntoArray($json, 'supplier_invoice
');
511 //var_dump($json, $invoiceindoc);
513 print '<div
id=
"supplierinvoice" class=
"">
';
515 //print '<div
class=
"inline-block">
'.img_picto('', 'bill
', '').' '.$langs->trans("SupplierInvoice").'</div>
';
518 $nameindoc = (string) $invoiceindoc['vendor_name
'];
519 $addressindoc = (string) $invoiceindoc['vendor_address
'];
520 $idprof1indoc = (string) $invoiceindoc['vendor_profid1
'];
521 $idprof2indoc = (string) $invoiceindoc['vendor_profid2
'];
522 $emailindoc = (string) $invoiceindoc['vendor_email
'];
523 $vatnumberindoc = (string) $invoiceindoc['vendor_vat_number
'];
526 $tmpthirdparty = new Societe($db);
527 print img_picto('', 'company
', 'class=
"pictofixedwidth"').$langs->trans("ThirdParty").'<br>
';
528 if (GETPOSTINT('socid
')) {
529 $tmpthirdparty->fetch(GETPOSTINT('socid
'));
530 // TODO We can show a warning if we find a diff with autodetected value $nameindoc
532 // Try to find thirdparty
533 $result = $tmpthirdparty->findNearest(0, $nameindoc, '', '', $idprof1indoc, $idprof2indoc, '', '', '', '', $emailindoc, $vatnumberindoc, 0, 0, '1
');
536 $tmpthirdparty->fetch($result);
540 print '<span
class=
"opacitymedium">
'.$langs->trans("KeyDataFoundInDocument").' :</span>
';
542 if (!empty($addressindoc)) {
543 $s .= ',
'.$addressindoc;
546 print '<span
class=
"warning">
'.$langs->trans("NoDataRelatedTo").'</span>
';
550 if (empty($tmpthirdparty->id)) {
552 print '<span
class=
"warning">
'.$langs->trans("NotFoundInDatabase").'</span><br>
';
554 print $langs->trans("ChooseTheThirdPartyTouse").' ';
555 print $form->select_company($socid, 'socid
', '(statut:=:0)
', $langs->trans("Name"), 0, 0, array(), 0, 'maxwidth200 disableautoopen
');
556 //print '
'.$langs->trans("or").' <input
type=
"checkbox" name=
"createthirdparty" id=
"createthirdparty" value=
"1" checked><label
for=
"createthirdparty">
'.$langs->trans("CreateIt").'</label>
';
558 print $langs->trans("WillUse").' ';
559 print $tmpthirdparty->getNomUrl(1);
560 print '<input
type=
"hidden" name=
"socid" value=
"'.$tmpthirdparty->id.'">
';
564 print '<br><br><hr><br>
';
567 // @phan-suppress-next-line PhanTypeMismatchDimFetch
568 $nameprodindoc = $invoiceindoc['items
'][0]['description'];
572 $prodid = GETPOSTINT('prodid
');
573 $prodtext = $langs->trans("RefOrLabel");
575 $tmpproduct = new Product($db);
576 print img_picto('', 'product
', 'class=
"pictofixedwidth"').$langs->trans("Product").'<br>
';
579 $tmpproduct->fetch($prodid);
580 // TODO We can show a warning if we find a diff with autodetected value $json['items
']['service
']
582 //$tmpproduct->ref = $json['ref'];
585 print '<span
class=
"opacitymedium">
'.$langs->trans("KeyDataFoundInDocument").' :</span>
';
588 print '<span
class=
"warning">
'.$langs->trans("NoDataRelatedTo").'</span>
';
592 if (empty($tmpproduct->id)) {
593 print $langs->trans("ChooseTheProductTouse").' ';
594 print $form->select_produits_fournisseurs(0, $prodid, 'prodid
', '', '', array(), 1, 1, 'maxwidth200 disableautoopen
', $prodtext, 1);
597 print $langs->trans("TotalTTC").' ';
598 print '<input
type=
"text" class=
"width100 right" name=
"amount_ttc" id=
"amount_ttc" value=
"'.(GETPOSTFLOAT('amount_ttc', '', 2) ? price(GETPOSTFLOAT('amount_ttc', '', 2)) : '').'">
';
600 // TODO On selection of product, refresh next section with the product price ref
602 print $langs->trans("WillUse").' ';
603 print $tmpproduct->getNomUrl(1);
604 print '<input
type=
"hidden" name=
"prodid" value=
"'.$tmpproduct->id.'">
';
608 print '<br><br><hr><br>
';
612 $tmpinvoice = new FactureFournisseur($db);
614 print img_picto('', 'supplier_invoice
', 'class=
"pictofixedwidth"').$langs->trans("SupplierInvoice").'<br>
';
616 print '<span
class=
"opacitymedium">
'.$langs->trans("KeyDataFoundInDocument").' :</span>
';
618 $invoiceindoc['supplierref
'] ? $tmpvalue[] = $invoiceindoc['supplierref
'] : '';
619 $invoiceindoc['due_date
'] ? $tmpvalue[] = dol_print_date($invoiceindoc['due_date
'], 'day
', 'tzuserrel
') : '';
620 $invoiceindoc['issue_date
'] ? $tmpvalue[] = dol_print_date($invoiceindoc['issue_date
'], 'day
', 'tzuserrel
') : '';
621 $invoiceindoc['currency_code
'] ? $tmpvalue[] = $invoiceindoc['currency_code
'] : '';
622 $invoiceindoc['invoice_label
'] ? $tmpvalue[] = $invoiceindoc['invoice_label
'] : '';
624 $s = implode(',
', $tmpvalue);
626 print '<span
class=
"warning">
'.$langs->trans("NoDataRelatedTo").'</span>
';
630 if (!empty($invoiceindoc['supplierref
'])) {
631 // Try to find supplier invoice
633 // Exact match. Always tried first, and always enough on its own.
634 $sql = "SELECT rowid, total_ttc FROM " . $db->prefix() . "facture_fourn";
635 $sql .= " WHERE ref_supplier = '" . $db->escape($invoiceindoc['supplierref']) . "'";
636 $sql .= " AND fk_soc = " . ((int) $tmpthirdparty->id);
637 $sql .= " AND entity IN (" . getEntity('facture_fourn
') . ")";
639 $resql = $db->query($sql);
641 dol_syslog("SQL Error " . $db->lasterror(), LOG_ERR);
644 $obj = $db->fetch_object($resql);
646 $tmpinvoice->fetch($obj->rowid);
650 if (empty($tmpinvoice->id)) {
651 print $langs->trans("InvoiceWillBeCreated");
652 print '<input
type=
"hidden" name=
"supplierref" value=
"'.$invoiceindoc['supplierref'].'">
';
653 print '<input
type=
"hidden" name=
"due_date" value=
"'.$invoiceindoc['due_date'].'">
';
654 print '<input
type=
"hidden" name=
"issue_date" value=
"'.$invoiceindoc['issue_date'].'">
';
655 print '<input
type=
"hidden" name=
"currency_code" value=
"'.$invoiceindoc['currency_code'].'">
';
656 print '<input
type=
"hidden" name=
"currency_code" value=
"'.$invoiceindoc['currency_code'].'">
';
657 print '<input
type=
"hidden" name=
"invoice_label" value=
"'.$invoiceindoc['invoice_label'].'">
';
659 print $tmpinvoice->getNomUrl(1);
660 print '<input
type=
"hidden" name=
"invoiceid" value=
"'.$tmpinvoice->id.'">
';
667 print '<center><input
type=
"submit" name=
"submit" class=
"button" value=
"'.$langs->trans("Create
").'"></center>
';
670 print '<input
type=
"hidden" name=
"jsonstring" value=
"'.$json.'">
';
677 print "<!-- Begin UploadForm -->\n";
678 print '<form
id=
"uploadform" enctype=
"multipart/form-data" method=
"POST" action=
"'.dolBuildUrl($_SERVER["PHP_SELF
"]).'">
';
679 print '<input
type=
"hidden" name=
"token" value=
"'.newToken().'">
';
680 print '<input
type=
"hidden" name=
"action" value=
"uploadfile">
';
681 print '<input
type=
"hidden" name=
"sendit" value=
"1">
';
682 print '<input
type=
"hidden" name=
"modulepart" id=
"modulepart" value=
"">
';
683 print '<input
type=
"hidden" name=
"overwritefile" value=
"1">
';
685 print '<div
class=
"center"><div
class=
"center" style=
"padding: 10px;">
';
686 print '<style>.menu_titre { padding-top: 7px; }</style>
';
687 print '<div
id=
"blockupload" class=
"center">
'."\n";
688 //print '<input
name=
"filenamePDF" id=
"filenamePDF" type=
"hideobject">
';
692 $accept = '.pdf,image
$propal type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
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.
if(! $sortfield) if(! $sortorder) $module
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
getElementProperties($elementType)
Get an array with properties of an element.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
$conf db name
Only used if Module[ID]Name translation string is not found.