From f89195e39fe015adc14bdcd9aa61414fd75babf4 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Thu, 21 May 2020 23:23:59 +0200 Subject: [PATCH 01/35] Fix SQL IF for PGSQL --- htdocs/margin/tabs/productMargins.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/margin/tabs/productMargins.php b/htdocs/margin/tabs/productMargins.php index 57eef531342..4551557e95a 100644 --- a/htdocs/margin/tabs/productMargins.php +++ b/htdocs/margin/tabs/productMargins.php @@ -136,9 +136,9 @@ if ($id > 0 || ! empty($ref)) $sql.= " f.datef, f.paye, f.fk_statut as statut, f.type,"; if (!$user->rights->societe->client->voir && !$socid) $sql.= " sc.fk_soc, sc.fk_user,"; $sql.= " sum(d.total_ht) as selling_price,"; // may be negative or positive - $sql.= " IF(f.type = 2, -1, 1) * sum(d.qty) as qty,"; // not always positive in case of Credit note - $sql.= " IF(f.type = 2, -1, 1) * sum(d.qty * d.buy_price_ht) as buying_price,"; // not always positive in case of Credit note - $sql.= " IF(f.type = 2, -1, 1) * sum(abs(d.total_ht) - (d.buy_price_ht * d.qty)) as marge" ; // not always positive in case of Credit note + $sql.= " ".$db->ifsql('f.type = 2', -1, 1)." * sum(d.qty) as qty,"; // not always positive in case of Credit note + $sql.= " ".$db->ifsql('f.type = 2', -1, 1)." * sum(d.qty * d.buy_price_ht) as buying_price,"; // not always positive in case of Credit note + $sql.= " ".$db->ifsql('f.type = 2', -1, 1)." * sum(abs(d.total_ht) - (d.buy_price_ht * d.qty)) as marge" ; // not always positive in case of Credit note $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql.= ", ".MAIN_DB_PREFIX."facture as f"; $sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; From f38118790e120bd6341a4e5342537308b7ac3ec6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 May 2020 12:18:47 +0200 Subject: [PATCH 02/35] Trans --- htdocs/langs/en_US/install.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/install.lang b/htdocs/langs/en_US/install.lang index f67dff57184..2d708c04147 100644 --- a/htdocs/langs/en_US/install.lang +++ b/htdocs/langs/en_US/install.lang @@ -218,6 +218,6 @@ ErrorFoundDuringMigration=Error(s) were reported during the migration process so YouTryInstallDisabledByDirLock=The application tried to self-upgrade, but the install/upgrade pages have been disabled for security (directory renamed with .lock suffix).
YouTryInstallDisabledByFileLock=The application tried to self-upgrade, but the install/upgrade pages have been disabled for security (by the existence of a lock file install.lock in the dolibarr documents directory).
ClickHereToGoToApp=Click here to go to your application -ClickOnLinkOrRemoveManualy=Click on the following link. If you always see this same page, you must remove/rename the file install.lock in the documents directory. +ClickOnLinkOrRemoveManualy=If an upgrade is in progress, please wait. If not, click on the following link. If you always see this same page, you must remove/rename the file install.lock in the documents directory. Loaded=Loaded FunctionTest=Function test From 91f5f8053af3eb062dbc62d5276a5af7fdcb626c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 May 2020 13:46:27 +0200 Subject: [PATCH 03/35] Fix label --- htdocs/langs/en_US/hrm.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/hrm.lang b/htdocs/langs/en_US/hrm.lang index 3697c47e30d..6cc7f6bef24 100644 --- a/htdocs/langs/en_US/hrm.lang +++ b/htdocs/langs/en_US/hrm.lang @@ -11,7 +11,7 @@ CloseEtablishment=Close establishment # Dictionary DictionaryPublicHolidays=HRM - Public holidays DictionaryDepartment=HRM - Department list -DictionaryFunction=HRM - Function list +DictionaryFunction=HRM - Job positions # Module Employees=Employees Employee=Employee From 1e208e537f12cf9be59655c728a64ab38df9e39a Mon Sep 17 00:00:00 2001 From: kamel Date: Fri, 29 May 2020 16:24:07 +0200 Subject: [PATCH 04/35] FIX: Fix link of the button to create a credit note and fix the awareness of a error happen when to create a credit note --- htdocs/compta/facture/card.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index cb3aa9cd099..b97d22631a1 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1106,12 +1106,12 @@ if (empty($reshook)) } // Add link between credit note and origin - if(! empty($object->fk_facture_source)) { + if(! empty($object->fk_facture_source) && $id>0) { $facture_source->fetch($object->fk_facture_source); $facture_source->fetchObjectLinked(); - if(! empty($facture_source->linkedObjectsIds)) { - foreach($facture_source->linkedObjectsIds as $sourcetype => $TIds) { + if (!empty($facture_source->linkedObjectsIds)) { + foreach ($facture_source->linkedObjectsIds as $sourcetype => $TIds) { $object->add_object_linked($sourcetype, current($TIds)); } } @@ -4835,9 +4835,8 @@ elseif ($id > 0 || ! empty($ref)) // Create a credit note if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA) && $object->statut > 0 && $usercancreate) { - if (! $objectidnext) - { - print ''; + if (! $objectidnext) { + print ''; } } From 30aa50684f0588c1c6610d19c5e9ca4622d1dc7a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 May 2020 16:35:01 +0200 Subject: [PATCH 05/35] Trans --- htdocs/langs/en_US/modulebuilder.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index b89e1fb0a38..b1f8fbf6384 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -139,3 +139,4 @@ ForeignKey=Foreign key TypeOfFieldsHelp=Type of fields:
varchar(99), double(24,8), real, text, html, datetime, timestamp, integer, integer:ClassName:relativepath/to/classfile.class.php[:1[:filter]] ('1' means we add a + button after the combo to create the record, 'filter' can be 'status=1 AND fk_user = __USER_ID AND entity IN (__SHARED_ENTITIES__)' for example) AsciiToHtmlConverter=Ascii to HTML converter AsciiToPdfConverter=Ascii to PDF converter +TableNotEmptyDropCanceled=Table not empty. Drop has been canceled. \ No newline at end of file From 264fd709e4d8d0d97d7e0c6ad779110af6157f2b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 May 2020 15:13:16 +0200 Subject: [PATCH 06/35] Fix template --- .../modulebuilder/template/core/modules/modMyModule.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 21ede6bfd58..74dbac7b870 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -316,7 +316,7 @@ class modMyModule extends DolibarrModules 'titre'=>'New MyObject', 'mainmenu'=>'mymodule', 'leftmenu'=>'mymodule_myobject_new', - 'url'=>'/mymodule/myobject_page.php?action=create', + 'url'=>'/mymodule/myobject_card.php?action=create', 'langs'=>'mymodule@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>1000+$r, 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. From 540a64bbba250a1cb046fcc94cf74b48afdb6068 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 May 2020 15:29:33 +0200 Subject: [PATCH 07/35] Fix templates --- htdocs/modulebuilder/template/myobject_agenda.php | 2 +- htdocs/modulebuilder/template/myobject_card.php | 2 +- htdocs/modulebuilder/template/myobject_list.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/modulebuilder/template/myobject_agenda.php b/htdocs/modulebuilder/template/myobject_agenda.php index 9b71971b6cf..8f4117a871e 100644 --- a/htdocs/modulebuilder/template/myobject_agenda.php +++ b/htdocs/modulebuilder/template/myobject_agenda.php @@ -140,7 +140,7 @@ if ($object->id > 0) $head = myobjectPrepareHead($object); - dol_fiche_head($head, 'agenda', $langs->trans("MyObject"), -1, $object->picto); + dol_fiche_head($head, 'agenda', $langs->trans("MyObject"), -1, 'object_'.$object->picto); // Object card // ------------------------------------------------------------ diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index e92c88f1364..b8f0476497d 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -205,7 +205,7 @@ jQuery(document).ready(function() { // Part to create if ($action == 'create') { - print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("MyObject"))); + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("MyObject")), '', 'object_'.$object->picto); print '
'; print ''; diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index a0fcb744bb1..0059570d314 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -374,7 +374,7 @@ print ''; $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/mymodule/myobject_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_companies', 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); // Add code for pre mass action (confirmation or email presend form) $topicmail = "SendMyObjectRef"; From 7fc6917cfdd6145de58da055f00cfc7ad2d49461 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 May 2020 21:59:33 +0200 Subject: [PATCH 08/35] Debug feature of alternate languages --- htdocs/core/class/commonobject.class.php | 6 ++++-- htdocs/core/class/extralanguages.class.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 4fcac1979b7..a6b96ef3b4d 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -635,6 +635,7 @@ abstract class CommonObject $contactid = 0; $thirdpartyid = 0; + $elementforaltlanguage = $this->element; if ($this->element == 'societe') { $thirdpartyid = $this->id; @@ -682,10 +683,11 @@ abstract class CommonObject include_once DOL_DOCUMENT_ROOT.'/core/class/extralanguages.class.php'; $extralanguages = new ExtraLanguages($this->db); } - $extralanguages->fetch_name_extralanguages('societe'); + $extralanguages->fetch_name_extralanguages($elementforaltlanguage); - if (!empty($extralanguages->attributes['societe']['address']) || !empty($extralanguages->attributes['societe']['town'])) + if (!empty($extralanguages->attributes[$elementforaltlanguage]['address']) || !empty($extralanguages->attributes[$elementforaltlanguage]['town'])) { + $out .= "\n"; $this->fetchValuesForExtraLanguages(); if (!is_object($form)) $form = new Form($this->db); $htmltext = ''; diff --git a/htdocs/core/class/extralanguages.class.php b/htdocs/core/class/extralanguages.class.php index 48f2e94936a..08413c788b2 100644 --- a/htdocs/core/class/extralanguages.class.php +++ b/htdocs/core/class/extralanguages.class.php @@ -71,7 +71,7 @@ class ExtraLanguages /** * Load array this->attributes with list of fields per object that need an alternate translation. The object and field must be managed with * the widgetForTranslation() method. - * You can set variable MAIN_USE_ALTERNATE_TRANSLATION_FOR=elementA:fieldname,fieldname2;elementB:... + * You must set variable MAIN_USE_ALTERNATE_TRANSLATION_FOR=elementA:fieldname,fieldname2;elementB:... * Example: MAIN_USE_ALTERNATE_TRANSLATION_FOR=societe:name,town;contact:firstname,lastname * * @param string $elementtype Type of element ('' = all, 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). From 455ba002b4c340378b6f7e018212876d80bcea12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 May 2020 22:13:10 +0200 Subject: [PATCH 09/35] css --- htdocs/modulebuilder/index.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 5b53de530bd..069fcad2bd2 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -2419,7 +2419,7 @@ elseif (!empty($module)) else { //print ''.$langs->trans("FileNotYetGenerated").' '; - print ''; + print ''; } // PHPUnit print '
'; @@ -2434,7 +2434,7 @@ elseif (!empty($module)) else { //print ''.$langs->trans("FileNotYetGenerated").' '; - print ''; + print ''; } print '
'; @@ -2470,7 +2470,7 @@ elseif (!empty($module)) print ''.$langs->trans("DropTableIfEmpty").''; } else { - print ''; + print ''; } //print '   '.$langs->trans("RunSql").''; print '
'; @@ -2563,15 +2563,15 @@ elseif (!empty($module)) //$propstat = $reflector->getStaticProperties(); //var_dump($reflectorpropdefault); - print ''; + print ''; print ''; print ''; print ''; print ''; print ''; - print ''; - //print ''; + print ''; + //print ''; print '

