diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml index 8afb7e8f4f8..5b55cdc54c8 100644 --- a/.github/workflows/stale-issues.yml +++ b/.github/workflows/stale-issues.yml @@ -9,7 +9,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: Dolibarr/stale@v1.1.0 + - uses: Dolibarr/stale@master with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue is stale because it has been open 1 year with no activity. If this is a bug, please comment to confirm it is still present on latest stable version. if this is a feature request, please comment to notify the request is still relevant and not yet covered by latest stable version. Without comment, this issue will be closed automatically by stale bot in 15 days.' @@ -17,7 +17,7 @@ jobs: exempt-issue-label: 'Priority High / Blocking' days-before-stale: 365 days-before-close: 15 - operations-per-run: 10 + operations-per-run: 50 #stale-pr-message: 'This PR is stale because it has been open 1 year with no activity. If this PR is still mergeable (no conflict, nor Continuous Integration errors), please comment to confirm this merge is still expected. Without comment, this issue will be closed automatically by stale bot in 15 days.' stale-pr-label: 'PR Stale (automatic label)' stale-pr-message: diff --git a/build/README b/build/README index 07f0ebe3b55..67ceb05c8d2 100644 --- a/build/README +++ b/build/README @@ -45,9 +45,12 @@ Dolibarr working. It is here only to build Dolibarr packages, and those generated packages will not contains this "build" directory. -We can find in "build", following sub-directories: +You can find in "build", following sub-directories: -* debian: +* composer +To test an upgrade of a lib. + +* debian To build Debian package. * dmg: diff --git a/build/obs/README b/build/obs/README index c8a29e1dac4..44427c01d49 100644 --- a/build/obs/README +++ b/build/obs/README @@ -1,20 +1,24 @@ README (English) ################################################## OBS Package tools +OBE - openSUSE Build Service ################################################## -This directory contains files to explain how to publish -a package onto OBS +This directory contains an instruction to explain +how to publish a package onto OBS. -# Create a project onto OBS -#---------------------------------- -https://build.opensuse.org +# Create a project onto OBS +--------------------------- +https://build.opensuse.org -Packaging rules: http://en.opensuse.org/Portal:Packaging + +# Packaging rules: +------------------ +https://en.opensuse.org/Portal:Packaging Add attributes: -OBS:Screenshots URL of screenshot http://www.dolibarr.org/images/dolibarr_screenshot1.png +OBS:Screenshots URL of screenshot https://www.dolibarr.org/images/dolibarr_screenshot1.png OBS:QualityCategory Development|Testing|Stable|Private OBS:Maintained 1 @@ -28,22 +32,24 @@ To submit a snapshot for building, we should have a service file with content -How to have such a service file created automatically ? -Go into project you want to update. It mught be: +# How to have such a service file created automatically ? +--------------------------------------------------------- +Go into project you want to update. It might be: - openSUSE Build Service > Projects > Application:ERP:Dolibarr > dolibarr - or your private project Once logged, click on "Add file" in section "Source Files", then select mode "Upload From: Remote URL" Keep empty for "Filename", choose "Remote URL" and enter into last field, URL that should looks like this: -http://www.dolibarr.org/files/stable/package_rpm_generic/dolibarr-x.y.v-0.4.src.rpm +https://www.dolibarr.org/files/stable/package_rpm_generic/dolibarr-x.y.v-0.4.src.rpm Then add into Advanded - Attributes -OBS:Screenshots http://www.dolibarr.org/images/dolibarr_screenshot1.png -OBS:QualityCategory Stable|Testing|Development|Private +OBS:Screenshots https://www.dolibarr.org/images/dolibarr_screenshot1.png +OBS:QualityCategory Stable|Testing|Development|Private # Move project into official directory +-------------------------------------- - Enter a bug to ask to be a maintener of a category or to add a new one. For example: https://bugzilla.novell.com/show_bug.cgi?id=848083 to be a maintener of category https://build.opensuse.org/project/show/Application:ERP diff --git a/dev/setup/eclipse/PSR-12 [built-in].xml b/dev/setup/eclipse/PSR-12 [built-in].xml new file mode 100644 index 00000000000..47925209682 --- /dev/null +++ b/dev/setup/eclipse/PSR-12 [built-in].xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/translation/erp_comparison_translation.txt b/dev/translation/erp_comparison_translation.txt index c99a5f4cc1c..6cf7c4f7c60 100644 --- a/dev/translation/erp_comparison_translation.txt +++ b/dev/translation/erp_comparison_translation.txt @@ -1,17 +1,25 @@ +comparison of terms -Term Dolibarr SAP Odoo ... ----------------------------------------------------------------------------- -Thirdparty Contact partner Partner/Contact (company) -Contact/address Contact person Partner/Contact (individual) +Dolibarr SAP ERP Odoo +------------------------------------------------------------------------- +Thirdparty Contact partner Partner/Contact (company) +Contact/address Contact person Partner/Contact (individual) -Financial ?? Invoicing - -Income / Expense ?? Profit / Loss -Balance ?? Net profit -Subledger account Subledger account ?? +Financial Finance (FI) Accounting +Accounting -Proposal ?? Quotation Proposal is ok but proposition looks better (proposal is for a detailed proposition). We can say also "business proposition or business proposal". - Indian are using "Quotation". +Income / Expense ?? Profit / Loss +Balance ?? Net profit +Subledger account Subledger account ?? + +CRM Sales & Distribution Sales +Proposal ?? Quotation + + + +Proposal is ok but proposition looks better (proposal is for a detailed proposition). +We can say also "business proposition or business proposal". +In India they are using "Quotation". diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 9de858da26b..c7681c6f9ca 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -283,6 +283,8 @@ if ($resql) '."\n"; $out .= ''; - $out .= ''.($revertonoff ?img_picto($langs->trans("Enabled"), 'switch_on') : img_picto($langs->trans("Disabled"), 'switch_off')).''; - $out .= ''.($revertonoff ?img_picto($langs->trans("Disabled"), 'switch_off') : img_picto($langs->trans("Enabled"), 'switch_on')).''; + $out .= ''.($revertonoff ?img_picto($langs->trans("Enabled"), 'switch_on', '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Disabled"), 'switch_off', '', false, 0, 0, '', '', $marginleftonlyshort)).''; + $out .= ''.($revertonoff ?img_picto($langs->trans("Disabled"), 'switch_off', '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Enabled"), 'switch_on', '', false, 0, 0, '', '', $marginleftonlyshort)).''; $out .= "\n"; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8129c810303..0b732f9372a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1145,15 +1145,16 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename = * @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto. * @param string $morehtmlright Add more html content on right of tabs title * @param string $morecss More Css + * @param int $limittoshow Limit number of tabs to show. Use 0 to use automatic default value. * @return void */ -function dol_fiche_head($links = array(), $active = '0', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '') +function dol_fiche_head($links = array(), $active = '0', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limittoshow = 0) { - print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath, $morehtmlright, $morecss); + print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath, $morehtmlright, $morecss, $limittoshow); } /** - * Show tab header of a card + * Show tabs of a record * * @param array $links Array of tabs * @param string $active Active tab name @@ -1163,9 +1164,10 @@ function dol_fiche_head($links = array(), $active = '0', $title = '', $notab = 0 * @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto. * @param string $morehtmlright Add more html content on right of tabs title * @param string $morecss More Css + * @param int $limittoshow Limit number of tabs to show. Use 0 to use automatic default value. * @return string */ -function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '') +function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limittoshow = 0) { global $conf, $langs, $hookmanager; @@ -1202,11 +1204,13 @@ function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab if (count($keys)) $maxkey = max($keys); } - if (!empty($conf->dol_optimize_smallscreen)) $conf->global->MAIN_MAXTABS_IN_CARD = 2; - // Show tabs // if =0 we don't use the feature - $limittoshow = (empty($conf->global->MAIN_MAXTABS_IN_CARD) ? 99 : $conf->global->MAIN_MAXTABS_IN_CARD); + if (empty($limittoshow)) { + $limittoshow = (empty($conf->global->MAIN_MAXTABS_IN_CARD) ? 99 : $conf->global->MAIN_MAXTABS_IN_CARD); + } + if (!empty($conf->dol_optimize_smallscreen)) $limittoshow = 2; + $displaytab = 0; $nbintab = 0; $popuptab = 0; @@ -3073,7 +3077,7 @@ function dol_trunc($string, $size = 40, $trunc = 'right', $stringencoding = 'UTF * @param int $srconly Return only content of the src attribute of img. * @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip. * @param string $alt Force alt for bind people - * @param string $morecss Add more class css on img tag (For example 'myclascss'). Work only if $moreatt is empty. + * @param string $morecss Add more class css on img tag (For example 'myclascss'). * @param string $marginleftonlyshort 1 = Add a short left margin on picto, 2 = Add a larger left margin on picto, 0 = No margin left. Works for fontawesome picto only. * @return string Return img tag * @see img_object(), img_picto_common() @@ -4082,11 +4086,22 @@ function getTitleFieldOfList($name, $thead = 0, $file = "", $field = "", $begin $tmpfield = explode(',', $field); $field1 = trim($tmpfield[0]); // If $field is 'd.datep,d.id', it becomes 'd.datep' + if (empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE)) { + $prefix = 'wrapcolumntitle '.$prefix; + } //var_dump('field='.$field.' field1='.$field1.' sortfield='.$sortfield.' sortfield1='.$sortfield1); // If field is used as sort criteria we use a specific css class liste_titre_sel // Example if (sortfield,field)=("nom","xxx.nom") or (sortfield,field)=("nom","nom") - if ($field1 && ($sortfield1 == $field1 || $sortfield1 == preg_replace("/^[^\.]+\./", "", $field1))) $out .= '<'.$tag.' class="'.$prefix.'liste_titre_sel" '.$moreattrib.'>'; - else $out .= '<'.$tag.' class="'.$prefix.'liste_titre" '.$moreattrib.'>'; + if ($field1 && ($sortfield1 == $field1 || $sortfield1 == preg_replace("/^[^\.]+\./", "", $field1))) { + $out .= '<'.$tag.' class="'.$prefix.'liste_titre_sel" '.$moreattrib; + $out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) && preg_match('/^[a-zA-Z_0-9\s\.\-:]*$/', $name)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : ''); + $out .= '>'; + } + else { + $out .= '<'.$tag.' class="'.$prefix.'liste_titre" '.$moreattrib; + $out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) && preg_match('/^[a-zA-Z_0-9\s\.\-:]*$/', $name)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : ''); + $out .= '>'; + } if (empty($thead) && $field && empty($disablesortlink)) // If this is a sort field { @@ -4119,7 +4134,9 @@ function getTitleFieldOfList($name, $thead = 0, $file = "", $field = "", $begin } } $sortordertouseinlink = preg_replace('/,$/', '', $sortordertouseinlink); - $out .= ''; + $out .= 'global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : ''); + $out .= '>'; } if ($tooltip) $out .= $form->textwithpicto($langs->trans($name), $langs->trans($tooltip)); @@ -4287,7 +4304,7 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', if ($picto && $titre) print ''.img_picto('', $picto, 'class="valignmiddle pictotitle widthpictotitle"', $pictoisfullpath).''; print ''; print '
'.$titre; - if (!empty($titre) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') print ' ('.$totalnboflines.')'; + if (!empty($titre) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') print '('.$totalnboflines.')'; print '
'; // Center diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index ddca8ef1153..dbfeef03259 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -2035,15 +2035,19 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $listofstatus = array_keys($listofoppstatus); - $statusOppList = array(); - $themeColorId = 0; - foreach ($listofstatus as $oppStatus) { - $oppStatusCode = dol_getIdFromCode($db, $oppStatus, 'c_lead_status', 'rowid', 'code'); - if ($oppStatusCode) { - $statusOppList[$oppStatus]['code'] = $oppStatusCode; - $statusOppList[$oppStatus]['color'] = isset($theme_datacolor[$themeColorId]) ? implode(', ', $theme_datacolor[$themeColorId]) : ''; + + if (is_array($listofstatus) && ! empty($conf->global->USE_COLOR_FOR_PROSPECTION_STATUS)) { + // Define $themeColorId and array $statusOppList for each $listofstatus + $themeColorId = 0; + $statusOppList = array(); + foreach ($listofstatus as $oppStatus) { + $oppStatusCode = dol_getIdFromCode($db, $oppStatus, 'c_lead_status', 'rowid', 'code'); + if ($oppStatusCode) { + $statusOppList[$oppStatus]['code'] = $oppStatusCode; + $statusOppList[$oppStatus]['color'] = isset($theme_datacolor[$themeColorId]) ? implode(', ', $theme_datacolor[$themeColorId]) : ''; + } + $themeColorId++; } - $themeColorId++; } $projectstatic = new Project($db); @@ -2175,7 +2179,8 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks if ($userAccess >= 0) { $projectstatic->ref = $objp->ref; - $projectstatic->statut = $objp->status; + $projectstatic->statut = $objp->status; // deprecated + $projectstatic->status = $objp->status; $projectstatic->title = $objp->title; $projectstatic->datee = $db->jdate($objp->datee); $projectstatic->dateo = $db->jdate($objp->dateo); @@ -2202,6 +2207,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks print ''; // Because color of prospection status has no meaning yet, it is used if hidden constant is set if (empty($conf->global->USE_COLOR_FOR_PROSPECTION_STATUS)) { + $oppStatusCode = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code'); if ($langs->trans("OppStatus".$oppStatusCode) != "OppStatus".$oppStatusCode) { print $langs->trans("OppStatus".$oppStatusCode); } @@ -2454,7 +2460,7 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide */ function getTaskProgressBadge($task, $label = '', $tooltip = '') { - global $conf; + global $conf, $langs; $out = ''; $badgeClass = ''; @@ -2472,12 +2478,15 @@ function getTaskProgressBadge($task, $label = '', $tooltip = '') if (doubleval($progressCalculated) > doubleval($task->progress * $warningRatio)) { $badgeClass .= 'badge-danger'; + if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("Expected").' '.$progressCalculated.'%'; } elseif (doubleval($progressCalculated) > doubleval($task->progress)) { // warning if close at 10% $badgeClass .= 'badge-warning'; + if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("Expected").' '.$progressCalculated.'%'; } else { $badgeClass .= 'badge-success'; + if (empty($tooltip)) $tooltip = $task->progress.'% >= '.$langs->trans("Expected").' '.$progressCalculated.'%'; } } } diff --git a/htdocs/core/lib/takepos.lib.php b/htdocs/core/lib/takepos.lib.php index 65ad4c091a0..6cf8189f3c8 100644 --- a/htdocs/core/lib/takepos.lib.php +++ b/htdocs/core/lib/takepos.lib.php @@ -52,7 +52,12 @@ function takepos_prepare_head() $h++; } - complete_head_from_modules($conf, $langs, null, $head, $h, 'takepos'); + $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/other.php'; + $head[$h][1] = $langs->trans("Other"); + $head[$h][2] = 'other'; + $h++; + + complete_head_from_modules($conf, $langs, null, $head, $h, 'takepos'); return $head; } diff --git a/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php b/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php index 6e23160baf6..9755369793e 100644 --- a/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php +++ b/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php @@ -411,9 +411,11 @@ class doc_generic_bom_odt extends ModelePDFBom } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index 4694cdaf6ee..75c5103c4ab 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -427,9 +427,11 @@ class doc_generic_order_odt extends ModelePDFCommandes } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php index 190abd86126..c938f40cfb2 100644 --- a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php +++ b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php @@ -408,9 +408,11 @@ class doc_generic_contract_odt extends ModelePDFContract } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index 01070a6a6c7..acbebd54da8 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -435,9 +435,11 @@ class doc_generic_invoice_odt extends ModelePDFFactures } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index b40ca3df78c..11c9f72c4c3 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -687,7 +687,9 @@ class modSociete extends DolibarrModules 'sr.domiciliation' => "BankAccountDomiciliation", 'sr.proprio' => "BankAccountOwner", 'sr.owner_address' => "BankAccountOwnerAddress", - 'sr.default_rib' => 'Default' + 'sr.default_rib' => 'Default', + 'sr.rum' => 'RUM', + 'sr.type' => "Type ban is defaut", ); $this->import_convertvalue_array[$r] = array( @@ -714,7 +716,9 @@ class modSociete extends DolibarrModules 'sr.domiciliation' => 'bank branch address eg. "PARIS"', 'sr.proprio' => 'name on the bank account', 'sr.owner_address' => 'address of account holder', - 'sr.default_rib' => '1 (default account) / 0 (not default)' + 'sr.default_rib' => '1 (default account) / 0 (not default)', + 'sr.rum' => 'RUM code', + 'sr.type' => 'ban', ); // Import Company Sales representatives diff --git a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php index 398c8670a47..e276fe1f5f7 100644 --- a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php +++ b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php @@ -418,9 +418,11 @@ class doc_generic_mo_odt extends ModelePDFMo } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index fde5f08d318..33850c5d882 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -456,9 +456,11 @@ class doc_generic_proposal_odt extends ModelePDFPropales } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php index c71fe8f59ec..d7f48915308 100644 --- a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php +++ b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php @@ -421,9 +421,11 @@ class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php index 77503c4b61b..3b4a39288ea 100644 --- a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php @@ -445,9 +445,11 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php index 17c7cb9e974..dd59b20c964 100644 --- a/htdocs/core/photos_resize.php +++ b/htdocs/core/photos_resize.php @@ -38,6 +38,10 @@ $original_file = GETPOST("file"); $backtourl = GETPOST('backtourl'); $cancel = GETPOST('cancel', 'alpha'); +$file = GETPOST('file', 'alpha'); +$num = GETPOST('num', 'alpha'); // Used for document on bank statement + + // Security check if (empty($modulepart)) accessforbidden('Bad value for modulepart'); $accessallowed = 0; @@ -249,19 +253,25 @@ else { if (empty($backtourl)) { - if (in_array($modulepart, array('product', 'produit', 'service', 'produit|service'))) $backtourl = DOL_URL_ROOT."/product/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('expensereport'))) $backtourl = DOL_URL_ROOT."/expensereport/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('holiday'))) $backtourl = DOL_URL_ROOT."/holiday/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('member'))) $backtourl = DOL_URL_ROOT."/adherents/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('project'))) $backtourl = DOL_URL_ROOT."/projet/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('propal'))) $backtourl = DOL_URL_ROOT."/comm/propal/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('societe'))) $backtourl = DOL_URL_ROOT."/societe/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('tax'))) $backtourl = DOL_URL_ROOT."/compta/sociales/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('ticket'))) $backtourl = DOL_URL_ROOT."/ticket/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('user'))) $backtourl = DOL_URL_ROOT."/user/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('bank'))) $backtourl = DOL_URL_ROOT."/compta/bank/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('mrp'))) $backtourl = DOL_URL_ROOT."/mrp/mo_document.php?id=".$id.'&file='.urldecode($_POST["file"]); - else $backtourl = DOL_URL_ROOT."/".$modulepart."/".$modulepart."_document.php?id=".$id.'&file='.urldecode($_POST["file"]); + $regs = array(); + + if (in_array($modulepart, array('product', 'produit', 'service', 'produit|service'))) $backtourl = DOL_URL_ROOT."/product/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('expensereport'))) $backtourl = DOL_URL_ROOT."/expensereport/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('holiday'))) $backtourl = DOL_URL_ROOT."/holiday/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('member'))) $backtourl = DOL_URL_ROOT."/adherents/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('project'))) $backtourl = DOL_URL_ROOT."/projet/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('propal'))) $backtourl = DOL_URL_ROOT."/comm/propal/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('societe'))) $backtourl = DOL_URL_ROOT."/societe/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('tax'))) $backtourl = DOL_URL_ROOT."/compta/sociales/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('ticket'))) $backtourl = DOL_URL_ROOT."/ticket/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('user'))) $backtourl = DOL_URL_ROOT."/user/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('bank')) && preg_match('/\/statement\/([^\/]+)\//', $file, $regs)) { + $num = $regs[1]; + $backtourl = DOL_URL_ROOT."/compta/bank/account_statement_document.php?id=".$id.'&num='.urlencode($num).'&file='.urldecode($file); + } + elseif (in_array($modulepart, array('bank'))) $backtourl = DOL_URL_ROOT."/compta/bank/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('mrp'))) $backtourl = DOL_URL_ROOT."/mrp/mo_document.php?id=".$id.'&file='.urldecode($file); + else $backtourl = DOL_URL_ROOT."/".$modulepart."/".$modulepart."_document.php?id=".$id.'&file='.urldecode($file); } @@ -283,11 +293,11 @@ if ($cancel) } } -if ($action == 'confirm_resize' && (isset($_POST["file"]) != "") && (isset($_POST["sizex"]) != "") && (isset($_POST["sizey"]) != "")) +if ($action == 'confirm_resize' && GETPOSTISSET("file") && GETPOSTISSET("sizex") && GETPOSTISSET("sizey")) { $fullpath = $dir."/".$original_file; - $result = dol_imageResizeOrCrop($fullpath, 0, $_POST['sizex'], $_POST['sizey']); + $result = dol_imageResizeOrCrop($fullpath, 0, GETPOST('sizex', 'int'), GETPOST('sizey', 'int')); if ($result == $fullpath) { @@ -357,7 +367,7 @@ if ($action == 'confirm_crop') $fullpath = $dir."/".$original_file; //var_dump($_POST['w'].'x'.$_POST['h'].'-'.$_POST['x'].'x'.$_POST['y']);exit; - $result = dol_imageResizeOrCrop($fullpath, 1, $_POST['w'], $_POST['h'], $_POST['x'], $_POST['y']); + $result = dol_imageResizeOrCrop($fullpath, 1, GETPOST('w', 'int'), GETPOST('h', 'int'), GETPOST('x', 'int'), GETPOST('y', 'int')); if ($result == $fullpath) { @@ -445,7 +455,7 @@ print '
'."\n"; */ print ''."\n"; -print '
'; +print ''; print ''; print '
'; @@ -454,7 +464,7 @@ print $langs->trans("ResizeDesc").'
'; print $langs->trans("NewLength").': px   '.$langs->trans("or").'   '; print $langs->trans("NewHeight").': px  
'; -print ''; +print ''; print ''; print ''; print ''; @@ -497,7 +507,8 @@ if (!empty($conf->use_javascript_ajax)) print ''; print ''; print '
'; - print ''; + + print ''; print ''; print '
diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index a3de72723a4..2a3d703d16f 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -23,6 +23,7 @@ // $permissiontoadd = permission or not to add a file (can use also $permission) and permission or not to edit file name or crop file (can use also $permtoedit) // $modulepart = for download // $param = param to add to download links +// $moreparam = param to add to download link for the form_attach_new_file function // $upload_dir // $object // $filearray @@ -109,7 +110,7 @@ if (!isset($savingdocmask) || !empty($conf->global->MAIN_DISABLE_SUGGEST_REF_AS_ // Show upload form (document and links) $formfile->form_attach_new_file( - $_SERVER["PHP_SELF"].'?id='.$object->id.(empty($withproject)?'':'&withproject=1'), + $_SERVER["PHP_SELF"].'?id='.$object->id.(empty($withproject)?'':'&withproject=1').(empty($moreparam)?'':$moreparam), '', 0, 0, diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index 60e5eafcb48..770d39ec951 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -33,7 +33,7 @@ class ExpenseReports extends DolibarrApi * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( - 'socid' + 'fk_user_author' ); /** @@ -384,6 +384,10 @@ class ExpenseReports extends DolibarrApi * @param array $request_data Datas * * @return int + * + * @throws RestException 401 Not allowed + * @throws RestException 404 Expense report not found + * @throws RestException 500 */ public function put($id, $request_data = null) { @@ -501,6 +505,11 @@ class ExpenseReports extends DolibarrApi // phpcs:enable $object = parent::_cleanObjectDatas($object); + unset($object->fk_statut); + unset($object->statut); + unset($object->user); + unset($object->thirdparty); + unset($object->cond_reglement); unset($object->shipping_method_id); @@ -509,6 +518,32 @@ class ExpenseReports extends DolibarrApi unset($object->barcode_type_label); unset($object->barcode_type_coder); + unset($object->code_paiement); + unset($object->code_statut); + unset($object->fk_c_paiement); + unset($object->fk_incoterms); + unset($object->label_incoterms); + unset($object->location_incoterms); + unset($object->mode_reglement_id); + unset($object->cond_reglement_id); + + unset($object->name); + unset($object->lastname); + unset($object->firstname); + unset($object->civility_id); + unset($object->cond_reglement_id); + unset($object->contact); + unset($object->contact_id); + + unset($object->state); + unset($object->state_id); + unset($object->state_code); + unset($object->country); + unset($object->country_id); + unset($object->country_code); + + unset($object->note); // We already use note_public and note_pricate + return $object; } diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 14ab2b88f22..c98d8af18d2 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -58,19 +58,20 @@ class ExpenseReport extends CommonObject public $date_fin; + /** + * 0=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied + * + * @var int Status + */ public $status; - public $fk_statut; // -- 0=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied + public $fk_statut; + public $fk_c_paiement; public $paid; public $user_author_infos; public $user_validator_infos; - public $fk_typepayment; - public $num_payment; - public $code_paiement; - public $code_statut; - // ACTIONS // Create @@ -285,10 +286,33 @@ class ExpenseReport extends CommonObject { if (is_array($this->lines) && count($this->lines) > 0) { - foreach ($this->lines as $i => $val) + foreach ($this->lines as $line) { + // Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array + //if (! is_object($line)) $line=json_decode(json_encode($line), false); // convert recursively array into object. + if (!is_object($line)) { + $line = (object) $line; + $newndfline = new ExpenseReportLine($this->db); + $newndfline->fk_expensereport = $line->fk_expensereport; + $newndfline->fk_c_type_fees = $line->fk_c_type_fees; + $newndfline->fk_project = $line->fk_project; + $newndfline->vatrate = $line->vatrate; + $newndfline->vat_src_code = $line->vat_src_code; + $newndfline->comments = $line->comments; + $newndfline->qty = $line->qty; + $newndfline->value_unit = $line->value_unit; + $newndfline->total_ht = $line->total_ht; + $newndfline->total_ttc = $line->total_ttc; + $newndfline->total_tva = $line->total_tva; + $newndfline->date = $line->date; + $newndfline->rule_warning_message = $line->rule_warning_message; + $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat; + $newndfline->fk_ecm_files = $line->fk_ecm_files; + } + else { + $newndfline = $line; + } //$newndfline=new ExpenseReportLine($this->db); - $newndfline = $this->lines[$i]; $newndfline->fk_expensereport = $this->id; $result = $newndfline->insert(); if ($result < 0) @@ -514,10 +538,8 @@ class ExpenseReport extends CommonObject $sql .= " d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,"; // DATES (datetime) $sql .= " d.fk_user_author, d.fk_user_modif, d.fk_user_validator,"; $sql .= " d.fk_user_valid, d.fk_user_approve,"; - $sql .= " d.fk_statut as status, d.fk_c_paiement, d.paid,"; - $sql .= " dp.libelle as label_payment, dp.code as code_paiement"; // INNER JOIN paiement + $sql .= " d.fk_statut as status, d.fk_c_paiement, d.paid"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id"; if ($ref) $sql .= " WHERE d.ref = '".$this->db->escape($ref)."'"; else $sql .= " WHERE d.rowid = ".$id; //$sql.= $restrict; @@ -566,7 +588,7 @@ class ExpenseReport extends CommonObject elseif ($this->fk_user_validator > 0) $user_approver->fetch($this->fk_user_validator); // For backward compatibility $this->user_validator_infos = dolGetFirstLastname($user_approver->firstname, $user_approver->lastname); - $this->fk_statut = $obj->status; + $this->fk_statut = $obj->status; // deprecated $this->status = $obj->status; $this->fk_c_paiement = $obj->fk_c_paiement; $this->paid = $obj->paid; @@ -578,9 +600,6 @@ class ExpenseReport extends CommonObject $this->user_valid_infos = dolGetFirstLastname($user_valid->firstname, $user_valid->lastname); } - $this->code_statut = $obj->code_statut; - $this->code_paiement = $obj->code_paiement; - $this->lines = array(); $result = $this->fetch_lines(); @@ -2650,7 +2669,7 @@ class ExpenseReportLine $sql .= " ".$this->db->escape($this->total_ht).","; $sql .= " ".$this->db->escape($this->total_tva).","; $sql .= " ".$this->db->escape($this->total_ttc).","; - $sql .= "'".$this->db->idate($this->date)."',"; + $sql .= " '".$this->db->idate($this->date)."',"; $sql .= " '".$this->db->escape($this->rule_warning_message)."',"; $sql .= " ".$this->db->escape($this->fk_c_exp_tax_cat).","; $sql .= " ".($this->fk_ecm_files > 0 ? $this->fk_ecm_files : 'null'); diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 3d1a23ee26d..6e95b17eb56 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -286,99 +286,100 @@ if (empty($reshook)) $lines = $srcobject->lines; } - $fk_parent_line = 0; - $num = count($lines); + if (is_array($lines)) { + $num = count($lines); - for ($i = 0; $i < $num; $i++) - { - $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : Product::TYPE_PRODUCT); + for ($i = 0; $i < $num; $i++) + { + $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : Product::TYPE_PRODUCT); - if ($product_type == Product::TYPE_SERVICE || !empty($conf->global->FICHINTER_PRINT_PRODUCTS)) { //only services except if config includes products - $duration = 3600; // Default to one hour + if ($product_type == Product::TYPE_SERVICE || !empty($conf->global->FICHINTER_PRINT_PRODUCTS)) { //only services except if config includes products + $duration = 3600; // Default to one hour - // Predefined products & services - if ($lines[$i]->fk_product > 0) - { - $prod = new Product($db); - $prod->id = $lines[$i]->fk_product; + // Predefined products & services + if ($lines[$i]->fk_product > 0) + { + $prod = new Product($db); + $prod->id = $lines[$i]->fk_product; - // Define output language - if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $prod->getMultiLangs(); - // We show if duration is present on service (so we get it) - $prod->fetch($lines[$i]->fk_product); - $outputlangs = $langs; - $newlang = ''; - if (empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09'); - if (empty($newlang)) $newlang = $srcobject->thirdparty->default_lang; - if (!empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); + // Define output language + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $prod->getMultiLangs(); + // We show if duration is present on service (so we get it) + $prod->fetch($lines[$i]->fk_product); + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09'); + if (empty($newlang)) $newlang = $srcobject->thirdparty->default_lang; + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label; + } else { + $prod->fetch($lines[$i]->fk_product); + $label = $lines[$i]->product_label; } - $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label; - } else { - $prod->fetch($lines[$i]->fk_product); - $label = $lines[$i]->product_label; - } - if ($prod->duration_value && $conf->global->FICHINTER_USE_SERVICE_DURATION) { - switch ($prod->duration_unit) { - default: - case 'h': - $mult = 3600; - break; - case 'd': - $mult = 3600 * 24; - break; - case 'w': - $mult = 3600 * 24 * 7; - break; - case 'm': - $mult = (int) 3600 * 24 * (365 / 12); // Average month duration - break; - case 'y': - $mult = 3600 * 24 * 365; - break; + if ($prod->duration_value && $conf->global->FICHINTER_USE_SERVICE_DURATION) { + switch ($prod->duration_unit) { + default: + case 'h': + $mult = 3600; + break; + case 'd': + $mult = 3600 * 24; + break; + case 'w': + $mult = 3600 * 24 * 7; + break; + case 'm': + $mult = (int) 3600 * 24 * (365 / 12); // Average month duration + break; + case 'y': + $mult = 3600 * 24 * 365; + break; + } + $duration = $prod->duration_value * $mult * $lines[$i]->qty; } - $duration = $prod->duration_value * $mult * $lines[$i]->qty; - } - $desc = $lines[$i]->product_ref; - $desc .= ' - '; - $desc .= $label; + $desc = $lines[$i]->product_ref; + $desc .= ' - '; + $desc .= $label; + $desc .= '
'; + } + // Common part (predefined or free line) + $desc .= dol_htmlentitiesbr($lines[$i]->desc); $desc .= '
'; - } - // Common part (predefined or free line) - $desc .= dol_htmlentitiesbr($lines[$i]->desc); - $desc .= '
'; - $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')'; + $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')'; - $timearray = dol_getdate(dol_now()); - $date_intervention = dol_mktime(0, 0, 0, $timearray['mon'], $timearray['mday'], $timearray['year']); + $timearray = dol_getdate(dol_now()); + $date_intervention = dol_mktime(0, 0, 0, $timearray['mon'], $timearray['mday'], $timearray['year']); - if ($product_type == Product::TYPE_PRODUCT) { - $duration = 0; - } + if ($product_type == Product::TYPE_PRODUCT) { + $duration = 0; + } - $predef = ''; + $predef = ''; - // Extrafields - $extrafields->fetch_name_optionals_label($object->table_element_line); - $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef); + // Extrafields + $extrafields->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef); - $result = $object->addline( - $user, - $id, - $desc, - $date_intervention, - $duration, - $array_options - ); + $result = $object->addline( + $user, + $id, + $desc, + $date_intervention, + $duration, + $array_options + ); - if ($result < 0) - { - $error++; - break; + if ($result < 0) + { + $error++; + break; + } } } } diff --git a/htdocs/install/doctemplates/README b/htdocs/install/doctemplates/README index 9ac615ea7c4..b1978fb3de7 100644 --- a/htdocs/install/doctemplates/README +++ b/htdocs/install/doctemplates/README @@ -1,8 +1,8 @@ README (English) -------------------------------- -This directory contains samples of odttemplates used by install +This directory contains samples of odt-templates used by install process. WARNING: -Do not edit files in those directories, but in installed data -directory instead. \ No newline at end of file +Do not edit/change files in these directories, +only in installed data directory instead (e.g. //dolibarr/documents/doctemplates/). diff --git a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql index 179fdf80dcc..bc4b562711b 100644 --- a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql +++ b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql @@ -59,11 +59,14 @@ ALTER TABLE llx_emailcollector_emailcollectoraction ADD COLUMN position integer -- For v11 + ALTER TABLE llx_product_price MODIFY COLUMN tva_tx double(6,3) DEFAULT 0 NOT NULL; ALTER TABLE llx_facturedet MODIFY COLUMN situation_percent real DEFAULT 100; UPDATE llx_facturedet SET situation_percent = 100 WHERE situation_percent IS NULL AND fk_prev_id IS NULL; +-- Set country to null for deprecated accounting system (there is now one per country) +UPDATE llx_accounting_system SET fk_country = NULL, active = 0 WHERE pcg_version = 'SYSCOHADA'; INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 20, 'BAS-K1-MINI', 'The Swedish mini chart of accounts', 1); ALTER TABLE llx_c_action_trigger MODIFY COLUMN elementtype varchar(64) NOT NULL; diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index b3ff583042d..282690edcf7 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -5024,7 +5024,7 @@ function migrate_users_socialnetworks() $obj->socialnetworks = '[]'; } $socialnetworks = array_merge($arraysocialnetworks, json_decode($obj->socialnetworks, true)); - $sqlupd = 'UPDATE '.MAIN_DB_PREFIX.'user SET socialnetworks="'.$db->escape(json_encode($socialnetworks, true)).'"'; + $sqlupd = 'UPDATE '.MAIN_DB_PREFIX."user SET socialnetworks='".$db->escape(json_encode($socialnetworks, true))."'"; $sqlupd.= ', skype=null'; $sqlupd.= ', twitter=null'; $sqlupd.= ', facebook=null'; diff --git a/htdocs/langs/HOWTO-Translation.txt b/htdocs/langs/HOWTO-Translation.txt index 2d7c910d98a..0a05133fdb8 100644 --- a/htdocs/langs/HOWTO-Translation.txt +++ b/htdocs/langs/HOWTO-Translation.txt @@ -1,8 +1,9 @@ --- Translation How to --- -Document explaining how to translate Dolibarr in a new language is -available on wiki: +An instruction guide for translating Dolibarr in a new language is +available on Dolibarr wiki: -English: http://wiki.dolibarr.org/index.php/Translator_documentation -French: http://wiki.dolibarr.org/index.php/Documentation_traducteur -Spanish: http://wiki.dolibarr.org/index.php/Documentaci%C3%B3n_traductores +English: https://wiki.dolibarr.org/index.php/Translator_documentation +French: https://wiki.dolibarr.org/index.php/Documentation_traducteur +Spanish: https://wiki.dolibarr.org/index.php/Documentaci%C3%B3n_traductores +German: https://wiki.dolibarr.org/index.php/Dokumentation_Uebersetzung diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 0f10ac291ff..7a4de856ba2 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -328,7 +328,7 @@ SetupIsReadyForUse=Module deployment is finished. You must however enable and se NotExistsDirect=The alternative root directory is not defined to an existing directory.
InfDirAlt=Since version 3, it is possible to define an alternative root directory. This allows you to store, into a dedicated directory, plug-ins and custom templates.
Just create a directory at the root of Dolibarr (eg: custom).
InfDirExample=
Then declare it in the file conf.php
$dolibarr_main_url_root_alt='/custom'
$dolibarr_main_document_root_alt='/path/of/dolibarr/htdocs/custom'
If these lines are commented with "#", to enable them, just uncomment by removing the "#" character. -YouCanSubmitFile=Alternatively, you may upload the module .zip file package: +YouCanSubmitFile=You can upload the .zip file of module package from here: CurrentVersion=Dolibarr current version CallUpdatePage=Browse to the page that updates the database structure and data: %s. LastStableVersion=Latest stable version @@ -642,7 +642,7 @@ Module50000Desc=Offer customers a PayBox online payment page (credit/debit cards Module50100Name=POS SimplePOS Module50100Desc=Point of Sale module SimplePOS (simple POS). Module50150Name=POS TakePOS -Module50150Desc=Point of Sale module TakePOS (touchscreen POS). +Module50150Desc=Point of Sale module TakePOS (touchscreen POS, for shops, bars or restaurants). Module50200Name=Paypal Module50200Desc=Offer customers a PayPal online payment page (PayPal account or credit/debit cards). This can be used to allow your customers to make ad-hoc payments or payments related to a specific Dolibarr object (invoice, order etc...) Module50300Name=Stripe @@ -1688,6 +1688,7 @@ StockDecreaseForPointOfSaleDisabledbyBatch=Stock decrease in POS is not compatib CashDeskYouDidNotDisableStockDecease=You did not disable stock decrease when making a sale from Point of Sale. Hence a warehouse is required. CashDeskForceDecreaseStockLabel=Stock decrease for batch products was forced. CashDeskForceDecreaseStockDesc=Decrease first by the oldest eatby and sellby dates. +CashDeskReaderKeyCodeForEnter=Key code for "Enter" defined in barcode reader (Example: 13) ##### Bookmark ##### BookmarkSetup=Bookmark module setup BookmarkDesc=This module allows you to manage bookmarks. You can also add shortcuts to any Dolibarr pages or external web sites on your left menu. @@ -1970,8 +1971,8 @@ DeleteEmailCollector=Delete email collector ConfirmDeleteEmailCollector=Are you sure you want to delete this email collector? RecipientEmailsWillBeReplacedWithThisValue=Recipient emails will be always replaced with this value AtLeastOneDefaultBankAccountMandatory=At least 1 default bank account must be defined -RESTRICT_API_ON_IP=Allow available APIs to some host IP only (wildcard not allowed, use space between values). Empty means every hosts can use the available APIs. RESTRICT_ON_IP=Allow access to some host IP only (wildcard not allowed, use space between values). Empty means every hosts can access. +IPListExample=127.0.0.1 192.168.0.2 [::1] BaseOnSabeDavVersion=Based on the library SabreDAV version NotAPublicIp=Not a public IP MakeAnonymousPing=Make an anonymous Ping '+1' to the Dolibarr foundation server (done 1 time only after installation) to allow the foundation to count the number of Dolibarr installation. diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 221d5032bfb..738f6ddea7a 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1685,6 +1685,7 @@ StockDecreaseForPointOfSaleDisabledbyBatch=La décrémentation de stock depuis c CashDeskYouDidNotDisableStockDecease=Vous n'avez pas désactivé la réduction de stock lors d'une vente depuis le Point de vente. Par conséquent, un entrepôt est nécessaire. CashDeskForceDecreaseStockLabel=Décrémentation des stocks pour les lots a été forcé. CashDeskForceDecreaseStockDesc=Décrémentation des lots par DLC et DLUO les plus anciennes. +CashDeskReaderKeyCodeForEnter=Code pour la touche "Entrée" du lecteur de codes à barres. ##### Bookmark ##### BookmarkSetup=Configuration du module Marque-pages BookmarkDesc=Ce module vous permet de gérer des liens et raccourcis. Il permet aussi d'ajouter n'importe quelle page de Dolibarr ou lien web dans le menu d'accès rapide sur la gauche. diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 8c1cdd829de..ef09674f8aa 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1757,9 +1757,11 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead /** * Build the tooltip on user login * - * @return string HTML content + * @param int $hideloginname Hide login name. Show only the image. + * @param string $urllogout URL for logout + * @return string HTML content */ -function top_menu_user() +function top_menu_user($hideloginname = 0, $urllogout = '') { global $langs, $conf, $db, $hookmanager, $user; global $dolibarr_main_authentication, $dolibarr_main_demo; @@ -1830,9 +1832,10 @@ function top_menu_user() } } - - - $logoutLink = '
'.$langs->trans("Logout").''; + if (empty($urllogout)) { + $urllogout = DOL_URL_ROOT.'/user/logout.php'; + } + $logoutLink = ' '.$langs->trans("Logout").''; $profilLink = ' '.$langs->trans("Card").''; @@ -1857,9 +1860,12 @@ function top_menu_user() $btnUser = '