'; print load_fiche_titre($langs->trans("ObjectProperties"), '', ''); @@ -3121,7 +3121,7 @@ elseif (!empty($module)) else { print ''.$langs->trans("FileNotYetGenerated").''; - print ''; + print ''; print ''; } print ''; @@ -3191,7 +3191,7 @@ elseif (!empty($module)) { print ''; print ' '.$langs->trans("NoTrigger"); - print ''; + print ''; print ''; print ''; } @@ -3246,7 +3246,7 @@ elseif (!empty($module)) else { print ''.$langs->trans("FileNotYetGenerated").''; - print ''; + print ''; } print ''; } @@ -3298,7 +3298,7 @@ elseif (!empty($module)) else { print ''.$langs->trans("FileNotYetGenerated").''; - print ''; + print ''; } print ''; } @@ -3356,7 +3356,7 @@ elseif (!empty($module)) else { print ' '.$langs->trans("NoWidget"); - print ''; + print ''; print ''; } print ''; @@ -3442,7 +3442,7 @@ elseif (!empty($module)) else { print ' '.$langs->trans("NoCLIFile"); - print ''; + print ''; print ''; } print ''; @@ -3624,7 +3624,7 @@ elseif (!empty($module)) { print ''; print ' '.$langs->trans("FileNotYetGenerated"); - print ''; + print ''; print ''; } print ''; From 926a9f68c4b7d424c09764a7d9b56321b9918046 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 00:23:14 +0200 Subject: [PATCH 10/35] Trans --- htdocs/langs/en_US/admin.lang | 2 +- htdocs/modulebuilder/index.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index bee43c2569f..38ca68ffdbe 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -207,7 +207,7 @@ ModulesMarketPlaces=Find external app/modules ModulesDevelopYourModule=Develop your own app/modules ModulesDevelopDesc=You may also develop your own module or find a partner to develop one for you. DOLISTOREdescriptionLong=Instead of switching on www.dolistore.com web site to find an external module, you can use this embedded tool that will perform the search on the external market place for you (may be slow, need an internet access)... -NewModule=New +NewModule=New module FreeModule=Free CompatibleUpTo=Compatible with version %s NotCompatible=This module does not seem compatible with your Dolibarr %s (Min %s - Max %s). diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 069fcad2bd2..5a40b0214f7 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -1756,7 +1756,7 @@ $head[$h][1] = $langs->trans("DangerZone"); $head[$h][2] = 'deletemodule'; $h++; -dol_fiche_head($head, $module, $langs->trans("Modules"), -1, 'generic', 0, $infomodulesfound, '', 8); // Modules +dol_fiche_head($head, $module, '', -1, '', 0, $infomodulesfound, '', 8); // Modules if ($module == 'initmodule') { From 0fd3292715cc3616292535c43defea6392bafb5a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 00:35:11 +0200 Subject: [PATCH 11/35] Fix show error message --- htdocs/modulebuilder/index.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 5a40b0214f7..3c118395e6b 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -650,14 +650,18 @@ if ($dirins && $action == 'confirm_removefile' && !empty($module)) $dirtodelete = $dirins.'/'.$dirnametodelete; $result = dol_delete_file($filetodelete); - if (dol_is_dir_empty($dirtodelete)) dol_delete_dir($dirtodelete); + if (! $result) { + setEventMessages($langs->trans("ErrorFailToDeleteFile", basename($filetodelete)), null, 'errors'); + } else { + if (dol_is_dir_empty($dirtodelete)) dol_delete_dir($dirtodelete); - // Update descriptor file to comment file - if (in_array($tab, array('css', 'js'))) - { - $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; - $arrayreplacement = array('/^\s*\''.preg_quote('/'.$relativefilename, '/').'\',*/m'=>' // \'/'.$relativefilename.'\','); - dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1); + // Update descriptor file to comment file + if (in_array($tab, array('css', 'js'))) + { + $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; + $arrayreplacement = array('/^\s*\''.preg_quote('/'.$relativefilename, '/').'\',*/m'=>' // \'/'.$relativefilename.'\','); + dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1); + } } } } From e2656ff2f803d419ad038b5cc08e3a6ba0247655 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 00:49:11 +0200 Subject: [PATCH 12/35] Update template --- htdocs/modulebuilder/template/myobject_card.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index b8f0476497d..0116d8db83e 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -215,6 +215,9 @@ if ($action == 'create') dol_fiche_head(array(), ''); + // Set some default values + //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; + print ''."\n"; // Common attributes From c4bbf12e729c0bb713bf6aa840e58343a613c818 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 00:56:51 +0200 Subject: [PATCH 13/35] Fix css --- htdocs/user/class/user.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 11d0cec3654..f9caa1e7798 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2427,7 +2427,7 @@ class User extends CommonObject $paddafterimage = ''; if (abs($withpictoimg) == 1) $paddafterimage = 'style="margin-'.($langs->trans("DIRECTION") == 'rtl' ? 'left' : 'right').': 3px;"'; // Only picto - if ($withpictoimg > 0) $picto = ''.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1).''; + if ($withpictoimg > 0) $picto = ''.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : 'class="paddingright classfortooltip"'), 0, 0, $notooltip ? 0 : 1).''; // Picto must be a photo else $picto = ''.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg == -3 ? 'small' : ''), 'mini', 0, 1).''; $result .= $picto; From 48596122e4677813e0b115c669098cba7af62e25 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 01:17:23 +0200 Subject: [PATCH 14/35] Fix template --- htdocs/modulebuilder/template/myobject_card.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 0116d8db83e..41d44a5807b 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -59,6 +59,7 @@ if (!$res) die("Include of main fails"); require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; dol_include_once('/mymodule/class/myobject.class.php'); dol_include_once('/mymodule/lib/mymodule_myobject.lib.php'); @@ -181,6 +182,7 @@ if (empty($reshook)) $form = new Form($db); $formfile = new FormFile($db); +$formproject = new FormProjets($db); $title = $langs->trans("MyObject"); $help_url = ''; @@ -346,8 +348,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtmlref.='
'.$langs->trans('Project') . ' '; if ($permissiontoadd) { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; $morehtmlref.=' : '; if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); From a69be00d377de5cec69f633d3992a200b9fbd4a3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 01:23:47 +0200 Subject: [PATCH 15/35] Fix template --- htdocs/modulebuilder/template/myobject_card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 41d44a5807b..2a79c4b6254 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -246,7 +246,7 @@ if ($action == 'create') // Part to edit record if (($id || $ref) && $action == 'edit') { - print load_fiche_titre($langs->trans("MyObject")); + print load_fiche_titre($langs->trans("MyObject"), '', 'object_'.$object->picto); print ''; print ''; From f9ac4c2ada46814e05dfcf874ada403d6ebce70c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 01:25:51 +0200 Subject: [PATCH 16/35] Fix template --- htdocs/modulebuilder/template/myobject_card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 2a79c4b6254..de26be0cb22 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -383,7 +383,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'."\n"; // Common attributes - //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just after this field + //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field //unset($object->fields['fk_project']); // Hide field already shown in banner //unset($object->fields['fk_soc']); // Hide field already shown in banner include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; From 156f09729eb77d9f4c9dcb6387d22a45979cc2d6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 02:10:02 +0200 Subject: [PATCH 17/35] Debug module Payment by credit transfer --- htdocs/admin/paymentbybanktransfer.php | 482 +++++++++++++++++++ htdocs/admin/prelevement.php | 89 +--- htdocs/core/modules/modPrelevement.class.php | 1 - htdocs/langs/en_US/withdrawals.lang | 2 + 4 files changed, 496 insertions(+), 78 deletions(-) create mode 100644 htdocs/admin/paymentbybanktransfer.php diff --git a/htdocs/admin/paymentbybanktransfer.php b/htdocs/admin/paymentbybanktransfer.php new file mode 100644 index 00000000000..3464a0857b7 --- /dev/null +++ b/htdocs/admin/paymentbybanktransfer.php @@ -0,0 +1,482 @@ + + * Copyright (C) 2005-2014 Laurent Destailleur + * Copyright (C) 2005-2010 Regis Houssin + * Copyright (C) 2010-2013 Juanjo Menent + * Copyright (C) 2019 Markus Welters + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/credtitransfer.php + * \ingroup paymentbybanktransfer + * \brief Page to setup payments by credit transfer + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("admin", "withdrawals")); + +// Security check +if (!$user->admin) accessforbidden(); + +$action = GETPOST('action', 'alpha'); +$type = 'paymentorder'; + + +/* + * Actions + */ + +if ($action == "set") +{ + $db->begin(); + + $id = GETPOST('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT', 'int'); + $account = new Account($db); + if ($account->fetch($id) > 0) + { + $res = dolibarr_set_const($db, "PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT", $id, 'chaine', 0, '', $conf->entity); + if (!$res > 0) $error++; + /* + $res = dolibarr_set_const($db, "PRELEVEMENT_CODE_BANQUE", $account->code_banque,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + $res = dolibarr_set_const($db, "PRELEVEMENT_CODE_GUICHET", $account->code_guichet,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + $res = dolibarr_set_const($db, "PRELEVEMENT_NUMERO_COMPTE", $account->number,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + $res = dolibarr_set_const($db, "PRELEVEMENT_NUMBER_KEY", $account->cle_rib,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + $res = dolibarr_set_const($db, "PRELEVEMENT_IBAN", $account->iban,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + $res = dolibarr_set_const($db, "PRELEVEMENT_BIC", $account->bic,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + $res = dolibarr_set_const($db, "PRELEVEMENT_RAISON_SOCIALE", $account->proprio,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + */ + } else $error++; + + $res = dolibarr_set_const($db, "PAYMENTBYBANKTRANSFER_ICS", GETPOST("PAYMENTBYBANKTRANSFER_ICS"), 'chaine', 0, '', $conf->entity); + if (!$res > 0) $error++; + + if (GETPOST("PAYMENTBYBANKTRANSFER_USER") > 0) + { + $res = dolibarr_set_const($db, "PAYMENTBYBANKTRANSFER_USER", GETPOST("PAYMENTBYBANKTRANSFER_USER"), 'chaine', 0, '', $conf->entity); + if (!$res > 0) $error++; + } + /* + if (GETPOST("PAYMENTBYBANKTRANSFER_END_TO_END") || GETPOST("PAYMENTBYBANKTRANSFER_END_TO_END") == "") + { + $res = dolibarr_set_const($db, "PAYMENTBYBANKTRANSFER_END_TO_END", GETPOST("PAYMENTBYBANKTRANSFER_END_TO_END"), 'chaine', 0, '', $conf->entity); + if (!$res > 0) $error++; + } + if (GETPOST("PAYMENTBYBANKTRANSFER_USTRD") || GETPOST("PAYMENTBYBANKTRANSFER_USTRD") == "") + { + $res = dolibarr_set_const($db, "PAYMENTBYBANKTRANSFER_USTRD", GETPOST("PAYMENTBYBANKTRANSFER_USTRD"), 'chaine', 0, '', $conf->entity); + if (!$res > 0) $error++; + } + */ + if (GETPOST("PAYMENTBYBANKTRANSFER_ADDDAYS") || GETPOST("PAYMENTBYBANKTRANSFER_ADDDAYS") == "") + { + $res = dolibarr_set_const($db, "PAYMENTBYBANKTRANSFER_ADDDAYS", GETPOST("PAYMENTBYBANKTRANSFER_ADDDAYS"), 'chaine', 0, '', $conf->entity); + if (!$res > 0) $error++; + } elseif (!$error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + $db->rollback(); + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} + +if ($action == "addnotif") +{ + $bon = new BonPrelevement($db); + $bon->AddNotification($db, GETPOST('user', 'int'), $action); + + header("Location: ".$_SERVER["PHP_SELF"]); + exit; +} + +if ($action == "deletenotif") +{ + $bon = new BonPrelevement($db); + $bon->DeleteNotificationById(GETPOST('notif', 'int')); + + header("Location: ".$_SERVER["PHP_SELF"]); + exit; +} + + +/* + * View + */ + +$form = new Form($db); + +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + +llxHeader('', $langs->trans("CreditTransferSetup")); + +$linkback = ''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans("CreditTransferSetup"), $linkback, 'title_setup'); +print '
'; + +print ''; +print ''; + +print '
'; + +print ''; +print ''; +print ''; +print ""; + +// Bank account (from Banks module) +print ''; +print ''; + +// ICS +print ''; +print ''; +print ''; + +//User +print ''; +print ''; +print ''; + +/* +//EntToEnd +print ''; +print ''; +print ''; + +//USTRD +print ''; +print ''; +print ''; +*/ + +//ADDDAYS +print ''; +print ''; +print ''; +print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("BankToPayCreditTransfer").''; +$form->select_comptes($conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT, 'PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT', 0, "courant=1", 1); +print '
'.$langs->trans("ICS").''; +print '
'.$langs->trans("ResponsibleUser").''; +print $form->select_dolusers($conf->global->PAYMENTBYBANKTRANSFER_USER, 'PAYMENTBYBANKTRANSFER_USER', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); +print '
'.$langs->trans("END_TO_END").''; +print '
'.$langs->trans("USTRD").''; +print '
'.$langs->trans("ADDDAYS").''; +if (!$conf->global->PAYMENTBYBANKTRANSFER_ADDDAYS) $conf->global->PAYMENTBYBANKTRANSFER_ADDDAYS = 0; +print '
'; +print '
'; + +print '
'; + +print ''; + + +print '
'; + + +/* + * Document templates generators + */ +/* +print load_fiche_titre($langs->trans("OrdersModelModule"),'',''); + +// Load array def with activated templates +$def = array(); +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + + +print "\n"; +print "\n"; +print ''; +print ''; +print '\n"; +print '\n"; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) +{ + foreach (array('','/doc') as $valdir) + { + $dir = dol_buildpath($reldir."core/modules/paymentorders".$valdir); + + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + arsort($filelist); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + $var = !$var; + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } + else + { + print '"; + } + + // Default + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip.='
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + //$htmltooltip.='
'.$langs->trans("Discounts").': '.yn($module->option_escompte,1,1); + //$htmltooltip.='
'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); + $htmltooltip.='
'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); + + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } +} + +*/ + + +dol_fiche_end(); + +print '
'; + + +/* + * Notifications + */ + +/* Disable this, there is no trigger with elementtype 'withdraw' +if (! empty($conf->global->MAIN_MODULE_NOTIFICATION)) +{ + $langs->load("mails"); + print load_fiche_titre($langs->trans("Notifications")); + + $sql = "SELECT u.rowid, u.lastname, u.firstname, u.fk_soc, u.email"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; + $sql.= " WHERE entity IN (".getEntity('invoice').")"; + + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + if (!$obj->fk_soc) + { + $username=dolGetFirstLastname($obj->firstname,$obj->lastname); + $internalusers[$obj->rowid] = $username; + } + + $i++; + } + $db->free($resql); + } + + // Get list of triggers for module withdraw + $sql = "SELECT rowid, code, label"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_action_trigger"; + $sql.= " WHERE elementtype = 'withdraw'"; + $sql.= " ORDER BY rang ASC"; + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + $label=($langs->trans("Notify_".$obj->code)!="Notify_".$obj->code?$langs->trans("Notify_".$obj->code):$obj->label); + $actions[$obj->rowid]=$label; + $i++; + } + $db->free($resql); + } + + + print ''; + print ''; + print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print "'; + if ($conf->global->PAYMENTORDER_ADDON_PDF == $name) + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'bill').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
'; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + print ''; + + print ''; + + print ''; + + // List of current notifications for objet_type='withdraw' + $sql = "SELECT u.lastname, u.firstname,"; + $sql.= " nd.rowid, ad.code, ad.label"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u,"; + $sql.= " ".MAIN_DB_PREFIX."notify_def as nd,"; + $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as ad"; + $sql.= " WHERE u.rowid = nd.fk_user"; + $sql.= " AND nd.fk_action = ad.rowid"; + $sql.= " AND u.entity IN (0,".$conf->entity.")"; + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + + print ''; + print ''; + $label=($langs->trans("Notify_".$obj->code)!="Notify_".$obj->code?$langs->trans("Notify_".$obj->code):$obj->label); + print ''; + print ''; + print ''; + $i++; + } + $db->free($resql); + } + + print '
'.$langs->trans("User").''.$langs->trans("Value").''.$langs->trans("Action").'
'; + print $form->selectarray('user',$internalusers);// select_dolusers(0,'user',0); + print ''; + print $form->selectarray('action',$actions);// select_dolusers(0,'user',0); + print '
'.dolGetFirstLastname($obj->firstname,$obj->lastname).''.$label.'rowid.'">'.img_delete().'
'; + print ''; +} +*/ + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index e9795304ad3..c83c8627f2b 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -113,7 +113,7 @@ if ($action == "addnotif") $bon = new BonPrelevement($db); $bon->AddNotification($db, GETPOST('user', 'int'), $action); - header("Location: prelevement.php"); + header("Location: ".$_SERVER["PHP_SELF"]); exit; } @@ -122,75 +122,10 @@ if ($action == "deletenotif") $bon = new BonPrelevement($db); $bon->DeleteNotificationById(GETPOST('notif', 'int')); - header("Location: prelevement.php"); + header("Location: ".$_SERVER["PHP_SELF"]); exit; } -/* -if ($action == 'specimen') -{ - $modele=GETPOST('module','alpha'); - - $commande = new Commande($db); - $commande->initAsSpecimen(); - - // Search template files - $file=''; $classname=''; $filefound=0; - $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); - foreach($dirmodels as $reldir) - { - $file=dol_buildpath($reldir."core/modules/paymentorders/doc/pdf_".$modele.".modules.php",0); - if (file_exists($file)) - { - $filefound=1; - $classname = "pdf_".$modele; - break; - } - } - - if ($filefound) - { - require_once $file; - - $module = new $classname($db); - - if ($module->write_file($commande,$langs) > 0) - { - header("Location: ".DOL_URL_ROOT."/document.php?modulepart=paymentorders&file=SPECIMEN.pdf"); - return; - } - else - { - setEventMessages($module->error, null, 'errors'); - dol_syslog($module->error, LOG_ERR); - } - } - else - { - setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); - dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); - } -} - -// Set default model -elseif ($action == 'setdoc') -{ - if (dolibarr_set_const($db, "PAYMENTORDER_ADDON_PDF",$value,'chaine',0,'',$conf->entity)) - { - // The constant that was read before the new set - // We therefore requires a variable to have a coherent view - $conf->global->PAYMENTORDER_ADDON_PDF = $value; - } - - // On active le modele - $ret = delDocumentModel($value, $type); - if ($ret > 0) - { - $ret = addDocumentModel($value, $type, $label, $scandir); - } -} -*/ - /* * View @@ -207,52 +142,52 @@ $linkback = ''; -print '
'; +print ''; print ''; print ''; print ''; -print ''; -print ''; +print ''; +print ''; print ""; // Bank account (from Banks module) -print ''; +print ''; print ''; // ICS -print ''; +print ''; print ''; print ''; //User -print ''; +print ''; print ''; print ''; //EntToEnd -print ''; +print ''; print ''; print ''; //USTRD -print ''; +print ''; print ''; print ''; //ADDDAYS -print ''; +print ''; print ''; +print ''; print ''; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").''.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("BankToReceiveWithdraw").'
'.$langs->trans("BankToReceiveWithdraw").''; $form->select_comptes($conf->global->PRELEVEMENT_ID_BANKACCOUNT, 'PRELEVEMENT_ID_BANKACCOUNT', 0, "courant=1", 1); print '
'.$langs->trans("ICS").'
'.$langs->trans("ICS").''; print '
'.$langs->trans("ResponsibleUser").'
'.$langs->trans("ResponsibleUser").''; print $form->select_dolusers($conf->global->PRELEVEMENT_USER, 'PRELEVEMENT_USER', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); print '
'.$langs->trans("END_TO_END").'
'.$langs->trans("END_TO_END").''; print '
'.$langs->trans("USTRD").'
'.$langs->trans("USTRD").''; print '
'.$langs->trans("ADDDAYS").'
'.$langs->trans("ADDDAYS").''; if (!$conf->global->PRELEVEMENT_ADDDAYS) $conf->global->PRELEVEMENT_ADDDAYS = 0; -print '
'; print '
'; diff --git a/htdocs/core/modules/modPrelevement.class.php b/htdocs/core/modules/modPrelevement.class.php index 00259fec22c..b1e8cb2db57 100644 --- a/htdocs/core/modules/modPrelevement.class.php +++ b/htdocs/core/modules/modPrelevement.class.php @@ -34,7 +34,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; */ class modPrelevement extends DolibarrModules { - /** * Constructor. Define names, constants, directories, boxes, permissions * diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index fb6c56687ee..a7a55c69c53 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -27,6 +27,7 @@ NoInvoiceToWithdraw=No customer invoice with open 'Direct debit requests' is wai NoSupplierInvoiceToWithdraw=No supplier invoice with open 'Direct credit requests' is waiting. Go on tab '%s' on invoice card to make a request. ResponsibleUser=User Responsible WithdrawalsSetup=Direct debit payment setup +CreditTransferSetup=Crebit transfer setup WithdrawStatistics=Direct debit payment statistics WithdrawRejectStatistics=Direct debit payment reject statistics LastWithdrawalReceipt=Latest %s direct debit receipts @@ -74,6 +75,7 @@ NumeroNationalEmetter=National Transmitter Number WithBankUsingRIB=For bank accounts using RIB WithBankUsingBANBIC=For bank accounts using IBAN/BIC/SWIFT BankToReceiveWithdraw=Receiving Bank Account +BankToPayCreditTransfer=Bank Account used as source of payments CreditDate=Credit on WithdrawalFileNotCapable=Unable to generate withdrawal receipt file for your country %s (Your country is not supported) ShowWithdraw=Show Direct Debit Order From 8146e4fdbdcad2a312d053567bb7ab9319eeb2e5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 02:17:10 +0200 Subject: [PATCH 18/35] Fix tooltip --- htdocs/admin/prelevement.php | 18 ++++++++++++++---- htdocs/langs/en_US/admin.lang | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index c83c8627f2b..0cfd03b7148 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -159,9 +159,13 @@ $form->select_comptes($conf->global->PRELEVEMENT_ID_BANKACCOUNT, 'PRELEVEMENT_ID print ''; // ICS -print ''.$langs->trans("ICS").''; +print ''; +$htmltext = $langs->trans("AskThisIDToYourBank"); +print $form->textwithpicto($langs->trans("ICS"), $htmltext); +print ''; print ''; -print ''; +print ''; +print ''; print ''; //User @@ -172,13 +176,19 @@ print ''; print ''; //EntToEnd -print ''.$langs->trans("END_TO_END").''; +print ''; +$htmltext = $langs->trans("KeepThisEmptyInMostCases"); +print $form->textwithpicto($langs->trans("END_TO_END"), $htmltext); +print ''; print ''; print ''; print ''; //USTRD -print ''.$langs->trans("USTRD").''; +print ''; +$htmltext = $langs->trans("KeepThisEmptyInMostCases"); +print $form->textwithpicto($langs->trans("USTRD"), $htmltext); +print ''; print ''; print ''; print ''; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 38ca68ffdbe..3d7407820a5 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -446,6 +446,7 @@ LinkToTestClickToDial=Enter a phone number to call to show a link to test the Cl RefreshPhoneLink=Refresh link LinkToTest=Clickable link generated for user %s (click phone number to test) KeepEmptyToUseDefault=Keep empty to use default value +KeepThisEmptyInMostCases=In most cases, you can keep this field empy. DefaultLink=Default link SetAsDefault=Set as default ValueOverwrittenByUserSetup=Warning, this value may be overwritten by user specific setup (each user can set his own clicktodial url) From b61b8ee1fb64183d2d48fccdbf76c5f4dded5097 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 02:27:10 +0200 Subject: [PATCH 19/35] Fix token renewal --- htdocs/imports/emptyexample.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/imports/emptyexample.php b/htdocs/imports/emptyexample.php index c5cee170394..0fa532a6e1b 100644 --- a/htdocs/imports/emptyexample.php +++ b/htdocs/imports/emptyexample.php @@ -21,6 +21,9 @@ * \brief Show example of import file */ +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) + + /** * This file is a wrapper, so empty header * From dfb5f02f4b45ea4d0b34730ba9c379e9282f0e1f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 02:40:05 +0200 Subject: [PATCH 20/35] Fix token renewal --- htdocs/imports/import.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index a84b255601d..0819ce0ac30 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -823,6 +823,7 @@ if ($step == 4 && $datatoimport) print ''.$langs->trans("CsvOptions").''; print ''; print ''; + print ''; print ''; print ''; print ''; @@ -1249,6 +1250,7 @@ if ($step == 5 && $datatoimport) print ''; + print ''; print ''; // step 5 print ''; // step 5 From a3b5d649e67d622c96ed9ce006e2dc565b6e019b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 12:30:05 +0200 Subject: [PATCH 21/35] Clean images for v12 --- doc/images/dolibarr.gif | Bin 1265 -> 0 bytes doc/images/dolibarr.ico | Bin 2238 -> 0 bytes doc/images/dolibarr_120x90.png | Bin 2353 -> 0 bytes doc/images/dolibarr_124x124.png | Bin 1848 -> 0 bytes doc/images/dolibarr_192x192.png | Bin 3453 -> 0 bytes doc/images/dolibarr_256x256.png | Bin 3525 -> 0 bytes doc/images/dolibarr_256x256_black.png | Bin 0 -> 1846 bytes doc/images/dolibarr_256x256_black.svg | 313 ++++++++++++++++++++++++ doc/images/dolibarr_256x256_color.png | Bin 0 -> 5078 bytes doc/images/dolibarr_256x256_color.svg | 123 ++++++++++ doc/images/dolibarr_256x256_white.jpg | Bin 0 -> 2601 bytes doc/images/dolibarr_256x256_white.png | Bin 0 -> 4257 bytes doc/images/dolibarr_256x256_white.svg | 327 ++++++++++++++++++++++++++ doc/images/dolibarr_48x48.png | Bin 1147 -> 0 bytes doc/images/dolibarr_512x512.png | Bin 6959 -> 0 bytes doc/images/dolibarr_73x73.png | Bin 1468 -> 0 bytes doc/images/dolibarr_favicon.ico | Bin 0 -> 2238 bytes doc/images/dolibarr_logo.jpg | Bin 23963 -> 18776 bytes doc/images/dolibarr_logo.png | Bin 25554 -> 14133 bytes doc/images/dolibarr_logo.svg | 209 ++++++++++++++++ 20 files changed, 972 insertions(+) delete mode 100644 doc/images/dolibarr.gif delete mode 100644 doc/images/dolibarr.ico delete mode 100644 doc/images/dolibarr_120x90.png delete mode 100644 doc/images/dolibarr_124x124.png delete mode 100644 doc/images/dolibarr_192x192.png delete mode 100644 doc/images/dolibarr_256x256.png create mode 100644 doc/images/dolibarr_256x256_black.png create mode 100644 doc/images/dolibarr_256x256_black.svg create mode 100644 doc/images/dolibarr_256x256_color.png create mode 100644 doc/images/dolibarr_256x256_color.svg create mode 100644 doc/images/dolibarr_256x256_white.jpg create mode 100644 doc/images/dolibarr_256x256_white.png create mode 100644 doc/images/dolibarr_256x256_white.svg delete mode 100644 doc/images/dolibarr_48x48.png delete mode 100644 doc/images/dolibarr_512x512.png delete mode 100644 doc/images/dolibarr_73x73.png create mode 100644 doc/images/dolibarr_favicon.ico mode change 100644 => 100755 doc/images/dolibarr_logo.png create mode 100644 doc/images/dolibarr_logo.svg diff --git a/doc/images/dolibarr.gif b/doc/images/dolibarr.gif deleted file mode 100644 index 7e6ac330fb1c7658e1aa91fabe687c6eef1f0fef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1265 zcmZ?wbhEHbRA5kGc;3z+<5MB)TP5dTtq@SF7*wYe+@KuNq#D+&7T&5E(W)NVrV-Vl z71O01+pQDVqZ8L_5Z9rX(5Ig`!6dQEAbFB$a=&59WaHGSmZ`la>C;U!W|(EpFw2@{ zkv-cocdk|5eCzxL_W84I3m4fHEp{!O>0C75zId^H$x`>?Io`$79ZQ$HmM(HCU*TM_ z%D-YkK;?X&npI)d^TKN82h^{QtXmM%uqd{1ad`9ExTYoX%}ZliR>ik0PiS2h+qp5m zYg1y+=ER;YIlZfMdsi1uTwgqCUEbtvB~!Ol&DdNzb9c?0U5#_MH_hA8G;e3~{GH7U zcDF3t)4FI++oHYgi}$rJ+267BK*zF!T_AL*YsKO26-T;P9_?9mtatVCzBMN%uQ@zt z%bA5c&Mn$`VaeXhYY$vnf9UeQv$yx3zjx%){Uetj9=m-1I1pU{q6a6g0@1@0*Pfib z_UP30$EU78Iep{F`J0cgKYDZP@tb?k-rj%q_Su_{FW-ND_5SnQPha1C`u6_w_isOb z{rvUk*Y7{S|NQ;)=kMRY|3KjXD4<^mDE44Gh6M+kSt2!JPHb3sxSc1|V~)qhMMt|u{4?&H*tqz3zl?i_ zjOV5$Cnu}8u884e?l?W&q3+9!#H6KXXKOjWxO4OAg!A(q7_SOGPF^0kSbmb$Th1*n z{hjmkH0I8_(tLGw%$%&RKiN-ST`yhPVtvlnhi)bV{TaV~(#XW_CsGo5n<3pYL0_I(<$?a$GbeP_jWI^<%P zX3n{|*jXTJ7Ry#vt_{h-hO)c2&07|h6+Gdc6GO3y3+fDP345e*~brRnAtu&w%7c>=*&#({<&41 z^7W1X|NEI-J;qn?Ht=Bmf6WCCntV-;y78rP9y;74qLlEk)yHHj8(%c5(UDdKrGf(; zDtZ^ENSS4{w)3cLvslDvaBPK3aOM>T5ycXji4HwB$082&J0v+Ap5VO9pi#huMUa`r z!R%!UBa4gX(uNBEvD?{(`igCn$KpWOv`*WgK^2qXR~s)y?i!{;fUt* PIVIOJpU+`rWUvMRBDp^! diff --git a/doc/images/dolibarr.ico b/doc/images/dolibarr.ico deleted file mode 100644 index 611e4bf150e66d320bd6eb8929fa3b93d0af5eb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2238 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 XhnrgM|N76U00000NkvXXu0mjfEI*cg diff --git a/doc/images/dolibarr_124x124.png b/doc/images/dolibarr_124x124.png deleted file mode 100644 index 43608028278fe4e2c60833ea377f81991caa966a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1848 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 diff --git a/doc/images/dolibarr_256x256.png b/doc/images/dolibarr_256x256.png deleted file mode 100644 index 3c3c61008adfc9caec9aeee2ce0b9ffd8a9e7257..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3525 zcmV;$4Lb6PP);8}Hega!f(!f^J2G%+Qn+O0104TvQY1V>i{ta{h z5CBku!2|$TAaDf&D-bBbU;=;=3?={w08G<>2>=2Bu0UV{fR|wK84j#KAOPSB1WGVi zfxs0AOaM@VK?w#c5C{MW062rfXH6;sSb;zQKmb4hc-gxL=t!0>4&Zkfdl@@x+xD|< z+qP}5&BwKEZ|uy(&LlG#_gByM)ca~u|KI7e=A6EL>sH^Y`o9BgjFlE0F}!;;c`b!q zisE#++2wM7{SAlH)oOQI?apt%G+P}ev#rTubGsD+^aA}l0Ir(co7y@>A+y!qXtp&r zTWgvu?5Z_cY8x%(buGpklgVNu;6^p#&UqxN(}$+scm5EP8w&sy28L==VR=J-c|$>Y zLqm&|JOs1^Vhi^7=^odfUG%;B=GGizU8bQnv!pi5P}^*=6CeQO5gz0>v|BX0z8yXp zYMKt`R2>5IDatLaBfxtA*+jPsx^Qgw+4s&^_|Tb`Pwd$#JdgkZAffn&Gv9?Cguj^$76Q5s1Gg*yH~;=o}t+^XdJs znAGcwy*bNwWY#uWkO4qCECaASu;TG^?>To!M6e%PA!JMdpwp<&8qsCypyZW1vleYR zCF2VR2Pj13p;o#V`VW^{{dFKH1BkQNj1@m{3 ztFE5f=bhW8v=8x@bQTB+0Qw|#n)~1xPt4tMD5o4nFhW2^p#i?H-!$>{mHR*2oh{=K z2tcD&-*^77JI)@gR;eTn001^S^x}2n^*Rk^fg}YZdc?kY)8zX;+GMsmkO5=_eUdx9 zd;7G|KwoT(B`>@%{@~7OH@&sCp}7?qKt>SPG4$NE!eD$x-2N-aOggM<;0j z0I=54S8kZ7(`rb3=mi2E`lWP!P}&fAVR!IDM*Odgn2TGKRh?NRgsNqYOkHPiYT zYD^mr<)a3W6g+g%h=fj|@&*84ZSiy0jAvh>2$mEib`HDeykXBR+=(I>Re+>U8=AT= z!?5*Ok)%T)fcq{O&N_u84FG_!AisOhAC75Ic?Uo+p?~70BL&+}6e9yj3hp|0sEBL9QW)4vU7M) zbo=0#4k6L)f>WX+x+ipCE6v+jr}XK=(iUw#i2#6Ka=VqXS`)htWR?C95-Cv;y%Ib2 zPm3JVEv9V*!?~loFWGWRzyrus18)3)M0M7PZVz8FibP_z+Q-~AoBk_oywpE6a#XMQ z3H_72eKWRO-(Jmv91CLp1~h2c9j<*DMs~fiV(++qiR?MrJE;?Sr)h&z4`h~N7U&;B z@xA_F-nFlMe);pO_GcQ&3ytlQ=;xzF0KmVJWvIFB?KQW&wK~UGOJ0TD{VWC$03HAb zvq~?2Vbw=p9dfzd{c}!N4w2dYzgTHpl>; z0U5>BSH8IFL_wvuyb$Q08YNgW91?(+Hz+l=*lv2`%jd3{IJR#B32#KtxV`BHWB~B+ zZ0Q3ZZ`gUVn1sh(?V$!h4Zx)&c=(fzAK!CkxA+buu-FbEtPiT*WI+b-FtFO4cfPl_ zrqL|^;oBGj0T=Aa`of|e!XLBO8Lbd#h2Ul9iQ;t!a;FYXB~kTa89>33NK^payt-`n z=-vtbzB*A47mHA-RJ=MvF$99f7VENYr$l}m5Y;{yvp^UFakOCLu?xob6gCN@M28!z z8<7EkmnO6Ii#?enDmDtjED-R;N?{Te|K=qelgf$WHDkt%qH05RV{C^|A$JZ9A_cQR zm<8f&l_hGLNZxwm<0mvBHINEyKGbIQnC}7HZl%s-K@kl6HzF5OO_Q0$00IDbAIKF?LaJ_P z!REN=2I4C?z;|emI8hgBnuyR0hn*358s9(p>z;cd6<0PW*c%iHfU6lpyOOAiD;hX{ zjHm&iM`EV|U7|@;MHThL4*~$LnLbeD_b4m_pa|v#W1ys{h;jXrNmRz_2D8CV{0FS1C9r7!kljhp@oAFBnB)%P6ek@)=?X zgyp~Q-g)NNyDkgN=5VGLR+48S06?u$y?DdauJIj6Y{&D;SqzW|p%nuEDt7ljcIEhS z{gX*}`!ful`~Z;wK%-GVcm33J$Mhm^a3HgUM54ud7_VLr6X2_V{)VZn?T5TUy~&bZ zSml`y5c>i__k@nG+&m+;V<>rv?Z*l{a55xn0Q{@88ujH<2Hbw`2=)!~9$Sy*|JzRw z834xjPhpe&ah<}*tF+o2`_lhK0e}ENkHd(b3D=!Iq+eS>Gap36#^wdpr3wp-=v8HQ%CfQ_topjo0Zp^4rUri5ibCgzx|KG z{jYGH*6f`e*(W8kUt08lv}m1HLv6wryV8F-|AQeAu-iSVeMmy*@WiNy#K?%`sEDMf zb{e&c+7_qFy?omV;s604(1}-fUpSh63%jB9TCGm2W{-1rv70_D*grhTkA2C07fE2_ z!5j|zpdbJQJM{Ci$^8j_%YqF@NK|S9;M@LLcCw&?M1pgIIWz4fKM3iC6}wIr5hLLc2;hD8_-7;x0Dz-8rL6rE0RWP&ns{O1R{D2vOsbeKf)x}2 zf1&f|R7PP1F|uUe+W`THked&(s#uj2^%K!k!a?6%(IYx|Z0RZ4| zx*nUko_}45HNip-g5Zs1I||Bbh(F;L#NhsiJtvFiu02Q!F>(!o0P0MZ2R>M>D8$GW z001txa{qf@etq~mf0zcv2uQ@C|DIFDBsvtq2mub(AIP5h)jsk(6v60+7G73K)k7bw z7XH7F8UQ#bt7*Fa#pSIw2a#j}0MOLZdfki5YWTN2AOJwbjXrODWo2P`9r1&WvB-Ni z#$rDx)!l#nOUsVt8cB4>0Knnyzu}eT2eS;s9cFi^PQ*05~YAtbg!>ua0CJi37|6;rTE0gMY!gL$58}CU$Q# zS|Jbt9Gu82dt&CgjG{`C3Wh+?&}?~i@wOFPk0}aC1aE?o0?e)U*{k=ni)~~}@<0Xv ztKGR|(~%E8-OV2VBo71tG?}f7)*qU;?qI#iLLgNDV19GahQrIY9Q#E}4`_uxAO@$T z{yR>Wd-I{3#T$?8OD~e8%taB5B3M!AXpZr#J?ZQAWq!R~A;>TU0+-9p?t9j~ymoJ9 zd2JJc3;_V8HH`-|O12-%+kK+YWVRBt`2fHvENqDuTb+0~tK?9YL8OIRXoWyC5Qp2{ zSlw7sQO{;_at+n2QJHiik(`s%!YlNSVj$Qt~`mewA(fj+d?|%KI zUdyPp8jW77`Su%bx7*=zJDo0eE887Tw)&*mVl|n+zStyvRYP-Cor!%}S!ZIG%dL>d z{jXg+FaaQjK>#R^`>*V;QOMm6l9(0&fG;2baE<^#v*jx20#+ap01yE19r|_PFA!LP zz!?-w08oNK2?i?=2mrVOff5W>AaDf&695DNIy(?100;oM0)YttUV^~{;Cc8A2TCwl zfj|ic695DNT!Fw92$W#Z0YCsi0H9kg0woxJji!|dA|wrv00000NkvXXu0mjfVjEkt diff --git a/doc/images/dolibarr_256x256_black.png b/doc/images/dolibarr_256x256_black.png new file mode 100644 index 0000000000000000000000000000000000000000..d89b44bf6caff60b61b8961d8163282aacb50817 GIT binary patch literal 1846 zcmV-62g&$}P)-K~#90?cIBfTvZ*w@z2syieN4B&_cB$ram!IL^J`6Mx#VS zd_;^UK8T9O#2EDtV~{BF4@47^=s_Wh$&62hCsMqD6u|e^>+R9P+sCQ+aJMg`g}0MEc&60<{V_xfZzrpDY2|fp;Wy!DLoBxpt2)ywagx*v z^c1X-{_~5B_*h~dz&adU_~G(0u~gzVTs?+*C$JXJ!i#WDr>q;p-zv#dq$BokAO1z@ zPI}$SWf@n#3TNOW(h%S25o51QSu{C8>7eQ&d?BZG{{D95e}_@anG07e4%!yyK3pN~ z?=O-D{WX<$FMJcidowHLZh0O)BSSag0=&Zl&mp`T2XQ%GD&=o$5^Hew{F@Ly7+df% z!<{acG6K2hoEQ zLwJ5_`PhpNA$$yMD;+=&jt}Aasq;haR)p~U44p%52{<;1isk87sAv`Z@adPP(dhnkR zo|p4V2hfM95T2KFO9#-09U(j)M@d7F>P)oojJ!fhnN?@*4&nK@xO4!0n8Q6GJP&8+ zlk&0#OkrOL&%>qaoe>NELX14g!OI<%N2R80B7~31u~HtiCj5?@X-1%RWkMQWw7zs8 z6`01K3E`vgS@l0qn`e`hsw9LD$tUos(m@QsZ|5iKeq>oUR^TgmU+F*wxM{NC2I(prqJ{V3IO+WQGCZ|#ETi!Kg>ORm<9R;b zFUekAIF?bF)HxlSCxoYd+g^_ge2bR}$+wEsP+Q;r#LXtm-RJb3trO%#5r^sw}xJG1!0Vqe5*Sv$E7 z_bm2B2yY*Uq|A_u62jZZHMpzWmm$1e?A7O{P6%%omrHqHyAs0N!yWiiznMaKJD9hVkgG7a{wQ}cg9h92(K4+<09$a z_E?BbdVTmVUSf>0i56Z59>9mBQJ!NbT6kHm#|tcxY(jV`{)$&h`|HOI2O1|Kd}-N< z58^E8g36K;`|zdVL3|!x#{QClgz)jQ6<@>#HFB4m$<)ZG(!-=7v~UmNG*6vr)<(d z!H2UPuPGfw7w+xy`7Y@S)e0$>+HyQmx~A}?&O9e{URPn6)M0-{y03gdN_ewRI&$8D ke|F0D&g*@h`CG^T0d7#lLq$*5PXGV_07*qoM6N<$f+SvZi2wiq literal 0 HcmV?d00001 diff --git a/doc/images/dolibarr_256x256_black.svg b/doc/images/dolibarr_256x256_black.svg new file mode 100644 index 00000000000..727387b5068 --- /dev/null +++ b/doc/images/dolibarr_256x256_black.svg @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + D + + diff --git a/doc/images/dolibarr_256x256_color.png b/doc/images/dolibarr_256x256_color.png new file mode 100644 index 0000000000000000000000000000000000000000..417387d6a27ce85f3ba64399804845b63da235c8 GIT binary patch literal 5078 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 + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/doc/images/dolibarr_256x256_white.jpg b/doc/images/dolibarr_256x256_white.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5c4e260ba78a261d669594bf129caa758a551f3 GIT binary patch literal 2601 zcmbtVdpwj`A3x7C^9*B#o*9F2%M9bv^4Z*lV({9qE)A{sv)fCdh)V93v@hCEcuVVk z??qC|YSX&2Q7*|=luJTXa$C~njV{7_o^e_K>>qvhH|II?yPWg={eI{9o!_(Ezx)K? zc3;_k1rP)QjqnGS2Z0qJp(rsRk>S8ZF^o*c#6(0WqI5AjohC-3iAykXaS4V5jfP9( z3`v%hloWlF3|pGTX0oJM1PDTcd&n3S!>BBAnmFsTY568#h#~+1B!mG_20~&W%Pl~G z2z79L4wZ)g7G8h@&KTd5P;$&8~|h)?2g{B;`3Pw+|sqSErnq8 ziyTBc-ihR=tC~goPbYQ0fh}HIX09Wq40MmSS&mo zz#@fpzFsg0U~o_pSsUXsC2?*5O9$4CD6}FNy2zdhdDZd!i09=GrL8V^MriWs)lt)? zkAor_JC82LN#-5uihVU2(7;QcWiSF4{x5i#ADYSulNHg>Pq#PL`V-FUFm|EbyN zVd|yIa9;JBwB2V8qTipdRv+VIY^CA#V zC3P*FJpxs9^ehFQ0WnF1<*P4;Vvf$af7e;3B6c~xLGzfk>*U~1u0fZ>66bs@$Csw= zJ_yjgcEwP3d}?P-JIVj3y|KYrZjaN@P~tPqUBgCROsR1dv5e=+AvH41hcSVw65a>{ z(Gb=KLPAB>B7wD`!{PD;+7^K^c)%`?k!=Hk6{EgO zSjbD8t$*yxUT_NWne@?kQF?=h^kd<9HO}!PdJgAonO~>&B`Ba1f}d+oYu{?Uq~B#j z8?*QFvYm~!$F&X8H7TR-n$j-r%2^|`B{HEk$$i)L~UsvpcG1_sCFsK!P{hKtTM z-`#myqykS=dSKLcRLc2+bX2#CfNRT@=}zzl_*6Tn6T@Dy9#-x%Z+ zTMly-fjCwsl^1y%0Apr;0t+Up`OZvZBqyfTMZ93 zI+SoBdIbGf{)$6ulgnQWZ}sG0C{8s51>=w;I9O* zCax$ya~9q?*pG-0GZBiA;OCL6!{HZN2t1Mll2)z-amDcu?%kP{>Y&hDE}YcxLqTzF zol;zVepq$c7wQ*gRmL8O#m0(0-oBvUa9XLpf+;6>Qp&cwM!hiJoTH5&w-mON%?zUZ z!H?>iGXTADxUioHHr#G}VXx`VO0#dW^d1?y?V%`oi=U(Ro!@h%G4yKD#4o!e3l#MW zt4_B{IWMiCYT#=*AgjFt(Sdz~t1Ynb2u$Y36b9hsH|{@Ozg_r}+OCY=fn!&?ABX*S zy5gPN#kvNC`pEjbtKDZEB zbiHb_@#XQFY^(V83q5|`Gp6Obai%88xwS(HX~wxH4+TqVgz10j5&=b1iPE&;aODFM z{-aq#EgcH8Rh&Eh^2xe!EZa)=uC6=%MxF=64Q|$3f4{}CUeEvB0r9V^{?m$`k}uai zSv>gb?8|?2$YuIjnZAZ%zjdMY@c&*Z!!>DKzGH>-PqBKxs77escDH-uETe(tRA-cp Rl|~$t$SlB>T1S>2{U5|v8Fl~w literal 0 HcmV?d00001 diff --git a/doc/images/dolibarr_256x256_white.png b/doc/images/dolibarr_256x256_white.png new file mode 100644 index 0000000000000000000000000000000000000000..b8fa1fef076bc5039a8b093033c9126296b0b7d0 GIT binary patch literal 4257 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/doc/images/dolibarr_48x48.png b/doc/images/dolibarr_48x48.png deleted file mode 100644 index 557eed6a7c0eb76ba68ff45a0b0f2dda4174f410..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1147 zcmV->1cdvEP)y1A8r-yZDgX)lH zQ&weHp0v+~>sGz=bz6X#{aFTN_gOXoF!Py*?HUEM@XNYMB$J!kDRxilv&WkkZ(4gCKBvl}e61U`J1d96NQ^(sq)qmqEz~2ujLGO{E7fJ$C7r)JEHX#3W%+Mb;r7 zMh-0p$WjajZw|z5U%6AG6jL-vY=+Pp_d9ggMVbQ5F7}wh=>X;wuwzqM!fQZNZ`< zGv^!fl{_d28Ae!3^X^0cXxq0s3IXIB@_j6AuH}!gO}iEze)~^5Q2X;YAmnalAe3vK ze>)C*?vqBU%FO*C+q_IvK*M#iu+0WC?!x2u z7v|LV*|b|>=dCxr;Q0Njq98P~xGtVLYu?BSGkOmlH*DNAdnfiu+2Nfoe!=6hx;Q2W zQD72WdId+homQv^4S0Y N002ovPDHLkV1h6eJO}^) diff --git a/doc/images/dolibarr_512x512.png b/doc/images/dolibarr_512x512.png deleted file mode 100644 index bbe16cbc6dbb4163a0df89c94f9b949ead0fa9b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6959 zcmaJ`c|4Tg_rK2=jIr-pY$-|Bk1P?!PDPaL%ZTiIvM*zcBHGCkWzCd*$v!Hy*h(Ul zEo7(cVt#k(^ZovQfBn2(^Kzf_oO{nX_n!B;=RD`Sp@9w~c0U#Xz^JFIc^&{19HIb* z@-Jk+#&ZDnuj^^583!Ws!w6%HA%kX1tnvQ*o|re6sLEvyEnZIk&DXz+Ca5@xB2sVj znL+Q?4l~IeEHeUt02}};0HFUJF0=6fdH@OpKq&y;^cc#+|KX90L?9jVXG8%KiZT~Y zY#*gCLt+D(<}VSBA-#t1Fa7VBvUCK32mpYgs80Z3lmiX803but;ByKIm;s5PT#Dxrd2M;f5(dsT1)mJ!7ASDyD zkvjJ3dLBJU{!90{p{lZ&Gw<#j?w5HR^Zg@UxCa3}SX3r0M{n7!?gSf_!wipC@7&lo zb*22#rKGLJ@ZolP#YY!BMnebz>-WV1SQO4w*bvamZHZNL2c=SPug#xZ4(9K2@rsI* zDgSm~4nsJ12H;!2DdTj?!$J;@bov$853LVWFFbS`s=ldO;xV+Is&`GV&EOxVdK=}P z#;0`o#O{p>*B2QVi4lz(C!P3FAoy}={o-=c?)H@*BjF`qE{+Tgi(*j-4iJn7%tHcy zEmEcXf12rTvj4{WNEg~Uc}3E`&C*cc&TuNR}WGS zK2`l$vg-I@cD8Y@deQb`qtmNui;{f0Y;^#1;~73@8GV(})GVQSC%;52{9@V^v{Y22 zyq$CrF@|T!mr~*68MPN5-%s=yu&H<0HP|&buPUg`y9f+WRHCI8;o5#IbUyAC4zIgyRgWC6o|*1P8|I<_%PbvF zpYpGy3$$Ur{qsBB`{l~c8Ppr_Bb=l>k3vug?i|WxM{G)}%Uw6l5vxOM8nm-a1wDY- zHY@PJ5Hjv^1N?cdpw4gI++N#`E>-GE@i=-6q3_Z$gXCIA$E zPjmnn#ChnN5AHfKhmqI!aqBPM=HNX;)T`WgCG z@`{5rp8ErufC>`~du+ykc6U3#t;xpX>+ISMMI1E{kWu-aA4K)-h0pB0y&!`){d*{g z&`^h-`@JD^(o$t!Nu92o7h5FKL@>Cssncl>!v2te-Zm~TPb zquj+0bNP8$T1f`8RBz5=`t9*E+nEtt-eutdWw@sht#y;HRYUq>(x;g*YcDiqA-)|u zZZ6*5YSX{q$V556CmbjM)KOFtnS;L`9&f)AW7Y})VL10qv#s2Ent53Cu)$V0Ne}Og z+6>WgK0lJNr}dV(VQWaztr~N$2!j8g*J0!@uNF^*#edt+)&~(QRVlV`f9~jpE}o){O3`m+}fuj5n$ z)^f``6#htf{D{ylc~Car=>d#t*`wvl`oCx%$(0*(XaazDetmMH-dd%xW{-PP3X1}c z3}P7HlS@HsDJCVR*~ZjR!Aqp)1x)2b&z|gudwMNEznMHghA^d57E4o!)l0Tk80;_R zcI3Jx40={h%h>bRdw)6-vGrS5qk@11g!8Lz4t$OHdrBlh0ccLXg0hJ%vv)Zk4gf>L z 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 diff --git a/doc/images/dolibarr_favicon.ico b/doc/images/dolibarr_favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b93a86747d647ddc80784e7d0e0313a9eb5393e6 GIT binary patch literal 2238 zcmeH{X;9Q<9LK+A2VG>DR+_rF92*d*T)HS;g%%s|0EQvrejC=G$_Mopky_Bj+lv(H6rYcazSbIY&K$) zuN9+GCPKMPj0%}6)N&W7O=|jiJmYdc|nupi<)FlR403*E=7Xc6fe}Jdcv6Mjha*+7}LB^o92r>X+Ee= zXE}Wi4C?|>pTW9}xoBAL2jhky?Az$a#vl7L1K0$@oIMW>SyHzB(UctsQ%(??bLK1`vvA0ejU!bV=-!=&W5!$@HRj{!UIluZigDajiWBBi95 z<7A5ppSM=vivyK7)mDkqZEBo8sKyyKU$$#;rd@}#9a^00)S=g^!+EP7UmY^w>#izX z?5;&`cRjxO)P%mCR$MuG5Z6w1;M%z(=s*7n2CtmO;MHCXes=*w{TFbf|00Hd_!dJy z_TiVG`Y=p$3B%Vf;n(YzF*?BZz-5fE86LQb(ZTO=YvgC#8ohx#H%D;y_D$UT{Wk91 zy~E}=Jh=Y{9{hP9e?5GNv9U3XkB>j;wfw*TkNg8qIpAprJmY|89q=6Cy><;_*{qbb zqz|1Y@Q$C)6Pbby<0@KvGA8oYb~+OqNN88nvIzTDyvTcJ=Sjpy61oUlf?yGnU*clY z6e5fJs7Ib%kaIERO(L6wUS{`##Waxoy<%kms-OsuTOq?PC38P z^a2?dViR>$Z`i_XW&FbXWZa3(R8>!-5XgNx1qqQyRn6NJUTvn7Pr-{Q;9f-Gtwu^) zDfkeD)YOW3q9ClN;7e?ws?N<8-YMZehRi%-8&x&4-}UtH-^sPvm5d*;ox1(13Uvdw zg0O2YnfXMKy|r(PS;~!+P}uuN+ajcLAzermKkhBUx&>S;3?Y<{``yutcpnn7nAq_T rUtby*#9Q0Bl!#1BAmU@g1A>?Ej-SgN5bA)H4*0+UVGj7WKQn&=2N5!r literal 0 HcmV?d00001 diff --git a/doc/images/dolibarr_logo.jpg b/doc/images/dolibarr_logo.jpg index 69de0129523f551ae32ce2e5c8122c8873b36880..a4a0611067d1c58945f76c097b0b3e4bd3311426 100644 GIT binary patch literal 18776 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 C&ZV0G literal 23963 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 TvjmVYoIxqbs7TjHehdCT65RR{ literal 25554 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%0DyqSXw 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 diff --git a/doc/images/dolibarr_logo.svg b/doc/images/dolibarr_logo.svg new file mode 100644 index 00000000000..9c9259d0b33 --- /dev/null +++ b/doc/images/dolibarr_logo.svg @@ -0,0 +1,209 @@ + + + + + Logo Dolibarr ERP-CRM + + + + + + + + + + + + + + + image/svg+xml + + Logo Dolibarr ERP-CRM + + + + Laurent Destailleur + + + + + Laurent Destailleur + + + + + + + + + + + + + + + + + + + + + + + + + + + ERP/CRM + + + From c6c12e7d7a85fe67436f6aac239c123d88b7692e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 13:21:28 +0200 Subject: [PATCH 22/35] Add picto --- doc/images/dolibarr_512x512_color.png | Bin 0 -> 10576 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/images/dolibarr_512x512_color.png diff --git a/doc/images/dolibarr_512x512_color.png b/doc/images/dolibarr_512x512_color.png new file mode 100644 index 0000000000000000000000000000000000000000..a1766d07fe31f99d0d9d96e435ff2a4983886002 GIT binary patch literal 10576 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 x{`yb@eqAP1bZEJgFX{{><_*BSr- literal 0 HcmV?d00001 From e223189507a74d268ce4ab19e9e68855f7403765 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 14:20:04 +0200 Subject: [PATCH 23/35] FIX #14002 --- htdocs/fichinter/list.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index fd45d2daecb..ef6b9241c8d 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -75,8 +75,6 @@ $pagenext = $page + 1; if (!$sortorder) $sortorder = "DESC"; if (!$sortfield) { - //if (empty($conf->global->FICHINTER_DISABLE_DETAILS)) $sortfield="fd.date"; - //else $sortfield = "f.ref"; } @@ -203,7 +201,7 @@ foreach ($arrayfields as $tmpkey => $tmpval) $sql = "SELECT"; $sql .= " f.ref, f.rowid, f.fk_statut, f.description, f.datec as date_creation, f.tms as date_update, f.note_private,"; -if (empty($conf->global->FICHINTER_DISABLE_DETAILS) && $atleastonefieldinlines) $sql .= "fd.rowid as lineid, fd.description as descriptiondetail, fd.date as dp, fd.duree,"; +if (empty($conf->global->FICHINTER_DISABLE_DETAILS) && $atleastonefieldinlines) $sql .= " fd.rowid as lineid, fd.description as descriptiondetail, fd.date as dp, fd.duree,"; $sql .= " s.nom as name, s.rowid as socid, s.client"; if (!empty($conf->projet->enabled)) { $sql .= ", pr.rowid as projet_id, pr.ref as projet_ref, pr.title as projet_title"; @@ -245,7 +243,7 @@ if ($search_contrat_ref) { $sql .= natural_search('c.ref', $search_contrat_ref); } if ($search_desc) { - if (empty($conf->global->FICHINTER_DISABLE_DETAILS)) $sql .= natural_search(array('f.description', 'fd.description'), $search_desc); + if (empty($conf->global->FICHINTER_DISABLE_DETAILS) && $atleastonefieldinlines) $sql .= natural_search(array('f.description', 'fd.description'), $search_desc); else $sql .= natural_search(array('f.description'), $search_desc); } if ($search_status != '' && $search_status >= 0) { From e8016a5e7eef6cb4d7c373eb85229dcf9a810490 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 23:46:14 +0200 Subject: [PATCH 24/35] Fix credit-transfer vs direct debit --- htdocs/compta/paymentbybanktransfer/index.php | 4 +- .../class/bonprelevement.class.php | 43 ++++++++++++++----- htdocs/compta/prelevement/create.php | 4 +- htdocs/compta/prelevement/index.php | 4 +- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/htdocs/compta/paymentbybanktransfer/index.php b/htdocs/compta/paymentbybanktransfer/index.php index 18a24245071..cefb55f2f42 100644 --- a/htdocs/compta/paymentbybanktransfer/index.php +++ b/htdocs/compta/paymentbybanktransfer/index.php @@ -78,13 +78,13 @@ print ''.$langs->trans("Statistics").''.$langs->trans("NbOfInvoiceToPayByBankTransfer").''; print ''; print ''; -print $bprev->NbFactureAPrelever(); +print $bprev->nbOfInvoiceToPay('credit-transfer'); print ''; print ''; print ''.$langs->trans("AmountToWithdraw").''; print ''; -print price($bprev->SommeAPrelever(), '', '', 1, -1, -1, 'auto'); +print price($bprev->SommeAPrelever('credit-transfer'), '', '', 1, -1, -1, 'auto'); print '
'; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 62188f1c7fc..a923f66c699 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -687,17 +687,21 @@ class BonPrelevement extends CommonObject /** * Returns amount of withdrawal * - * @return double Total amount + * @param string $mode 'direct-debit' or 'credit-transfer' + * @return double db->error()); + + return -1; } } + /** + * Get number of invoices waiting for payment + * + * @param string $mode 'direct-debit' or 'credit-transfer' + * @return int NbFactureAPrelever($mode); + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Get number of invoices to withdrawal - * TODO delete params banque and agence when not necesary * - * @param int $banque dolibarr mysoc bank - * @param int $agence dolibarr mysoc agence + * @param string $mode 'direct-debit' or 'credit-transfer' * @return int global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS)) { $sql .= " AND f.fk_statut = ".Facture::STATUS_VALIDATED; } - $sql .= " AND f.rowid = pfd.fk_facture"; + if ($mode == 'credit-transfer') { + $sql .= " AND f.rowid = pfd.fk_facture_fourn"; + } else { + $sql .= " AND f.rowid = pfd.fk_facture"; + } $sql .= " AND pfd.traite = 0"; $sql .= " AND f.total_ttc > 0"; diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 06ae8f7c794..d94864e8358 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -142,10 +142,8 @@ print load_fiche_titre($title); dol_fiche_head(); $nb = $bprev->NbFactureAPrelever(); -$nb1 = $bprev->NbFactureAPrelever(1); -$nb11 = $bprev->NbFactureAPrelever(1, 1); $pricetowithdraw = $bprev->SommeAPrelever(); -if ($nb < 0 || $nb1 < 0 || $nb11 < 0) +if ($nb < 0) { dol_print_error($bprev->error); } diff --git a/htdocs/compta/prelevement/index.php b/htdocs/compta/prelevement/index.php index 5e1905e3a59..eaec6d92f16 100644 --- a/htdocs/compta/prelevement/index.php +++ b/htdocs/compta/prelevement/index.php @@ -78,13 +78,13 @@ print ''.$langs->trans("Statistics").''.$langs->trans("NbOfInvoiceToWithdraw").''; print ''; print ''; -print $bprev->NbFactureAPrelever(); +print $bprev->nbOfInvoiceToPay('direct-debit'); print ''; print ''; print ''.$langs->trans("AmountToWithdraw").''; print ''; -print price($bprev->SommeAPrelever(), '', '', 1, -1, -1, 'auto'); +print price($bprev->SommeAPrelever('direct-debit'), '', '', 1, -1, -1, 'auto'); print '
'; From ddebe1bbbaca89a27f7ae1f48471a490648817a0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 May 2020 23:51:02 +0200 Subject: [PATCH 25/35] FIX Missing ref into popup --- htdocs/comm/action/index.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index b480586bc6a..55e587a050d 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -608,7 +608,9 @@ if ($resql) // Create a new object action $event = new ActionComm($db); + $event->id = $obj->id; + $event->ref = $event->id; $event->datep = $db->jdate($obj->datep); // datep and datef are GMT date. Example: 1970-01-01 01:00:00, jdate will return 0 if TZ of PHP server is Europe/Berlin $event->datef = $db->jdate($obj->datep2); @@ -718,7 +720,10 @@ if ($showbirthday) { $obj = $db->fetch_object($resql); $event = new ActionComm($db); + $event->id = $obj->rowid; // We put contact id in action id for birthdays events + $event->ref = $event->id; + $datebirth = dol_stringtotime($obj->birthday, 1); //print 'ee'.$obj->birthday.'-'.$datebirth; $datearray = dol_getdate($datebirth, true); @@ -796,6 +801,7 @@ if ($conf->global->AGENDA_SHOW_HOLIDAYS) // Need the id of the leave object for link to it $event->id = $obj->rowid; + $event->ref = $event->id; $event->type_code = 'HOLIDAY'; $event->datep = dol_mktime(0, 0, 0, $dateStartArray['mon'], $dateStartArray['mday'], $dateStartArray['year'], true); @@ -1036,6 +1042,8 @@ if (count($listofextcals)) if ($addevent) { $event->id = $icalevent['UID']; + $event->ref = $event->id; + $event->icalname = $namecal; $event->icalcolor = $colorcal; $usertime = 0; // We dont modify date because we want to have date into memory datep and datef stored as GMT date. Compensation will be done during output. From 94e02269eef18973e448fca90609be98e81a8f32 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 May 2020 00:20:01 +0200 Subject: [PATCH 26/35] Fix: missing fk_project --- htdocs/comm/action/index.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 55e587a050d..40fbcab737b 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -7,7 +7,7 @@ * Copyright (C) 2014 Cedric GROSS * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Open-DSI - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -493,7 +493,7 @@ $sql .= ' a.datep2,'; $sql .= ' a.percent,'; $sql .= ' a.fk_user_author,a.fk_user_action,'; $sql .= ' a.transparency, a.priority, a.fulldayevent, a.location,'; -$sql .= ' a.fk_soc, a.fk_contact,'; +$sql .= ' a.fk_soc, a.fk_contact, a.fk_project,'; $sql .= ' a.fk_element, a.elementtype,'; $sql .= ' ca.code as type_code, ca.libelle as type_label, ca.color as type_color'; $sql .= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; @@ -634,6 +634,8 @@ if ($resql) $event->fk_element = $obj->fk_element; $event->elementtype = $obj->elementtype; + $event->fk_project = $obj->fk_project; + $event->thirdparty_id = $obj->fk_soc; $event->contact_id = $obj->fk_contact; @@ -1634,7 +1636,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa // Hour start if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) { - $daterange .= dol_print_date($event->date_start_in_calendar, '%H:%M'); // Il faudrait utiliser ici tzuser, mais si on ne peut pas car qd on rentre un date dans fiche action, en input la conversion local->gmt se base sur le TZ server et non user + $daterange .= dol_print_date($event->date_start_in_calendar, 'hour'); // Il faudrait utiliser ici tzuser, mais si on ne peut pas car qd on rentre un date dans fiche action, en input la conversion local->gmt se base sur le TZ server et non user if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) @@ -1654,7 +1656,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) - $daterange .= dol_print_date($event->date_end_in_calendar, '%H:%M'); // Il faudrait utiliser ici tzuser, mais si on ne peut pas car qd on rentre un date dans fiche action, en input la conversion local->gmt se base sur le TZ server et non user + $daterange .= dol_print_date($event->date_end_in_calendar, 'hour'); // Il faudrait utiliser ici tzuser, mais si on ne peut pas car qd on rentre un date dans fiche action, en input la conversion local->gmt se base sur le TZ server et non user } } else From 8b03a5e225c03f168dddeabe5e4ce48e9ebf7724 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 May 2020 00:22:17 +0200 Subject: [PATCH 27/35] Fix phpcs --- htdocs/imports/emptyexample.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/imports/emptyexample.php b/htdocs/imports/emptyexample.php index 0fa532a6e1b..9c5d8c12a0d 100644 --- a/htdocs/imports/emptyexample.php +++ b/htdocs/imports/emptyexample.php @@ -21,7 +21,7 @@ * \brief Show example of import file */ -if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) /** From c04903d15cf326d81392e6d0005a9c5388e4f72d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 May 2020 22:59:33 +0200 Subject: [PATCH 28/35] Fix debug modulebuilder for doc and ref generation Conflicts: htdocs/core/class/commonobject.class.php --- htdocs/core/class/commonobject.class.php | 17 +- htdocs/langs/en_US/admin.lang | 1 + htdocs/modulebuilder/index.php | 9 +- htdocs/modulebuilder/template/admin/setup.php | 371 +++++ .../doc/doc_generic_myobject_odt.modules.php | 2 +- .../doc/pdf_standard_myobject.modules.php | 1483 +++++++++++++++++ .../modules/mymodule/modules_myobject.php | 3 +- 7 files changed, 1873 insertions(+), 13 deletions(-) create mode 100644 htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index a6b96ef3b4d..fd5e70c3669 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4744,7 +4744,7 @@ abstract class CommonObject // Search template files $file = ''; $classname = ''; - $filefound = 0; + $filefound = ''; $dirmodels = array('/'); if (is_array($conf->modules_parts['models'])) $dirmodels = array_merge($dirmodels, $conf->modules_parts['models']); foreach ($dirmodels as $reldir) @@ -4758,7 +4758,7 @@ abstract class CommonObject $file = dol_buildpath($reldir.$modelspath.$file, 0); if (file_exists($file)) { - $filefound = 1; + $filefound = $file; $classname = $prefix.'_'.$modele; break; } @@ -4962,11 +4962,14 @@ abstract class CommonObject dol_print_error($this->db, "Error generating document for ".__CLASS__.". Error: ".$obj->error, $obj->errors); return -1; } - } - else - { - $this->error = $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists", $file); - dol_print_error('', $this->error); + } else { + if (! $filefound) { + $this->error = $langs->trans("Error").' Failed to load doc generator with modelpaths='.$modelspath.' - modele='.$modele; + dol_print_error('', $this->error); + } else { + $this->error = $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists", $filefound); + dol_print_error('', $this->error); + } return -1; } } diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 3d7407820a5..a7fa6d2aa55 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1264,6 +1264,7 @@ FieldEdition=Edition of field %s FillThisOnlyIfRequired=Example: +2 (fill only if timezone offset problems are experienced) GetBarCode=Get barcode NumberingModules=Numbering models +DocumentModules=Document models ##### Module password generation PasswordGenerationStandard=Return a password generated according to internal Dolibarr algorithm: 8 characters containing shared numbers and characters in lowercase. PasswordGenerationNone=Do not suggest a generated password. Password must be typed in manually. diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 3c118395e6b..1bb1c934aa4 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -871,7 +871,8 @@ if ($dirins && $action == 'initobject' && $module && $objectname) dol_mkdir($destdir.'/core/modules/'.strtolower($module).'/doc'); $filetogenerate += array( - 'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php'=>'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php' + 'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php'=>'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php', + 'core/modules/mymodule/doc/pdf_standard_myobject.modules.php'=>'core/modules/'.strtolower($module).'/doc/pdf_standard_'.strtolower($objectname).'.modules.php' ); } @@ -1281,13 +1282,15 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname) 'core/modules/mymodule/mod_myobject_advanced.php'=>'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_advanced.php', 'core/modules/mymodule/mod_myobject_standard.php'=>'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_standard.php', 'core/modules/mymodule/modules_myobject.php'=>'core/modules/'.strtolower($module).'/modules_'.strtolower($objectname).'.php', - 'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php'=>'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php' + 'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php'=>'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php', + 'core/modules/mymodule/doc/pdf_standard_myobject.modules.php'=>'core/modules/'.strtolower($module).'/doc/pdf_standard_'.strtolower($objectname).'.modules.php' ); $resultko = 0; foreach ($filetodelete as $filetodelete) { $resulttmp = dol_delete_file($dir.'/'.$filetodelete, 0, 0, 1); + $resulttmp = dol_delete_file($dir.'/'.$filetodelete.'.back', 0, 0, 1); if (!$resulttmp) $resultko++; } @@ -2567,7 +2570,7 @@ elseif (!empty($module)) //$propstat = $reflector->getStaticProperties(); //var_dump($reflectorpropdefault); - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 05b2c56ffb8..0d464aab90d 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -53,11 +53,14 @@ if (!$user->admin) accessforbidden(); $action = GETPOST('action', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); +$value = GETPOST('value', 'alpha'); + $arrayofparameters = array( 'MYMODULE_MYPARAM1'=>array('css'=>'minwidth200', 'enabled'=>1), 'MYMODULE_MYPARAM2'=>array('css'=>'minwidth500', 'enabled'=>1) ); +$error = 0; /* @@ -69,12 +72,116 @@ if ((float) DOL_VERSION >= 6) include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; } +if ($action == 'updateMask') +{ + $maskconstorder = GETPOST('maskconstorder', 'alpha'); + $maskorder = GETPOST('maskorder', 'alpha'); + + if ($maskconstorder) $res = dolibarr_set_const($db, $maskconstorder, $maskorder, 'chaine', 0, '', $conf->entity); + + if (!$res > 0) $error++; + + if (!$error) + { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} elseif ($action == 'specimen') +{ + $modele = GETPOST('module', 'alpha'); + $tmpobjectkey = GETPOST('object'); + + $tmpobject = new $tmpobjectkey($db); + $tmpobject->initAsSpecimen(); + + // Search template files + $file = ''; $classname = ''; $filefound = 0; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $file = dol_buildpath($reldir."core/modules/mymodule/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0); + if (file_exists($file)) + { + $filefound = 1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) + { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($tmpobject, $langs) > 0) + { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); + return; + } else { + setEventMessages($module->error, null, 'errors'); + dol_syslog($module->error, LOG_ERR); + } + } else { + setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} + +// Activate a model +elseif ($action == 'set') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); +} elseif ($action == 'del') +{ + $tmpobjectkey = GETPOST('object'); + + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; + if ($conf->global->$constforval == "$value") dolibarr_del_const($db, $constforval, $conf->entity); + } +} + +// Set default model +elseif ($action == 'setdoc') +{ + $tmpobjectkey = GETPOST('object'); + $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; + if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity)) + { + // The constant that was read before the new set + // We therefore requires a variable to have a coherent view + $conf->global->$constforval = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } +} elseif ($action == 'setmod') +{ + // TODO Check if numbering module chosen can be activated + // by calling method canBeActivated + $tmpobjectkey = GETPOST('object'); + + dolibarr_set_const($db, strtoupper($tmpobjectkey)."_ADDON", $value, 'chaine', 0, '', $conf->entity); +} + /* * View */ +$form = new Form($db); + +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + $page_name = "MyModuleSetup"; llxHeader('', $langs->trans($page_name)); @@ -144,6 +251,270 @@ else } +$moduledir = 'mymodule'; +$myTmpObjects = array(); +$myTmpObjects['MyObject']=array('includerefgeneration'=>0, 'includedocgeneration'=>0); + + + +foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { + if ($myTmpObjectArray['includerefgeneration']) { + /* + * Orders Numbering model + */ + + print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', ''); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/".$moduledir); + + if (is_dir($dir)) + { + $handle = opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle)) !== false) + { + if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') + { + $file = substr($file, 0, dol_strlen($file) - 4); + + require_once $dir.'/'.$file.'.php'; + + $module = new $file($db); + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + if ($module->isEnabled()) + { + dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php'); + + print ''; + + // Show example of numbering model + print ''."\n"; + + print ''; + + $mytmpinstance = new $myTmpObjectKey($db); + $mytmpinstance->initAsSpecimen(); + + // Info + $htmltooltip = ''; + $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; + + $nextval = $module->getNextValue($mytmpinstance); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip .= ''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') + $nextval = $langs->trans($nextval); + $htmltooltip .= $nextval.'
'; + } else { + $htmltooltip .= $langs->trans($module->error).'
'; + } + } + + print ''; + + print "\n"; + } + } + } + closedir($handle); + } + } + } + print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; + print $module->info(); + print ''; + $tmp = $module->getExample(); + if (preg_match('/^Error/', $tmp)) print '
'.$langs->trans($tmp).'
'; + elseif ($tmp == 'NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON'; + if ($conf->global->$constforvar == $file) + { + print img_picto($langs->trans("Activated"), 'switch_on'); + } else { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print '

\n"; + } + + + if ($myTmpObjectArray['includedocgeneration']) { + /* + * Document templates generators + */ + $type = strtolower($myTmpObjectKey); + + print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', ''); + + // Load array def with activated templates + $def = array(); + $sql = "SELECT nom"; + $sql .= " FROM ".MAIN_DB_PREFIX."document_model"; + $sql .= " WHERE type = '".$type."'"; + $sql .= " AND entity = ".$conf->entity; + $resql = $db->query($sql); + if ($resql) + { + $i = 0; + $num_rows = $db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } + } else { + dol_print_error($db); + } + + + print "\n"; + print "\n"; + print ''; + print ''; + print '\n"; + print '\n"; + print ''; + print ''; + print "\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) + { + foreach (array('', '/doc') as $valdir) + { + $realpath = $reldir."core/modules/".$moduledir.$valdir; + $dir = dol_buildpath($realpath); + + if (is_dir($dir)) + { + $handle = opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle)) !== false) + { + $filelist[] = $file; + } + closedir($handle); + arsort($filelist); + + foreach ($filelist as $file) + { + if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) + { + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) - 16); + $classname = substr($file, 0, dol_strlen($file) - 12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified = 1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified = 0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0; + + if ($modulequalified) + { + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } else { + print '"; + } + + // Default + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip .= '
'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip .= '
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip .= '
'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file; + + $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); + $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } + } + + print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name) ? $name : $module->name); + print "\n"; + if (method_exists($module, 'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"), 'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print "'; + $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON'; + if ($conf->global->$constforvar == $name) + { + print img_picto($langs->trans("Default"), 'on'); + } else { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"), 'generic').''; + } else { + print img_object($langs->trans("PreviewNotAvailable"), 'generic'); + } + print '
'; + } +} + + // Page end dol_fiche_end(); diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php index 98c2c94bc7b..d8b836a6593 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php @@ -27,7 +27,7 @@ * \brief File of class to build ODT documents for myobjects */ -require_once DOL_DOCUMENT_ROOT.'/core/modules/myobject/modules_myobject.php'; +dol_include_once('/mymodule/core/modules/mymodule/modules_myobject.php'); require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php new file mode 100644 index 00000000000..1d08e857e96 --- /dev/null +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php @@ -0,0 +1,1483 @@ + + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2014 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard.modules.php + * \ingroup mymodule + * \brief File of class to generate document from standard template + */ + +dol_include_once('/mymodule/core/modules/mymodule/modules_myobject.php'); +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; + + +/** + * Class to manage PDF template standard_myobject + */ +class pdf_standard_myobject extends ModelePDFMyObject +{ + /** + * @var DoliDb Database handler + */ + public $db; + + /** + * @var string model name + */ + public $name; + + /** + * @var string model description (short text) + */ + public $description; + + /** + * @var int Save the name of generated file as the main doc when generating a doc with this template + */ + public $update_main_doc_field; + + /** + * @var string document type + */ + public $type; + + /** + * @var array Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.5 = array(5, 5) + */ + public $phpmin = array(5, 5); + + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; + + /** + * @var int page_largeur + */ + public $page_largeur; + + /** + * @var int page_hauteur + */ + public $page_hauteur; + + /** + * @var array format + */ + public $format; + + /** + * @var int marge_gauche + */ + public $marge_gauche; + + /** + * @var int marge_droite + */ + public $marge_droite; + + /** + * @var int marge_haute + */ + public $marge_haute; + + /** + * @var int marge_basse + */ + public $marge_basse; + + /** + * Issuer + * @var Societe Object that emits + */ + public $emetteur; + + /** + * @var bool Situation invoice type + */ + public $situationinvoice; + + + /** + * @var array of document table collumns + */ + public $cols; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf, $langs, $mysoc; + + // Translations + $langs->loadLangs(array("main", "bills")); + + $this->db = $db; + $this->name = "standard"; + $this->description = $langs->trans('PDFStandardDescription'); + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + + // Dimension page + $this->type = 'pdf'; + $formatarray = pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur, $this->page_hauteur); + $this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10; + $this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10; + $this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10; + $this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10; + + $this->option_logo = 1; // Display logo + $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION + $this->option_modereg = 1; // Display payment mode + $this->option_condreg = 1; // Display payment terms + $this->option_codeproduitservice = 1; // Display product-service code + $this->option_multilang = 1; // Available in several languages + $this->option_escompte = 1; // Displays if there has been a discount + $this->option_credit_note = 1; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 1; // Support add of a watermark on drafts + + // Get source company + $this->emetteur = $mysoc; + if (empty($this->emetteur->country_code)) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined + + // Define position of columns + $this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff + + + $this->tabTitleHeight = 5; // default height + + // Use new system for position of columns, view $this->defineColumnField() + + $this->tva = array(); + $this->localtax1 = array(); + $this->localtax2 = array(); + $this->atleastoneratenotnull = 0; + $this->atleastonediscount = 0; + $this->situationinvoice = false; + } + + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Function to build pdf onto disk + * + * @param Object $object Object to generate + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO + */ + public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + // phpcs:enable + global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines; + + dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null')); + + if (!is_object($outputlangs)) $outputlangs = $langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (!empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output = 'ISO-8859-1'; + + // Load translation files required by the page + $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies")); + + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) { + global $outputlangsbis; + $outputlangsbis = new Translate('', $conf); + $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE); + $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies")); + } + + $nblines = count($object->lines); + + $hidetop = 0; + if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) { + $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE; + } + + // Loop on each lines to detect if there is at least one image to show + $realpatharray = array(); + $this->atleastonephoto = false; + /* + if (!empty($conf->global->MAIN_GENERATE_MYOBJECT_WITH_PICTURE)) + { + $objphoto = new Product($this->db); + + for ($i = 0; $i < $nblines; $i++) + { + if (empty($object->lines[$i]->fk_product)) continue; + + $objphoto->fetch($object->lines[$i]->fk_product); + //var_dump($objphoto->ref);exit; + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { + $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; + $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; + } else { + $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default + $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative + } + + $arephoto = false; + foreach ($pdir as $midir) + { + if (!$arephoto) + { + $dir = $conf->product->dir_output.'/'.$midir; + + foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) + { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + { + if ($obj['photo_vignette']) + { + $filename = $obj['photo_vignette']; + } else { + $filename = $obj['photo']; + } + } else { + $filename = $obj['photo']; + } + + $realpath = $dir.$filename; + $arephoto = true; + $this->atleastonephoto = true; + } + } + } + + if ($realpath && $arephoto) $realpatharray[$i] = $realpath; + } + } + */ + + //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva; + + if ($conf->mymodule->dir_output.'/myobject') + { + $object->fetch_thirdparty(); + + $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); + $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); + $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); + + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->mymodule->dir_output.'/myobject'; + $file = $dir."/SPECIMEN.pdf"; + } else { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->mymodule->dir_output.'/myobject/'.$objectref; + $file = $dir."/".$objectref.".pdf"; + } + if (!file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Add pdfgeneration hook + if (!is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + + // Set nblines with the new facture lines content after hook + $nblines = count($object->lines); + + // Create pdf instance + $pdf = pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance + $pdf->SetAutoPageBreak(1, 0); + + $heightforinfotot = 50; // Height reserved to output the info and total part and payment part + $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin) + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + + // Set path to the background PDF File + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb = 0; + $pdf->SetDrawColor(128, 128, 128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + // Set certificate + $cert = empty($user->conf->CERTIFICATE_CRT) ? '' : $user->conf->CERTIFICATE_CRT; + // If user has no certificate, we try to take the company one + if (!$cert) { + $cert = empty($conf->global->CERTIFICATE_CRT) ? '' : $conf->global->CERTIFICATE_CRT; + } + // If a certificate is found + if ($cert) { + $info = array( + 'Name' => $this->emetteur->name, + 'Location' => getCountry($this->emetteur->country_code, 0), + 'Reason' => 'MYOBJECT', + 'ContactInfo' => $this->emetteur->email + ); + $pdf->setSignature($cert, $cert, $this->emetteur->name, '', 2, $info); + } + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + // New page + $pdf->AddPage(); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + + $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0, 0, 0); + + $tab_top = 90 + $top_shift; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10); + $tab_height = 130 - $top_shift; + $tab_height_newpage = 150; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift; + + $nexY = $tab_top - 1; + + // Display notes + $notetoshow = empty($object->note_public) ? '' : $object->note_public; + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + + $pagenb = $pdf->getPage(); + if ($notetoshow) + { + $tab_top -= 2; + + $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite; + $pageposbeforenote = $pagenb; + + $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs); + $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow); + + $pdf->startTransaction(); + + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + // Description + $pageposafternote = $pdf->getPage(); + $posyafter = $pdf->GetY(); + + if ($pageposafternote > $pageposbeforenote) + { + $pdf->rollbackTransaction(true); + + // prepare pages to receive notes + while ($pagenb < $pageposafternote) { + $pdf->AddPage(); + $pagenb++; + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + // $this->_pagefoot($pdf,$object,$outputlangs,1); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + } + + // back to start + $pdf->setPage($pageposbeforenote); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + $pageposafternote = $pdf->getPage(); + + $posyafter = $pdf->GetY(); + + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) // There is no space left for total+free text + { + $pdf->AddPage('', '', true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + //$posyafter = $tab_top_newpage; + } + + + // apply note frame to previous pages + $i = $pageposbeforenote; + while ($i < $pageposafternote) { + $pdf->setPage($i); + + + $pdf->SetDrawColor(128, 128, 128); + // Draw note frame + if ($i > $pageposbeforenote) { + $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); + } else { + $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); + } + + // Add footer + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $this->_pagefoot($pdf, $object, $outputlangs, 1); + + $i++; + } + + // apply note frame to last page + $pdf->setPage($pageposafternote); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $height_note = $posyafter - $tab_top_newpage; + $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); + } else // No pagebreak + { + $pdf->commitTransaction(); + $posyafter = $pdf->GetY(); + $height_note = $posyafter - $tab_top; + $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); + + + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) + { + // not enough space, need to add page + $pdf->AddPage('', '', true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + + $posyafter = $tab_top_newpage; + } + } + + $tab_height = $tab_height - $height_note; + $tab_top = $posyafter + 6; + } else { + $height_note = 0; + } + + // Use new auto column system + $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref); + + // Table simulation to know the height of the title line + $pdf->startTransaction(); + $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop); + $pdf->rollbackTransaction(true); + + $nexY = $tab_top + $this->tabTitleHeight; + + // Loop on each lines + $pageposbeforeprintlines = $pdf->getPage(); + $pagenb = $pageposbeforeprintlines; + for ($i = 0; $i < $nblines; $i++) + { + $curY = $nexY; + $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0, 0, 0); + + // Define size of image if we need it + $imglinesize = array(); + if (!empty($realpatharray[$i])) $imglinesize = pdf_getSizeForImage($realpatharray[$i]); + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore = $pdf->getPage(); + + $showpricebeforepagebreak = 1; + $posYAfterImage = 0; + + if ($this->getColumnStatus('photo')) + { + // We start with Photo of product line + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page + { + $pdf->AddPage('', '', true); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pdf->setPage($pageposbefore + 1); + + $curY = $tab_top_newpage; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else $showpricebeforepagebreak = 0; + } + + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) + { + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + // $pdf->Image does not increase value return by getY, so we save it manually + $posYAfterImage = $curY + $imglinesize['height']; + } + } + + // Description of product line + if ($this->getColumnStatus('desc')) + { + $pdf->startTransaction(); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); + $pageposafter = $pdf->getPage(); + + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); + + $pageposafter = $pdf->getPage(); + $posyafter = $pdf->GetY(); + //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page + { + $pdf->AddPage('', '', true); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pdf->setPage($pageposafter + 1); + } + } else { + // We found a page break + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else $showpricebeforepagebreak = 0; + } + } else // No pagebreak + { + $pdf->commitTransaction(); + } + } + + $nexY = $pdf->GetY(); + $pageposafter = $pdf->getPage(); + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description or photo were moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut + + // VAT Rate + if ($this->getColumnStatus('vat')) + { + $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); + $nexY = max($pdf->GetY(), $nexY); + } + + // Unit price before discount + if ($this->getColumnStatus('subprice')) + { + $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax); + $nexY = max($pdf->GetY(), $nexY); + } + + // Quantity + // Enough for 6 chars + if ($this->getColumnStatus('qty')) + { + $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'qty', $qty); + $nexY = max($pdf->GetY(), $nexY); + } + + // Situation progress + if ($this->getColumnStatus('progress')) + { + $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'progress', $progress); + $nexY = max($pdf->GetY(), $nexY); + } + + // Unit + if ($this->getColumnStatus('unit')) + { + $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); + $this->printStdColumnContent($pdf, $curY, 'unit', $unit); + $nexY = max($pdf->GetY(), $nexY); + } + + // Discount on line + if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) + { + $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); + $nexY = max($pdf->GetY(), $nexY); + } + + // Total HT line + if ($this->getColumnStatus('totalexcltax')) + { + $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax); + $nexY = max($pdf->GetY(), $nexY); + } + + // Extrafields + if (!empty($object->lines[$i]->array_options)) { + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) { + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } + + + $parameters = array( + 'object' => $object, + 'i' => $i, + 'pdf' =>& $pdf, + 'curY' =>& $curY, + 'nexY' =>& $nexY, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails + ); + $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook + + + $sign = 1; + if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign = -1; + // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva + $prev_progress = $object->lines[$i]->get_prev_progress($object->id); + if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) // Compute progress from previous situation + { + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent; + else $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent; + } else { + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva; + else $tvaligne = $sign * $object->lines[$i]->total_tva; + } + + $localtax1ligne = $object->lines[$i]->total_localtax1; + $localtax2ligne = $object->lines[$i]->total_localtax2; + $localtax1_rate = $object->lines[$i]->localtax1_tx; + $localtax2_rate = $object->lines[$i]->localtax2_tx; + $localtax1_type = $object->lines[$i]->localtax1_type; + $localtax2_type = $object->lines[$i]->localtax2_type; + + if ($object->remise_percent) $tvaligne -= ($tvaligne * $object->remise_percent) / 100; + if ($object->remise_percent) $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100; + if ($object->remise_percent) $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100; + + $vatrate = (string) $object->lines[$i]->tva_tx; + + // Retrieve type from database for backward compatibility with old records + if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined + && (!empty($localtax1_rate) || !empty($localtax2_rate))) // and there is local tax + { + $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); + $localtax1_type = $localtaxtmp_array[0]; + $localtax2_type = $localtaxtmp_array[2]; + } + + // retrieve global local tax + if ($localtax1_type && $localtax1ligne != 0) { + $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne; + } + if ($localtax2_type && $localtax2ligne != 0) { + $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne; + } + + if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate .= '*'; + if (!isset($this->tva[$vatrate])) $this->tva[$vatrate] = 0; + $this->tva[$vatrate] += $tvaligne; + + $nexY = max($nexY, $posYAfterImage); + + // Add line + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); + $pdf->SetLineStyle(array('dash'=>0)); + } + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) { + $pdf->setPage($pagenb); + if ($pagenb == $pageposbeforeprintlines) { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); + } else { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); + } + $this->_pagefoot($pdf, $object, $outputlangs, 1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { + if ($pagenb == $pageposafter) { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); + } else { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); + } + $this->_pagefoot($pdf, $object, $outputlangs, 1); + // New page + $pdf->AddPage(); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + } + + // Show square + if ($pagenb == $pageposbeforeprintlines) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis); + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } else { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis); + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } + + // Display infos area + //$posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs); + + // Display total zone + //$posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); + + // Display payment area + /* + if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS)) + { + $posy = $this->drawPaymentsTable($pdf, $object, $posy, $outputlangs); + } + */ + + // Pagefoot + $this->_pagefoot($pdf, $object, $outputlangs); + if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file, 'F'); + + // Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) + { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + } + + if (!empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $this->result = array('fullpath'=>$file); + + return 1; // No error + } else { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + } else { + $this->error = $langs->transnoentities("ErrorConstantNotDefined", "FAC_OUTPUTDIR"); + return 0; + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + public static function liste_modeles($db, $maxfilenamelength = 0) + { + // phpcs:enable + return parent::liste_modeles($db, $maxfilenamelength); // TODO: Change the autogenerated stub + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show table for lines + * + * @param tcpdf $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y (not used) + * @param Translate $outputlangs Langs object + * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title + * @param int $hidebottom Hide bottom bar of array + * @param string $currency Currency code + * @param Translate $outputlangsbis Langs object bis + * @return void + */ + protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null) + { + global $conf; + + // Force to disable hidetop and hidebottom + $hidebottom = 0; + if ($hidetop) $hidetop = -1; + + $currency = !empty($currency) ? $currency : $conf->currency; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + + if (empty($hidetop)) + { + $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency)); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency)); + } + + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; + if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) { + $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)); + } + } + + $pdf->SetDrawColor(128, 128, 128); + $pdf->SetFont('', '', $default_font_size - 1); + + // Output Rect + $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter + + + $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop); + + if (empty($hidetop)) { + $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show top header of page. + * + * @param Tcpdf $pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @param Translate $outputlangsbis Object lang for output bis + * @return void + */ + protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null) + { + global $conf, $langs; + + // Load traductions files required by page + $outputlangs->loadLangs(array("main", "bills", "propal", "companies")); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); + + // Show Draft Watermark + if ($object->statut == Facture::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK))) + { + pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK); + } + + $pdf->SetTextColor(0, 0, 60); + $pdf->SetFont('', 'B', $default_font_size + 3); + + $w = 110; + + $posy = $this->marge_haute; + $posx = $this->page_largeur - $this->marge_droite - $w; + + $pdf->SetXY($this->marge_gauche, $posy); + + // Logo + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) + { + if ($this->emetteur->logo) + { + $logodir = $conf->mycompany->dir_output; + if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity]; + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) + { + $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; + } else { + $logo = $logodir.'/logos/'.$this->emetteur->logo; + } + if (is_readable($logo)) + { + $height = pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } else { + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } else { + $text = $this->emetteur->name; + $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + } + + $pdf->SetFont('', 'B', $default_font_size + 3); + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $title = $outputlangs->transnoentities("PdfInvoiceTitle"); + if ($object->type == 1) $title = $outputlangs->transnoentities("InvoiceReplacement"); + if ($object->type == 2) $title = $outputlangs->transnoentities("InvoiceAvoir"); + if ($object->type == 3) $title = $outputlangs->transnoentities("InvoiceDeposit"); + if ($object->type == 4) $title = $outputlangs->transnoentities("InvoiceProForma"); + if ($this->situationinvoice) $title = $outputlangs->transnoentities("InvoiceSituation"); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title .= ' - '; + if ($object->type == 0) { + if ($this->situationinvoice) $title .= $outputlangsbis->transnoentities("InvoiceSituation"); + $title .= $outputlangsbis->transnoentities("PdfInvoiceTitle"); + } elseif ($object->type == 1) $title .= $outputlangsbis->transnoentities("InvoiceReplacement"); + elseif ($object->type == 2) $title .= $outputlangsbis->transnoentities("InvoiceAvoir"); + elseif ($object->type == 3) $title .= $outputlangsbis->transnoentities("InvoiceDeposit"); + elseif ($object->type == 4) $title .= $outputlangsbis->transnoentities("InvoiceProForma"); + } + $pdf->MultiCell($w, 3, $title, '', 'R'); + + $pdf->SetFont('', 'B', $default_font_size); + + $posy += 5; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref); + if ($object->statut == Facture::STATUS_DRAFT) + { + $pdf->SetTextColor(128, 0, 0); + $textref .= ' - '.$outputlangs->transnoentities("NotValidated"); + } + $pdf->MultiCell($w, 4, $textref, '', 'R'); + + $posy += 1; + $pdf->SetFont('', '', $default_font_size - 2); + + if ($object->ref_client) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); + } + + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R'); + } + } + + if (!empty($conf->global->PDF_SHOW_PROJECT)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R'); + } + } + + $objectidnext = $object->getIdReplacingInvoice('validated'); + if ($object->type == 0 && $objectidnext) + { + $objectreplacing = new Facture($this->db); + $objectreplacing->fetch($objectidnext); + + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R'); + } + if ($object->type == 1) + { + $objectreplaced = new Facture($this->db); + $objectreplaced->fetch($object->fk_facture_source); + + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R'); + } + if ($object->type == 2 && !empty($object->fk_facture_source)) + { + $objectreplaced = new Facture($this->db); + $objectreplaced->fetch($object->fk_facture_source); + + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R'); + } + + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + + $title = $outputlangs->transnoentities("DateInvoice"); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title .= ' - '.$outputlangsbis->transnoentities("DateInvoice"); + } + $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date, "day", false, $outputlangs), '', 'R'); + + if (!empty($conf->global->INVOICE_POINTOFTAX_DATE)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : ".dol_print_date($object->date_pointoftax, "day", false, $outputlangs), '', 'R'); + } + + if ($object->type != 2) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $title = $outputlangs->transnoentities("DateDue"); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title .= ' - '.$outputlangsbis->transnoentities("DateDue"); + } + $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date_lim_reglement, "day", false, $outputlangs, true), '', 'R'); + } + + if ($object->thirdparty->code_client) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R'); + } + + // Get contact + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) + { + $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $usertmp = new User($this->db); + $usertmp->fetch($arrayidcontact[0]); + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R'); + } + } + + $posy += 1; + + $top_shift = 0; + // Show list of linked objects + $current_y = $pdf->getY(); + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size); + if ($current_y < $pdf->getY()) + { + $top_shift = $pdf->getY() - $current_y; + } + + if ($showaddress) + { + // Sender properties + $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); + + // Show sender + $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posy += $top_shift; + $posx = $this->marge_gauche; + if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->page_largeur - $this->marge_droite - 80; + + $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40; + $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82; + + + // Show sender frame + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posx, $posy - 5); + $pdf->MultiCell(66, 5, $outputlangs->transnoentities("BillFrom").":", 0, 'L'); + $pdf->SetXY($posx, $posy); + $pdf->SetFillColor(230, 230, 230); + $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0, 0, 60); + + // Show sender name + $pdf->SetXY($posx + 2, $posy + 3); + $pdf->SetFont('', 'B', $default_font_size); + $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + $posy = $pdf->getY(); + + // Show sender information + $pdf->SetXY($posx + 2, $posy); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L'); + + // If BILLING contact defined on invoice, we use it + $usecontact = false; + $arrayidcontact = $object->getIdContact('external', 'BILLING'); + if (count($arrayidcontact) > 0) + { + $usecontact = true; + $result = $object->fetch_contact($arrayidcontact[0]); + } + + //Recipient name + // On peut utiliser le nom de la societe du contact + if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) { + $thirdparty = $object->contact; + } else { + $thirdparty = $object->thirdparty; + } + + $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + + $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object); + + // Show recipient + $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100; + if ($this->page_largeur < 210) $widthrecbox = 84; // To work with US executive format + $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posy += $top_shift; + $posx = $this->page_largeur - $this->marge_droite - $widthrecbox; + if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->marge_gauche; + + // Show recipient frame + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posx + 2, $posy - 5); + $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L'); + $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); + + // Show recipient name + $pdf->SetXY($posx + 2, $posy + 3); + $pdf->SetFont('', 'B', $default_font_size); + $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); + + // Show recipient information + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->SetXY($posx + 2, $posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + } + + $pdf->SetTextColor(0, 0, 0); + return $top_shift; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show footer of page. Need this->emetteur object + * + * @param PDF $pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0) + { + global $conf; + $showdetails = $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf, $outputlangs, 'INVOICE_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext); + } + + /** + * Define Array Column Field + * + * @param object $object common object + * @param Translate $outputlangs langs + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return null + */ + public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + global $conf, $hookmanager; + + // Default field style for content + $this->defaultContentsFieldsStyle = array( + 'align' => 'R', // R,C,L + 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + // Default field style for content + $this->defaultTitlesFieldsStyle = array( + 'align' => 'C', // R,C,L + 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + /* + * For exemple + $this->cols['theColKey'] = array( + 'rank' => $rank, // int : use for ordering columns + 'width' => 20, // the column width in mm + 'title' => array( + 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + 'label' => ' ', // the final label : used fore final generated text + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + */ + + $rank = 0; // do not use negative rank + $this->cols['desc'] = array( + 'rank' => $rank, + 'width' => false, // only for desc + 'status' => true, + 'title' => array( + 'textkey' => 'Designation', // use lang key is usefull in somme case with module + 'align' => 'L', + // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + // 'label' => ' ', // the final label + 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', + 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + + // PHOTO + $rank = $rank + 10; + $this->cols['photo'] = array( + 'rank' => $rank, + 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Photo', + 'label' => ' ' + ), + 'content' => array( + 'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'border-left' => false, // remove left line separator + ); + + if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto)) + { + $this->cols['photo']['status'] = true; + } + + + $rank = $rank + 10; + $this->cols['vat'] = array( + 'rank' => $rank, + 'status' => false, + 'width' => 16, // in mm + 'title' => array( + 'textkey' => 'VAT' + ), + 'border-left' => true, // add left line separator + ); + + if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) + { + $this->cols['vat']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['subprice'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'PriceUHT' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['qty'] = array( + 'rank' => $rank, + 'width' => 16, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'Qty' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['progress'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Progress' + ), + 'border-left' => true, // add left line separator + ); + + if ($this->situationinvoice) + { + $this->cols['progress']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['unit'] = array( + 'rank' => $rank, + 'width' => 11, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Unit' + ), + 'border-left' => true, // add left line separator + ); + if ($conf->global->PRODUCT_USE_UNITS) { + $this->cols['unit']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['discount'] = array( + 'rank' => $rank, + 'width' => 13, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'ReductionShort' + ), + 'border-left' => true, // add left line separator + ); + if ($this->atleastonediscount) { + $this->cols['discount']['status'] = true; + } + + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 + $this->cols['totalexcltax'] = array( + 'rank' => $rank, + 'width' => 26, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'TotalHT' + ), + 'border-left' => true, // add left line separator + ); + + // Add extrafields cols + if (!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } + + $parameters = array( + 'object' => $object, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails, + 'hidedesc' => $hidedesc, + 'hideref' => $hideref + ); + + $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook + if ($reshook < 0) + { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } elseif (empty($reshook)) + { + $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys + } else { + $this->cols = $hookmanager->resArray; + } + } +} diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/modules_myobject.php b/htdocs/modulebuilder/template/core/modules/mymodule/modules_myobject.php index f2451be5f42..a16f56e137c 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/modules_myobject.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/modules_myobject.php @@ -122,11 +122,10 @@ abstract class ModeleNumRefMyObject /** * Returns next assigned value * - * @param Societe $objsoc Object thirdparty * @param Object $object Object we need next value for * @return string Valeur */ - public function getNextValue($objsoc, $object) + public function getNextValue($object) { global $langs; return $langs->trans("NotAvailable"); From 67f007ea4048ac9241b8d776d05258648ae5b0a5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 May 2020 23:12:26 +0200 Subject: [PATCH 29/35] Fix length of field. Make some module die. --- htdocs/install/mysql/migration/11.0.0-12.0.0.sql | 2 ++ htdocs/install/mysql/tables/llx_ecm_files.sql | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 89b8a8ace76..dd448ccdb39 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -73,6 +73,8 @@ delete from llx_const where name in ('PROJECT_HIDE_TASKS', 'MAIN_BUGTRACK_ENABLE ALTER TABLE llx_prelevement_bons ADD COLUMN type varchar(16) DEFAULT 'debit-order'; +ALTER TABLE llx_ecm_files MODIFY COLUMN src_object_type varchar(64); + -- Delete an old index that is duplicated -- VMYSQL4.1 DROP INDEX ix_fk_product_stock on llx_product_batch; diff --git a/htdocs/install/mysql/tables/llx_ecm_files.sql b/htdocs/install/mysql/tables/llx_ecm_files.sql index 2973a962b17..c459e2ca219 100644 --- a/htdocs/install/mysql/tables/llx_ecm_files.sql +++ b/htdocs/install/mysql/tables/llx_ecm_files.sql @@ -25,7 +25,7 @@ CREATE TABLE llx_ecm_files entity integer DEFAULT 1 NOT NULL, -- multi company id filepath varchar(255) NOT NULL, -- relative to dolibarr document dir. Example module/def filename varchar(255) NOT NULL, -- file name only without any directory - src_object_type varchar(32), -- Source object type ('proposal', 'invoice', ...) + src_object_type varchar(64), -- Source object type ('proposal', 'invoice', ...) src_object_id integer, -- Source object id fullpath_orig varchar(750), -- full path of original filename, when file is uploaded from a local computer description text, From 3349144f5ebc818ae404c5e4662467c5be6be6e8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 May 2020 23:23:42 +0200 Subject: [PATCH 30/35] Fix lose enabled and default when editing field signatures in modulebuilder --- htdocs/core/lib/modulebuilder.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index b9a958160d4..6bfe70bc5f2 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -127,12 +127,12 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = { $i++; $texttoinsert .= "\t\t'".$key."' => array('type'=>'".$val['type']."', 'label'=>'".$val['label']."',"; - $texttoinsert .= " 'enabled'=>".($val['enabled'] !== '' ? $val['enabled'] : 1).","; + $texttoinsert .= " 'enabled'=>'".($val['enabled'] !== '' ? $val['enabled'] : 1)."',"; $texttoinsert .= " 'position'=>".($val['position'] !== '' ? $val['position'] : 50).","; $texttoinsert .= " 'notnull'=>".(empty($val['notnull']) ? 0 : $val['notnull']).","; $texttoinsert .= " 'visible'=>".($val['visible'] !== '' ? $val['visible'] : -1).","; if ($val['noteditable']) $texttoinsert .= " 'noteditable'=>'".$val['noteditable']."',"; - if ($val['default']) $texttoinsert .= " 'default'=>'".$val['default']."',"; + if ($val['default'] || $val['default'] === '0') $texttoinsert .= " 'default'=>'".$val['default']."',"; if ($val['index']) $texttoinsert .= " 'index'=>".$val['index'].","; if ($val['foreignkey']) $texttoinsert .= " 'foreignkey'=>'".$val['foreignkey']."',"; if ($val['searchall']) $texttoinsert .= " 'searchall'=>".$val['searchall'].","; From 28df07225d78f8b0d3d1cea610eff08f195528de Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 May 2020 23:11:49 +0200 Subject: [PATCH 31/35] Debug modulebuilder --- htdocs/modulebuilder/index.php | 2 +- .../template/class/myobject.class.php | 2 +- .../doc/pdf_standard_myobject.modules.php | 60 +------------------ 3 files changed, 4 insertions(+), 60 deletions(-) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 1bb1c934aa4..1c7cd3a375d 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -2311,7 +2311,7 @@ elseif (!empty($module)) print ''.$langs->trans("EnterNameOfObjectDesc").'

'; - print '
'; + print '
'; print ' '.$form->textwithpicto($langs->trans("IncludeRefGeneration"), $langs->trans("IncludeRefGenerationHelp")).'
'; print ' '.$form->textwithpicto($langs->trans("IncludeDocGeneration"), $langs->trans("IncludeDocGenerationHelp")).'
'; print ''; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 12400ecb087..7dc98dbf1e7 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -1027,7 +1027,7 @@ class MyObject extends CommonObject $langs->load("mymodule@mymodule"); if (!dol_strlen($modele)) { - $modele = 'standard'; + $modele = 'standard_myobject'; if ($this->modelpdf) { $modele = $this->modelpdf; diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php index 1d08e857e96..e7bd7540835 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php @@ -295,10 +295,6 @@ class pdf_standard_myobject extends ModelePDFMyObject { $object->fetch_thirdparty(); - $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); - $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); - $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); - // Definition of $dir and $file if ($object->specimen) { @@ -1076,68 +1072,16 @@ class pdf_standard_myobject extends ModelePDFMyObject } } - $objectidnext = $object->getIdReplacingInvoice('validated'); - if ($object->type == 0 && $objectidnext) - { - $objectreplacing = new Facture($this->db); - $objectreplacing->fetch($objectidnext); - - $posy += 3; - $pdf->SetXY($posx, $posy); - $pdf->SetTextColor(0, 0, 60); - $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R'); - } - if ($object->type == 1) - { - $objectreplaced = new Facture($this->db); - $objectreplaced->fetch($object->fk_facture_source); - - $posy += 4; - $pdf->SetXY($posx, $posy); - $pdf->SetTextColor(0, 0, 60); - $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R'); - } - if ($object->type == 2 && !empty($object->fk_facture_source)) - { - $objectreplaced = new Facture($this->db); - $objectreplaced->fetch($object->fk_facture_source); - - $posy += 3; - $pdf->SetXY($posx, $posy); - $pdf->SetTextColor(0, 0, 60); - $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R'); - } - $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); - $title = $outputlangs->transnoentities("DateInvoice"); + $title = $outputlangs->transnoentities("Date"); if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { - $title .= ' - '.$outputlangsbis->transnoentities("DateInvoice"); + $title .= ' - '.$outputlangsbis->transnoentities("Date"); } $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date, "day", false, $outputlangs), '', 'R'); - if (!empty($conf->global->INVOICE_POINTOFTAX_DATE)) - { - $posy += 4; - $pdf->SetXY($posx, $posy); - $pdf->SetTextColor(0, 0, 60); - $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : ".dol_print_date($object->date_pointoftax, "day", false, $outputlangs), '', 'R'); - } - - if ($object->type != 2) - { - $posy += 3; - $pdf->SetXY($posx, $posy); - $pdf->SetTextColor(0, 0, 60); - $title = $outputlangs->transnoentities("DateDue"); - if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { - $title .= ' - '.$outputlangsbis->transnoentities("DateDue"); - } - $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date_lim_reglement, "day", false, $outputlangs, true), '', 'R'); - } - if ($object->thirdparty->code_client) { $posy += 3; From e83b754e6fe650cfc375ed8423399fef1930dd91 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 May 2020 23:32:36 +0200 Subject: [PATCH 32/35] Debug modulebuilder --- htdocs/core/lib/modulebuilder.lib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index 6bfe70bc5f2..384fd608597 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -141,6 +141,7 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = if ($val['help']) $texttoinsert .= " 'help'=>\"".preg_replace('/"/', '', $val['help'])."\","; if ($val['showoncombobox']) $texttoinsert .= " 'showoncombobox'=>'".$val['showoncombobox']."',"; if ($val['disabled']) $texttoinsert .= " 'disabled'=>'".$val['disabled']."',"; + if ($val['autofocusoncreate']) $texttoinsert .= " 'autofocusoncreate'=>'".$val['autofocusoncreate']."',"; if ($val['arrayofkeyval']) { $texttoinsert .= " 'arrayofkeyval'=>array("; From 5a8c4ad3f51ef651ead619a10742254b272b0e32 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 1 Jun 2020 00:01:23 +0200 Subject: [PATCH 33/35] Debug modulebuilder --- htdocs/modulebuilder/index.php | 2 ++ .../doc/pdf_standard_myobject.modules.php | 11 ++++++----- .../modulebuilder/template/myobject_card.php | 19 +++++++++++-------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 1c7cd3a375d..2a01a282a90 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -917,10 +917,12 @@ if ($dirins && $action == 'initobject' && $module && $objectname) '/\$includedocgeneration = 0;/' => '$includedocgeneration = 1;' ); dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', 0, 0, 1); + dolReplaceInFile($destdir.'/'.strtolower($objectname).'_card.php', $arrayreplacement, '', 0, 0, 1); $arrayreplacement = array( '/\'models\' => 0,/' => '\'models\' => 1,' ); + dolReplaceInFile($destdir.'/core/modules/mod'.$module.'.class.php', $arrayreplacement, '', 0, 0, 1); } diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php index e7bd7540835..4c0ff154a04 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php @@ -226,7 +226,7 @@ class pdf_standard_myobject extends ModelePDFMyObject $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies")); } - $nblines = count($object->lines); + $nblines = (is_array($object->lines) ? count($object->lines) : 0); $hidetop = 0; if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) { @@ -328,7 +328,7 @@ class pdf_standard_myobject extends ModelePDFMyObject $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks // Set nblines with the new facture lines content after hook - $nblines = count($object->lines); + $nblines = (is_array($object->lines) ? count($object->lines) : 0); // Create pdf instance $pdf = pdf_getInstance($this->format); @@ -1161,15 +1161,16 @@ class pdf_standard_myobject extends ModelePDFMyObject $result = $object->fetch_contact($arrayidcontact[0]); } - //Recipient name - // On peut utiliser le nom de la societe du contact + // Recipient name if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) { $thirdparty = $object->contact; } else { $thirdparty = $object->thirdparty; } - $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (is_object($thirdparty)) { + $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + } $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object); diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index de26be0cb22..07850c17491 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -560,15 +560,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '

'; print ''; // ancre + $includedocgeneration = 0; + // Documents - /*$objref = dol_sanitizeFileName($object->ref); - $relativepath = $objref . '/' . $objref . '.pdf'; - $filedir = $conf->mymodule->dir_output . '/' . $objref; - $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->mymodule->myobject->read; // If you can read, you can build the PDF to read content - $delallowed = $user->rights->mymodule->myobject->create; // If you can create/edit, you can remove a file on card - print $formfile->showdocuments('mymodule', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); - */ + if ($includedocgeneration) { + $objref = dol_sanitizeFileName($object->ref); + $relativepath = $objref . '/' . $objref . '.pdf'; + $filedir = $conf->mymodule->dir_output.'/'.$object->element.'/'.$objref; + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->mymodule->myobject->read; // If you can read, you can build the PDF to read content + $delallowed = $user->rights->mymodule->myobject->create; // If you can create/edit, you can remove a file on card + print $formfile->showdocuments('mymodule:myobject', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); + } // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('myobject')); From dbac97a90846837c7ad64fae89450d6fc9f8e05d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 1 Jun 2020 04:02:47 +0200 Subject: [PATCH 34/35] Fix several troubles into numbering modules. Prefix for takepos moved from TK to TC (TK was already used for tasks) --- htdocs/core/modules/bom/mod_bom_standard.php | 6 +- .../modules/cheque/mod_chequereceipt_mint.php | 6 +- .../modules/commande/mod_commande_marbre.php | 6 +- .../modules/contract/mod_contract_serpis.php | 4 +- .../expedition/mod_expedition_safor.php | 4 +- .../expensereport/mod_expensereport_jade.php | 4 +- .../core/modules/facture/mod_facture_mars.php | 9 +- .../modules/facture/mod_facture_terre.php | 11 ++- htdocs/core/modules/fichinter/mod_pacific.php | 6 +- .../modules/holiday/mod_holiday_madonna.php | 4 +- .../modules/livraison/mod_livraison_jade.php | 6 +- htdocs/core/modules/mrp/mod_mo_standard.php | 6 +- .../modules/payment/mod_payment_cicada.php | 6 +- .../modules/project/mod_project_simple.php | 6 +- .../modules/project/task/mod_task_simple.php | 6 +- .../modules/propale/mod_propale_marbre.php | 6 +- .../modules/reception/mod_reception_beryl.php | 4 +- .../modules/societe/mod_codeclient_monkey.php | 4 +- .../mod_facture_fournisseur_cactus.php | 14 +-- .../mod_commande_fournisseur_muguet.php | 6 +- .../mod_supplier_payment_bronan.php | 6 +- .../mod_supplier_proposal_marbre.php | 6 +- .../takepos/mod_takepos_ref_simple.php | 10 +- .../core/modules/ticket/mod_ticket_simple.php | 6 +- htdocs/modulebuilder/template/admin/setup.php | 93 ++++++++++--------- .../mymodule/mod_myobject_standard.php | 6 +- 26 files changed, 129 insertions(+), 122 deletions(-) diff --git a/htdocs/core/modules/bom/mod_bom_standard.php b/htdocs/core/modules/bom/mod_bom_standard.php index 08acd30451c..2440a36feff 100644 --- a/htdocs/core/modules/bom/mod_bom_standard.php +++ b/htdocs/core/modules/bom/mod_bom_standard.php @@ -83,7 +83,7 @@ class mod_bom_standard extends ModeleNumRefboms $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."bom"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -116,8 +116,8 @@ class mod_bom_standard extends ModeleNumRefboms { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 9; + // First we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."bom_bom"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/cheque/mod_chequereceipt_mint.php b/htdocs/core/modules/cheque/mod_chequereceipt_mint.php index daa2e04366d..bf3f6e9b842 100644 --- a/htdocs/core/modules/cheque/mod_chequereceipt_mint.php +++ b/htdocs/core/modules/cheque/mod_chequereceipt_mint.php @@ -80,7 +80,7 @@ class mod_chequereceipt_mint extends ModeleNumRefChequeReceipts $payyymm = ''; $max = ''; - $posindice = 9; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."bordereau_cheque"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -113,8 +113,8 @@ class mod_chequereceipt_mint extends ModeleNumRefChequeReceipts { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 9; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."bordereau_cheque"; $sql .= " WHERE ref like '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/commande/mod_commande_marbre.php b/htdocs/core/modules/commande/mod_commande_marbre.php index 87e5666be4b..335ceb27b52 100644 --- a/htdocs/core/modules/commande/mod_commande_marbre.php +++ b/htdocs/core/modules/commande/mod_commande_marbre.php @@ -83,7 +83,7 @@ class mod_commande_marbre extends ModeleNumRefCommandes $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."commande"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -116,8 +116,8 @@ class mod_commande_marbre extends ModeleNumRefCommandes { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."commande"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/contract/mod_contract_serpis.php b/htdocs/core/modules/contract/mod_contract_serpis.php index 52950778738..b625fd2c450 100644 --- a/htdocs/core/modules/contract/mod_contract_serpis.php +++ b/htdocs/core/modules/contract/mod_contract_serpis.php @@ -93,7 +93,7 @@ class mod_contract_serpis extends ModelNumRefContracts $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."contrat"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -126,7 +126,7 @@ class mod_contract_serpis extends ModelNumRefContracts { global $db, $conf; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."contrat"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/expedition/mod_expedition_safor.php b/htdocs/core/modules/expedition/mod_expedition_safor.php index afbeec748ea..43ee9551109 100644 --- a/htdocs/core/modules/expedition/mod_expedition_safor.php +++ b/htdocs/core/modules/expedition/mod_expedition_safor.php @@ -88,7 +88,7 @@ class mod_expedition_safor extends ModelNumRefExpedition $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."expedition"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -121,7 +121,7 @@ class mod_expedition_safor extends ModelNumRefExpedition { global $db, $conf; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."expedition"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/expensereport/mod_expensereport_jade.php b/htdocs/core/modules/expensereport/mod_expensereport_jade.php index 9093e55f78f..2915dac3d0e 100644 --- a/htdocs/core/modules/expensereport/mod_expensereport_jade.php +++ b/htdocs/core/modules/expensereport/mod_expensereport_jade.php @@ -89,7 +89,7 @@ class mod_expensereport_jade extends ModeleNumRefExpenseReport $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."expensereport"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -174,7 +174,7 @@ class mod_expensereport_jade extends ModeleNumRefExpenseReport } // First we get the max value - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."expensereport"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/facture/mod_facture_mars.php b/htdocs/core/modules/facture/mod_facture_mars.php index 6b4b5f0451d..0d70631294a 100644 --- a/htdocs/core/modules/facture/mod_facture_mars.php +++ b/htdocs/core/modules/facture/mod_facture_mars.php @@ -98,7 +98,7 @@ class mod_facture_mars extends ModeleNumRefFactures // Check invoice num $fayymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefixinvoice) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefixinvoice)."____-%'"; @@ -120,7 +120,7 @@ class mod_facture_mars extends ModeleNumRefFactures // Check credit note num $fayymm = ''; - $posindice = 8; + $posindice = strlen($this->prefixcreditnote) + 6; $sql = "SELECT MAX(SUBSTRING(ref FROM ".$posindice.")) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefixcreditnote)."____-%'"; @@ -152,15 +152,14 @@ class mod_facture_mars extends ModeleNumRefFactures public function getNextValue($objsoc, $invoice, $mode = 'next') { global $db; - $prefix = $this->prefixinvoice; + $prefix = $this->prefixinvoice; if ($invoice->type == 1) $prefix = $this->prefixreplacement; elseif ($invoice->type == 2) $prefix = $this->prefixcreditnote; elseif ($invoice->type == 3) $prefix = $this->prefixdeposit; - else $prefix = $this->prefixinvoice; // First we get the max value - $posindice = 8; + $posindice = strlen($prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref LIKE '".$prefix."____-%'"; diff --git a/htdocs/core/modules/facture/mod_facture_terre.php b/htdocs/core/modules/facture/mod_facture_terre.php index caa47db3529..7bc81121cb1 100644 --- a/htdocs/core/modules/facture/mod_facture_terre.php +++ b/htdocs/core/modules/facture/mod_facture_terre.php @@ -108,7 +108,7 @@ class mod_facture_terre extends ModeleNumRefFactures // Check invoice num $fayymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefixinvoice) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefixinvoice)."____-%'"; @@ -130,7 +130,7 @@ class mod_facture_terre extends ModeleNumRefFactures // Check credit note num $fayymm = ''; - $posindice = 8; + $posindice = strlen($this->prefixcreditnote) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefixcreditnote)."____-%'"; @@ -151,7 +151,7 @@ class mod_facture_terre extends ModeleNumRefFactures // Check deposit num $fayymm = ''; - $posindice = 8; + $posindice = strlen($this->prefixdeposit) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefixdeposit)."____-%'"; @@ -186,11 +186,12 @@ class mod_facture_terre extends ModeleNumRefFactures dol_syslog(get_class($this)."::getNextValue mode=".$mode, LOG_DEBUG); + $prefix = $this->prefixinvoice; if ($invoice->type == 2) $prefix = $this->prefixcreditnote; elseif ($invoice->type == 3) $prefix = $this->prefixdeposit; - else $prefix = $this->prefixinvoice; + // First we get the max value - $posindice = 8; + $posindice = strlen($prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref LIKE '".$prefix."____-%'"; diff --git a/htdocs/core/modules/fichinter/mod_pacific.php b/htdocs/core/modules/fichinter/mod_pacific.php index b592e65b0d3..cb935c572b3 100644 --- a/htdocs/core/modules/fichinter/mod_pacific.php +++ b/htdocs/core/modules/fichinter/mod_pacific.php @@ -91,7 +91,7 @@ class mod_pacific extends ModeleNumRefFicheinter $fayymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."fichinter"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -126,8 +126,8 @@ class mod_pacific extends ModeleNumRefFicheinter { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."fichinter"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/holiday/mod_holiday_madonna.php b/htdocs/core/modules/holiday/mod_holiday_madonna.php index 3de92c4a05e..50f87a9b335 100644 --- a/htdocs/core/modules/holiday/mod_holiday_madonna.php +++ b/htdocs/core/modules/holiday/mod_holiday_madonna.php @@ -94,7 +94,7 @@ class mod_holiday_madonna extends ModelNumRefHolidays $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."holiday"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -127,7 +127,7 @@ class mod_holiday_madonna extends ModelNumRefHolidays { global $db, $conf; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."holiday"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/livraison/mod_livraison_jade.php b/htdocs/core/modules/livraison/mod_livraison_jade.php index 840b6a6f0a6..d3043ea75ec 100644 --- a/htdocs/core/modules/livraison/mod_livraison_jade.php +++ b/htdocs/core/modules/livraison/mod_livraison_jade.php @@ -96,7 +96,7 @@ class mod_livraison_jade extends ModeleNumRefDeliveryOrder // Check invoice num $fayymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."livraison"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -129,8 +129,8 @@ class mod_livraison_jade extends ModeleNumRefDeliveryOrder { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."livraison"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/mrp/mod_mo_standard.php b/htdocs/core/modules/mrp/mod_mo_standard.php index 3fd3b1ad87e..4687bc48fb4 100644 --- a/htdocs/core/modules/mrp/mod_mo_standard.php +++ b/htdocs/core/modules/mrp/mod_mo_standard.php @@ -83,7 +83,7 @@ class mod_mo_standard extends ModeleNumRefMos $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."mrp_mo"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -116,8 +116,8 @@ class mod_mo_standard extends ModeleNumRefMos { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 9; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."mrp_mo"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/payment/mod_payment_cicada.php b/htdocs/core/modules/payment/mod_payment_cicada.php index 5650ad43707..1f42febd15b 100644 --- a/htdocs/core/modules/payment/mod_payment_cicada.php +++ b/htdocs/core/modules/payment/mod_payment_cicada.php @@ -90,7 +90,7 @@ class mod_payment_cicada extends ModeleNumRefPayments $payyymm = ''; $max = ''; - $posindice = 9; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."paiement"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -123,8 +123,8 @@ class mod_payment_cicada extends ModeleNumRefPayments { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 9; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."paiement"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/project/mod_project_simple.php b/htdocs/core/modules/project/mod_project_simple.php index 301e226020c..00d079c0061 100644 --- a/htdocs/core/modules/project/mod_project_simple.php +++ b/htdocs/core/modules/project/mod_project_simple.php @@ -92,7 +92,7 @@ class mod_project_simple extends ModeleNumRefProjects $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."projet"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -127,8 +127,8 @@ class mod_project_simple extends ModeleNumRefProjects { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."projet"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/project/task/mod_task_simple.php b/htdocs/core/modules/project/task/mod_task_simple.php index cb186594b84..5caeeaf54dd 100644 --- a/htdocs/core/modules/project/task/mod_task_simple.php +++ b/htdocs/core/modules/project/task/mod_task_simple.php @@ -92,7 +92,7 @@ class mod_task_simple extends ModeleNumRefTask $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(task.ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task AS task, "; $sql .= MAIN_DB_PREFIX."projet AS project WHERE task.fk_projet=project.rowid"; @@ -128,8 +128,8 @@ class mod_task_simple extends ModeleNumRefTask { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/propale/mod_propale_marbre.php b/htdocs/core/modules/propale/mod_propale_marbre.php index 4dde423a5e6..a7753cf0f3d 100644 --- a/htdocs/core/modules/propale/mod_propale_marbre.php +++ b/htdocs/core/modules/propale/mod_propale_marbre.php @@ -92,7 +92,7 @@ class mod_propale_marbre extends ModeleNumRefPropales $pryymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."propal"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -128,8 +128,8 @@ class mod_propale_marbre extends ModeleNumRefPropales { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."propal"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/reception/mod_reception_beryl.php b/htdocs/core/modules/reception/mod_reception_beryl.php index 66576eaab76..94bad5adf31 100644 --- a/htdocs/core/modules/reception/mod_reception_beryl.php +++ b/htdocs/core/modules/reception/mod_reception_beryl.php @@ -68,7 +68,7 @@ class mod_reception_beryl extends ModelNumRefReception $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."reception"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -101,7 +101,7 @@ class mod_reception_beryl extends ModelNumRefReception { global $db, $conf; - $posindice = 9; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."reception"; $sql .= " WHERE ref like '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/societe/mod_codeclient_monkey.php b/htdocs/core/modules/societe/mod_codeclient_monkey.php index 15519688f98..ba7bb120e45 100644 --- a/htdocs/core/modules/societe/mod_codeclient_monkey.php +++ b/htdocs/core/modules/societe/mod_codeclient_monkey.php @@ -129,8 +129,8 @@ class mod_codeclient_monkey extends ModeleThirdPartyCode return -1; } - // D'abord on recupere la valeur max (reponse immediate car champ indexe) - $posindice = 8; + // First, we get the max value (reponse immediate car champ indexe) + $posindice = strlen($prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(".$field." FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."societe"; $sql .= " WHERE ".$field." LIKE '".$prefix."____-%'"; diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php index c821e6b60aa..0aa766c2c88 100644 --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php @@ -101,7 +101,7 @@ class mod_facture_fournisseur_cactus extends ModeleNumRefSuppliersInvoices // Check invoice num $siyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefixinvoice) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefixinvoice)."____-%'"; @@ -122,7 +122,7 @@ class mod_facture_fournisseur_cactus extends ModeleNumRefSuppliersInvoices // Check credit note num $siyymm = ''; - $posindice = 8; + $posindice = strlen($this->prefixcreditnote) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefixcreditnote)."____-%'"; @@ -143,7 +143,7 @@ class mod_facture_fournisseur_cactus extends ModeleNumRefSuppliersInvoices // Check deposit num $siyymm = ''; - $posindice = 8; + $posindice = strlen($this->prefixdeposit) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefixdeposit)."____-%'"; @@ -174,12 +174,12 @@ class mod_facture_fournisseur_cactus extends ModeleNumRefSuppliersInvoices { global $db, $conf; + $prefix = $this->prefixinvoice; if ($object->type == 2) $prefix = $this->prefixcreditnote; - elseif ($facture->type == 3) $prefix = $this->prefixdeposit; - else $prefix = $this->prefixinvoice; + elseif ($object->type == 3) $prefix = $this->prefixdeposit; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn"; $sql .= " WHERE ref LIKE '".$prefix."____-%'"; diff --git a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php index df4a60b10e2..79241628482 100644 --- a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php +++ b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php @@ -102,7 +102,7 @@ class mod_commande_fournisseur_muguet extends ModeleNumRefSuppliersOrders $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -136,8 +136,8 @@ class mod_commande_fournisseur_muguet extends ModeleNumRefSuppliersOrders { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php b/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php index 9baa8d2dafe..197d607b08b 100644 --- a/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php +++ b/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php @@ -90,7 +90,7 @@ class mod_supplier_payment_bronan extends ModeleNumRefSupplierPayments $payyymm = ''; $max = ''; - $posindice = 9; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."paiementfourn"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -123,8 +123,8 @@ class mod_supplier_payment_bronan extends ModeleNumRefSupplierPayments { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 10; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."paiementfourn"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php index 37ba98b0058..15fa4930bd9 100644 --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php @@ -92,7 +92,7 @@ class mod_supplier_proposal_marbre extends ModeleNumRefSupplierProposal $pryymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -128,8 +128,8 @@ class mod_supplier_proposal_marbre extends ModeleNumRefSupplierProposal { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; diff --git a/htdocs/core/modules/takepos/mod_takepos_ref_simple.php b/htdocs/core/modules/takepos/mod_takepos_ref_simple.php index 48b1e856aab..911ed761177 100644 --- a/htdocs/core/modules/takepos/mod_takepos_ref_simple.php +++ b/htdocs/core/modules/takepos/mod_takepos_ref_simple.php @@ -41,7 +41,7 @@ class mod_takepos_ref_simple extends ModeleNumRefTakepos * Prefix * @var string */ - public $prefix = 'TK'; + public $prefix = 'TC'; /** * @var string Error code (or message) @@ -89,7 +89,11 @@ class mod_takepos_ref_simple extends ModeleNumRefTakepos $pryymm = ''; $max = ''; - $posindice = 8; + $pos_source = 0; + + // First, we get the max value + $posindice = strlen($this->prefix.$pos_source.'-____-') + 1; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -127,7 +131,7 @@ class mod_takepos_ref_simple extends ModeleNumRefTakepos $pos_source = is_object($invoice) && $invoice->pos_source > 0 ? $invoice->pos_source : 0; - // D'abord on recupere la valeur max + // First, we get the max value $posindice = strlen($this->prefix.$pos_source.'-____-') + 1; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL $sql .= " FROM ".MAIN_DB_PREFIX."facture"; diff --git a/htdocs/core/modules/ticket/mod_ticket_simple.php b/htdocs/core/modules/ticket/mod_ticket_simple.php index 86a4a524da5..67eebfc789a 100644 --- a/htdocs/core/modules/ticket/mod_ticket_simple.php +++ b/htdocs/core/modules/ticket/mod_ticket_simple.php @@ -89,7 +89,7 @@ class mod_ticket_simple extends ModeleNumRefTicket $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."ticket"; $search = $this->prefix."____-%"; @@ -123,8 +123,8 @@ class mod_ticket_simple extends ModeleNumRefTicket { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 8; + // First, we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."ticket"; $search = $this->prefix."____-%"; diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 0d464aab90d..8a116783637 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -61,6 +61,7 @@ $arrayofparameters = array( ); $error = 0; +$setupnotempty = 0; /* @@ -168,8 +169,8 @@ elseif ($action == 'setdoc') // TODO Check if numbering module chosen can be activated // by calling method canBeActivated $tmpobjectkey = GETPOST('object'); - - dolibarr_set_const($db, strtoupper($tmpobjectkey)."_ADDON", $value, 'chaine', 0, '', $conf->entity); + $constforval = 'MYMODULE_'.strtoupper($tmpobjectkey)."_ADDON"; + dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity); } @@ -222,9 +223,7 @@ if ($action == 'edit') print ''; print '
'; -} -else -{ +} else { if (!empty($arrayofparameters)) { print ''; @@ -232,6 +231,8 @@ else foreach ($arrayofparameters as $key => $val) { + $setupnotempty++; + print '
'; $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); print $form->textwithpicto($langs->trans($key), $tooltiphelp); @@ -256,15 +257,15 @@ $myTmpObjects = array(); $myTmpObjects['MyObject']=array('includerefgeneration'=>0, 'includedocgeneration'=>0); - foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { if ($myTmpObjectArray['includerefgeneration']) { /* * Orders Numbering model */ - + $setupnotempty++; + print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', ''); - + print ''; print ''; print ''; @@ -273,13 +274,13 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; print ''; print ''."\n"; - + clearstatcache(); - + foreach ($dirmodels as $reldir) { $dir = dol_buildpath($reldir."core/modules/".$moduledir); - + if (is_dir($dir)) { $handle = opendir($dir); @@ -290,23 +291,23 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') { $file = substr($file, 0, dol_strlen($file) - 4); - + require_once $dir.'/'.$file.'.php'; - + $module = new $file($db); - + // Show modules according to features level if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; - + if ($module->isEnabled()) { dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php'); - + print ''; - + // Show example of numbering model print ''."\n"; - + print ''; - + $mytmpinstance = new $myTmpObjectKey($db); $mytmpinstance->initAsSpecimen(); - + // Info $htmltooltip = ''; $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; - + $nextval = $module->getNextValue($mytmpinstance); if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval $htmltooltip .= ''.$langs->trans("NextValue").': '; @@ -345,11 +346,11 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $htmltooltip .= $langs->trans($module->error).'
'; } } - + print ''; - + print "\n"; } } @@ -360,16 +361,16 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } print "
'.$langs->trans("Name").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; print $module->info(); print ''; $tmp = $module->getExample(); @@ -314,26 +315,26 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { elseif ($tmp == 'NotConfigured') print $langs->trans($tmp); else print $tmp; print ''; $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON'; if ($conf->global->$constforvar == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { - print ''; + print ''; print img_picto($langs->trans("Disabled"), 'switch_off'); print ''; } print ''; print $form->textwithpicto('', $htmltooltip, 1, 0); print '

\n"; } - - + if ($myTmpObjectArray['includedocgeneration']) { /* * Document templates generators */ + $setupnotempty++; $type = strtolower($myTmpObjectKey); - + print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', ''); - + // Load array def with activated templates $def = array(); $sql = "SELECT nom"; @@ -390,8 +391,7 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } else { dol_print_error($db); } - - + print "\n"; print "\n"; print ''; @@ -401,16 +401,16 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; print ''; print "\n"; - + clearstatcache(); - + foreach ($dirmodels as $reldir) { foreach (array('', '/doc') as $valdir) { $realpath = $reldir."core/modules/".$moduledir.$valdir; $dir = dol_buildpath($realpath); - + if (is_dir($dir)) { $handle = opendir($dir); @@ -422,7 +422,7 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } closedir($handle); arsort($filelist); - + foreach ($filelist as $file) { if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) @@ -431,14 +431,14 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { { $name = substr($file, 4, dol_strlen($file) - 16); $classname = substr($file, 0, dol_strlen($file) - 12); - + require_once $dir.'/'.$file; $module = new $classname($db); - + $modulequalified = 1; if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified = 0; if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0; - + if ($modulequalified) { print ''; - + // Active if (in_array($name, $def)) { @@ -461,7 +461,7 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print ""; } - + // Default print ''; - + // Info $htmltooltip = ''.$langs->trans("Name").': '.$module->name; $htmltooltip .= '
'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); @@ -481,15 +481,15 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $htmltooltip .= '
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; } $htmltooltip .= '
'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file; - + $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); - + print ''; - + // Preview print ''; - + print "\n"; } } @@ -509,11 +509,14 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } } } - + print '
'.$langs->trans("Name").''.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; @@ -447,7 +447,7 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { if (method_exists($module, 'info')) print $module->info($langs); else print $module->description; print ''; $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON'; @@ -472,7 +472,7 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print ''; print $form->textwithpicto('', $htmltooltip, 1, 0); print ''; if ($module->type == 'pdf') @@ -499,7 +499,7 @@ foreach($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print img_object($langs->trans("PreviewNotAvailable"), 'generic'); } print '
'; } } +if (empty($setupnotempty)) { + print '
'.$langs->trans("NothingToSetup"); +} // Page end dol_fiche_end(); diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php index a611b6210bc..51e50fbf43f 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php @@ -85,7 +85,7 @@ class mod_myobject_standard extends ModeleNumRefMyObject $coyymm = ''; $max = ''; - $posindice = 8; + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."mymodule_myobject"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; @@ -122,8 +122,8 @@ class mod_myobject_standard extends ModeleNumRefMyObject { global $db, $conf; - // D'abord on recupere la valeur max - $posindice = 9; + // first we get the max value + $posindice = strlen($this->prefix) + 6; $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; $sql .= " FROM ".MAIN_DB_PREFIX."mymodule_myobject"; $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; From c4d8f0b6cc2eaba6c152ce964c67972670cb7408 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 1 Jun 2020 12:35:27 +0200 Subject: [PATCH 35/35] css --- htdocs/theme/eldy/info-box.inc.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index badc7f2d655..604aff91a3e 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -188,8 +188,7 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> .info-box-title{ text-transform: uppercase; font-weight: bold; - margin-bottom: 6px; - /* padding-bottom: 4px; */ + margin-bottom: 3px; /* not too much space so we can add another lines */ } .info-box-text{ font-size: 0.92em;