From f7145ea4d3f0241ae7e7c5e5db2026e8ea148aba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 20 Mar 2025 02:39:21 +0100 Subject: [PATCH 01/31] Fix POS has some product unvisible when using smartphone --- htdocs/takepos/index.php | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index baa290337f1..181e4df764f 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -299,7 +299,7 @@ function MoreCategories(moreorless) { // LoadProducts function LoadProducts(position, issubcat) { console.log("LoadProducts position="+position+" issubcat="+issubcat); - var maxproduct = ; + var maxproduct = ; if (position=="supplements") { currentcat="supplements"; @@ -336,8 +336,9 @@ function LoadProducts(position, issubcat) { $("#proimg"+ishow).attr("src","genimg/index.php?query=cat&id="+val.rowid); $("#prodiv"+ishow).data("rowid",val.rowid); $("#prodiv"+ishow).attr("data-rowid",val.rowid); - $("#prodiv"+ishow).data("iscat",1); - $("#prodiv"+ishow).attr("data-iscat",1); + $("#prodiv"+ishow).data("iscat", 1); + $("#prodiv"+ishow).attr("data-iscat", 1); + $("#prodiv"+ishow).removeClass("divempty"); $("#prowatermark"+ishow).show(); ishow++; } @@ -346,7 +347,7 @@ function LoadProducts(position, issubcat) { idata=0; //product data counter var limit = 0; if (maxproduct >= 1) { - limit = maxproduct-1; + limit = maxproduct - 1; } // Only show products for sale (tosell=1) $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&thirdpartyid=' + jQuery('#thirdpartyid').val() + '&category='+currentcat+'&tosell=1&limit='+limit+'&offset=0', function(data) { @@ -373,6 +374,9 @@ function LoadProducts(position, issubcat) { $("#prodiv"+ishow).data("rowid",""); $("#prodiv"+ishow).attr("data-rowid",""); + $("#prodiv"+ishow).data("iscat","0"); + $("#prodiv"+ishow).attr("data-iscat","0"); + $("#prodiv"+ishow).attr("class","wrapper2 divempty"); } else { "> - onclick="MoreProducts('less')" onclick="MoreProducts('more')" > + print '
+ onclick="MoreProducts('less')" onclick="MoreProducts('more')" > '; From 841a109cdb68d5462db0fdffc5bcc83b896e77b7 Mon Sep 17 00:00:00 2001 From: Pierre Ardoin <32256817+mapiolca@users.noreply.github.com> Date: Thu, 20 Mar 2025 08:55:58 +0100 Subject: [PATCH 02/31] FIX Sort and search Ref Project column was missing (#33539) * FIX Sort and search Ref Project column was missing * Remove White space --- htdocs/supplier_proposal/list.php | 81 ++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index 3e8b03d3d22..2fed4e1020d 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -48,8 +48,18 @@ if (isModEnabled('project')) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; } + +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ + + // Load translation files required by the page -$langs->loadLangs(array('companies', 'propal', 'supplier_proposal', 'compta', 'bills', 'orders', 'products')); +$langs->loadLangs(array('companies', 'propal', 'supplier_proposal', 'compta', 'bills', 'orders', 'products', 'projects')); $socid = GETPOSTINT('socid'); @@ -97,6 +107,7 @@ $search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha'); $search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha'); $search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha'); $search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha'); +$search_project_ref = GETPOST('search_project_ref', 'alpha'); $search_status = GETPOST('search_status', 'intcomma'); $search_product_category = GETPOST('search_product_category', 'int'); $search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); @@ -109,9 +120,10 @@ $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page"); -if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { + // If $page is not defined, or '' or -1 or if we click on clear filters $page = 0; -} // If $page is not defined, or '' or -1 +} $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -156,12 +168,17 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // List of fields to search into when doing a "search in all" -$fieldstosearchall = array( - 'sp.ref' => 'Ref', - 's.nom' => 'Supplier', - 'pd.description' => 'Description', - 'sp.note_public' => 'NotePublic', -); +$fieldstosearchall = array(); +foreach ($object->fields as $key => $val) { + if (!empty($val['searchall'])) { + $fieldstosearchall['sp.'.$key] = $val['label']; + } +} +$fieldstosearchall['pd.description'] = 'Description'; +$fieldstosearchall['s.nom'] = "ThirdParty"; +$fieldstosearchall['s.name_alias'] = "AliasNameShort"; +$fieldstosearchall['s.zip'] = "Zip"; +$fieldstosearchall['s.town'] = "Town"; if (empty($user->socid)) { $fieldstosearchall["p.note_private"] = "NotePrivate"; } @@ -186,6 +203,7 @@ $arrayfields = array( 'sp.multicurrency_total_ht' => array('label' => 'MulticurrencyAmountHT', 'checked' => 0, 'enabled' => (!isModEnabled("multicurrency") ? 0 : 1)), 'sp.multicurrency_total_vat' => array('label' => 'MulticurrencyAmountVAT', 'checked' => 0, 'enabled' => (!isModEnabled("multicurrency") ? 0 : 1)), 'sp.multicurrency_total_ttc' => array('label' => 'MulticurrencyAmountTTC', 'checked' => 0, 'enabled' => (!isModEnabled("multicurrency") ? 0 : 1)), + 'sp.fk_projet' => array('label' => $langs->trans("RefProject"), 'checked' => 1,'enabled' => (!isModEnabled("project") ? 0 : 1)), 'u.login' => array('label' => $langs->trans("Author"), 'checked' => 1, 'position' => 10), 'sp.datec' => array('label' => $langs->trans("DateCreation"), 'checked' => 0, 'position' => 500), 'sp.tms' => array('label' => $langs->trans("DateModificationShort"), 'checked' => 0, 'position' => 500), @@ -247,6 +265,7 @@ if (empty($reshook)) { $search_multicurrency_montant_ht = ''; $search_multicurrency_montant_vat = ''; $search_multicurrency_montant_ttc = ''; + $search_project_ref = ''; $search_login = ''; $search_product_category = ''; $search_town = ''; @@ -322,7 +341,7 @@ $sql .= " state.code_departement as state_code, state.nom as state_name,"; $sql .= ' sp.rowid, sp.note_public, sp.note_private, sp.total_ht, sp.total_tva, sp.total_ttc, sp.localtax1, sp.localtax2, sp.ref, sp.fk_statut as status, sp.fk_user_author, sp.date_valid, sp.date_livraison as dp,'; $sql .= ' sp.fk_multicurrency, sp.multicurrency_code, sp.multicurrency_tx, sp.multicurrency_total_ht, sp.multicurrency_total_tva as multicurrency_total_vat, sp.multicurrency_total_ttc,'; $sql .= ' sp.datec as date_creation, sp.tms as date_modification,'; -$sql .= " p.rowid as project_id, p.ref as project_ref,"; +$sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_title,"; $sql .= " u.firstname, u.lastname, u.photo, u.login, u.statut as ustatus, u.admin, u.employee, u.email as uemail"; // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { @@ -408,6 +427,9 @@ if ($search_multicurrency_montant_vat != '') { if ($search_multicurrency_montant_ttc != '') { $sql .= natural_search('sp.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1); } +if ($search_project_ref != '') { + $sql .= natural_search("p.ref", $search_project_ref); +} if ($search_all) { $sql .= natural_search(array_keys($fieldstosearchall), $search_all); } @@ -625,6 +647,9 @@ if ($resql) { if ($search_status != '') { $param .= '&search_status='.urlencode($search_status); } + if ($search_project_ref >= 0) { + $param .= "&search_project_ref=".urlencode($search_project_ref); + } if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); } @@ -749,6 +774,12 @@ if ($resql) { print ''; print ''; } + // Project ref + if (!empty($arrayfields['sp.fk_projet']['checked'])) { + print ''; + print ''; + print ''; + } if (!empty($arrayfields['s.nom']['checked'])) { print ''; print ''; @@ -905,6 +936,12 @@ if ($resql) { print_liste_field_titre($arrayfields['sp.ref']['label'], $_SERVER["PHP_SELF"], 'sp.ref', '', $param, '', $sortfield, $sortorder); $totalarray['nbfield']++; } + + if (!empty($arrayfields['sp.fk_projet']['checked'])) { + print_liste_field_titre($arrayfields['sp.fk_projet']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; + } + if (!empty($arrayfields['s.nom']['checked'])) { print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], 's.nom', '', $param, '', $sortfield, $sortorder); $totalarray['nbfield']++; @@ -1006,10 +1043,13 @@ if ($resql) { $i = 0; $total = 0; $subtotal = 0; + + $userstatic = new User($db); + $objectstatic = new SupplierProposal($db); + $projectstatic = new Project($db); + $savnbfield = $totalarray['nbfield']; - $totalarray = array(); - $totalarray['nbfield'] = 0; - $totalarray['val'] = array(); + $totalarray = array('nbfield' => 0, 'val' => array(), 'pos' => array()); $totalarray['val']['sp.total_ht'] = 0; $totalarray['val']['sp.total_tva'] = 0; $totalarray['val']['sp.total_ttc'] = 0; @@ -1089,6 +1129,21 @@ if ($resql) { } } + // Project + if (!empty($arrayfields['sp.fk_projet']['checked'])) { + $projectstatic->id = $obj->project_id; + $projectstatic->ref = $obj->project_ref; + $projectstatic->title = $obj->project_title; + print ''; + if ($obj->project_id > 0) { + print $projectstatic->getNomUrl(1); + } + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Thirdparty if (!empty($arrayfields['s.nom']['checked'])) { print ''; From f7c9d4ecfc101bb9af9bb4167c5d83e0a5c67b25 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Thu, 20 Mar 2025 08:56:47 +0100 Subject: [PATCH 03/31] =?UTF-8?q?migration:=2019.0=E2=86=9220.0:=20rename?= =?UTF-8?q?=20llx=5Fcommande=5Ffournisseur=5Fdispatch=20sequences=20#31228?= =?UTF-8?q?=20(#33542)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix an issue after upgrading to 20.0.x with the backend saying that the sequences llx_expeditiondet_batch_rowid_seq doesn't exist. The table was somehow renamed, and migration fixed for PostgreSQL in the following commits: - 3670ba75ba4f1172ea50c1f266af78e141402965: rename the table to match the intent of the table. - 9913778da0cd573c2f95718c4cb7a8370503918a: using VPGSQL comments to use a different RENAME function for PostgreSQL. - d73d27466bbd4a8592173d683f95fb861e8e63c7: Using RENAME TO which is compatible with both PostgreSQL and MySQL. But the sequence was still a leftover after those migrations. Co-authored-by: Alexis Thietard Co-authored-by: Geoffrey Mellar Fixes #31228 --- htdocs/install/mysql/migration/19.0.0-20.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/19.0.0-20.0.0.sql b/htdocs/install/mysql/migration/19.0.0-20.0.0.sql index cf2697e3567..5b575cafd66 100644 --- a/htdocs/install/mysql/migration/19.0.0-20.0.0.sql +++ b/htdocs/install/mysql/migration/19.0.0-20.0.0.sql @@ -244,6 +244,9 @@ ALTER TABLE llx_knowledgemanagement_knowledgerecord MODIFY COLUMN answer longtex ALTER TABLE llx_commande_fournisseur_dispatch_extrafields RENAME TO llx_receptiondet_batch_extrafields; ALTER TABLE llx_commande_fournisseur_dispatch RENAME TO llx_receptiondet_batch; +-- VPGSQL8.2 ALTER SEQUENCE llx_commande_fournisseur_dispatch_extrafields_rowid_seq RENAME TO llx_receptiondet_batch_extrafields_rowid_seq; +-- VPGSQL8.2 ALTER SEQUENCE llx_commande_fournisseur_dispatch_rowid_seq RENAME TO llx_receptiondet_batch_rowid_seq; + -- Rename const to add customer categories on not customer/prospect third-party if enabled UPDATE llx_const SET name = 'THIRDPARTY_CAN_HAVE_CUSTOMER_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT' WHERE name = 'THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER'; From 92baf3faa9dcb55388ff26a1d9a96e264f4bf77d Mon Sep 17 00:00:00 2001 From: John BOTELLA <68917336+thersane-john@users.noreply.github.com> Date: Thu, 20 Mar 2025 18:32:49 +0100 Subject: [PATCH 04/31] Fix : MAIN_SEARCH_PRODUCT_BY_FOURN_REF search critera (#33550) --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9d7837bcc26..699b0e2418e 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3089,7 +3089,7 @@ class Form // include search in supplier ref if (getDolGlobalString('MAIN_SEARCH_PRODUCT_BY_FOURN_REF')) { - $sqlSupplierSearch .= !empty($sqlSupplierSearch) ? ' OR ':''; + $sqlSupplierSearch .= !empty($sqlSupplierSearch) ? ' AND ':''; $sqlSupplierSearch .= " pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) . "%'"; } $sql .= ")"; From 7eb6a9e455db1add14a6e54129b2a6c47d653b9c Mon Sep 17 00:00:00 2001 From: Christophe Battarel Date: Thu, 20 Mar 2025 18:33:57 +0100 Subject: [PATCH 05/31] fix buy price (#33552) Co-authored-by: Christophe Battarel --- htdocs/mrp/mo_production.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 32a72dbccaa..d75b48d44f1 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -983,7 +983,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (empty($costprice)) { require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; $productFournisseur = new ProductFournisseur($db); - if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { + if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product, $line->qty) > 0) { $costprice = $productFournisseur->fourn_unitprice; } else { $costprice = 0; From cbb9f5aa0c8d2177786ce8f436cc0b171b3e14eb Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Mon, 24 Mar 2025 14:41:02 +0100 Subject: [PATCH 06/31] Replace hard coded value with var --- build/makepack-dolibarr.pl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index b7586e3909f..19cc4d457c4 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -18,9 +18,8 @@ use Term::ANSIColor; # Change this to defined target for option 98 and 99 $PROJECT="dolibarr"; -$PUBLISHSTABLE="eldy,dolibarr\@frs.sourceforge.net:/home/frs/project/dolibarr"; -$PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/dolibarr_documents/website/www.dolibarr.org/files"; - +$PUBLISHBETARC="$ENV{'DESTIASSLOGIN'}\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/dolibarr_documents/website/www.dolibarr.org/files"; +$PUBLISHSTABLE="$ENV{'DESTISFLOGIN'}\@frs.sourceforge.net:/home/frs/project/dolibarr"; #@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT"); # Possible packages @LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT"); # Possible packages From 9b36b6e965e6fa03c5338a2c9382aaf7ecb27bab Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Mon, 24 Mar 2025 14:43:40 +0100 Subject: [PATCH 07/31] Fix typo --- build/makepack-dolibarr.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 19cc4d457c4..b220311ded1 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -18,7 +18,7 @@ use Term::ANSIColor; # Change this to defined target for option 98 and 99 $PROJECT="dolibarr"; -$PUBLISHBETARC="$ENV{'DESTIASSLOGIN'}\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/dolibarr_documents/website/www.dolibarr.org/files"; +$PUBLISHBETARC="$ENV{'DESTIASSOLOGIN'}\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/dolibarr_documents/website/www.dolibarr.org/files"; $PUBLISHSTABLE="$ENV{'DESTISFLOGIN'}\@frs.sourceforge.net:/home/frs/project/dolibarr"; #@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT"); # Possible packages From 58039d4994f8f7a72145051092e3e0dadd880894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Cendrier?= <81741011+altairis-noe@users.noreply.github.com> Date: Wed, 26 Mar 2025 19:29:02 +0100 Subject: [PATCH 08/31] FIX: we must retrieve linked order_supplier and no other object (#33602) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * FIX: we must retrieve linked order_supplier preferably to any other object * FIX: better sourcetype verification, won’t collapse if order_supplier link is lost * FIX: typo --- htdocs/reception/class/reception.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 8478ac2a85b..7951b3347ee 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -378,7 +378,7 @@ class Reception extends CommonObject $sql .= ', e.fk_incoterms, e.location_incoterms'; $sql .= ', i.libelle as label_incoterms'; $sql .= " FROM ".MAIN_DB_PREFIX."reception as e"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element)."'"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element)."' AND el.sourcetype = 'order_supplier'"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON e.fk_incoterms = i.rowid'; $sql .= " WHERE e.entity IN (".getEntity('reception').")"; if ($id) { From 1a015cd91e9ef87c6267a89bab291b7dbde1b407 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 27 Mar 2025 15:01:50 +0100 Subject: [PATCH 09/31] Exclude more files --- build/tgz/tar_exclude.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build/tgz/tar_exclude.txt b/build/tgz/tar_exclude.txt index 4a69b4e87dc..99ad5eafb18 100644 --- a/build/tgz/tar_exclude.txt +++ b/build/tgz/tar_exclude.txt @@ -3,6 +3,11 @@ .git .gitignore .scrutinizer.yml +.travis.yml +.vscode +.idea +.editorconfig +.codeclimate.yml Thumbs.db build/exe build/html From 473e88a3e906e3d9ca64df545dd327bf83a594fd Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 28 Mar 2025 00:58:44 +0100 Subject: [PATCH 10/31] FIX syntax error on list of intervention for external users --- htdocs/fichinter/list.php | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index a2270349bab..665a9470b61 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -70,6 +70,12 @@ $toselect = GETPOST('toselect', 'array'); $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'interventionlist'; $mode = GETPOST('mode', 'alpha'); +if (getDolGlobalInt('MAIN_SEE_SUBORDINATES')) { + $userschilds = $user->getAllChildIds(); +} else { + $userschilds = array(); +} + $search_ref = GETPOST('search_ref') ? GETPOST('search_ref', 'alpha') : GETPOST('search_inter', 'alpha'); $search_ref_client = GETPOST('search_ref_client', 'alpha'); $search_company = GETPOST('search_company', 'alpha'); @@ -170,6 +176,7 @@ if ($user->socid) { } $result = restrictedArea($user, 'ficheinter', $id, 'fichinter'); +$permissiontoreadallthirdparty = $user->hasRight('societe', 'client', 'voir'); $permissiontoread = $user->hasRight('ficheinter', 'lire'); $permissiontoadd = $user->hasRight('ficheinter', 'creer'); $permissiontodelete = $user->hasRight('ficheinter', 'supprimer'); @@ -349,12 +356,18 @@ if (!getDolGlobalString('FICHINTER_DISABLE_DETAILS') && $atleastonefieldinlines) $sql .= " AND fd.date <= '".$db->idate($search_date_end)."'"; } } -if (!$user->hasRight('societe', 'client', 'voir')) { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); -} -if ($socid) { +if ($socid > 0) { $sql .= " AND s.rowid = ".((int) $socid); } +// Restriction on sale representative +if (empty($user->socid) && !$permissiontoreadallthirdparty) { + $sql .= " AND (EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = c.fk_soc AND sc.fk_user = ".((int) $user->id).")"; + if (getDolGlobalInt('MAIN_SEE_SUBORDINATES') && $userschilds) { + $sql .= " OR EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = c.fk_soc AND sc.fk_user IN (".$db->sanitize(implode(',', $userschilds))."))"; + } + $sql .= ")"; +} + if ($search_all) { $sql .= natural_search(array_keys($fieldstosearchall), $search_all); } From 0a1c338666f564fed1b51fd9faaf8eb612ad0eea Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 28 Mar 2025 03:07:34 +0100 Subject: [PATCH 11/31] Add log to help debug --- htdocs/public/payment/paymentok.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index aa46e7ccf0b..de5f0326059 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -1887,6 +1887,8 @@ if ($ispaymentok) { } } +dol_syslog("ispaymentok=".$ispaymentok." ispostactionok=".$ispostactionok." doactionsthenredirect=".$doactionsthenredirect, LOG_DEBUG, 0, '_payment'); + if ($ispaymentok) { // Get on url call $onlinetoken = empty($PAYPALTOKEN) ? $_SESSION['onlinetoken'] : $PAYPALTOKEN; From 7b58b23c973a853e0bb2c68f5e95da1b561cef7f Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 28 Mar 2025 03:25:41 +0100 Subject: [PATCH 12/31] FIX Redirect in PHP is reliable, not in Javascript ! --- htdocs/public/payment/paymentko.php | 11 ++++++++--- htdocs/public/payment/paymentok.php | 16 ++++++++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index 9372a667b1e..a19d8e40485 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -116,14 +116,14 @@ if (empty($paymentmethod)) { dol_print_error(null, 'The back url does not contain a parameter fulltag that should help us to find the payment method used'); exit; } else { - dol_syslog("paymentmethod=".$paymentmethod); + dol_syslog("paymentko.php: paymentmethod=".$paymentmethod, LOG_DEBUG, 0, '_payment'); } // Detect $ws $reg_ws = array(); $ws = preg_match('/WS=([^\.]+)/', $FULLTAG, $reg_ws) ? $reg_ws[1] : 0; if ($ws) { - dol_syslog("Paymentko.php page is invoked from a website with ref ".$ws.". It performs actions and then redirects back to this website. A page with ref paymentko must be created for this website.", LOG_DEBUG, 0, '_payment'); + dol_syslog("paymentko.php: page is invoked from a website with ref ".$ws.". It performs actions and then redirects back to this website. A page with ref paymentko must be created for this website.", LOG_DEBUG, 0, '_payment'); } @@ -354,5 +354,10 @@ if (!empty($doactionsthenredirect)) { $ext_urlko = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG; } - print ""; + dol_syslog("Now do a redirect to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); + + header("Location: ".$ext_urlko); + exit; + // Redirect in js is not reliable + //print ""; } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index de5f0326059..11f23d8e630 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -2150,7 +2150,13 @@ if (!empty($doactionsthenredirect)) { } else { $ext_urlok = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentok&fulltag='.$FULLTAG; } - print ""; + + dol_syslog("Now do a redirect to ".$ext_urlok, LOG_DEBUG, 0, '_payment'); + + header("Location: ".$ext_urlok); + exit; + // Redirect in js is not reliable + //print ""; } else { // Redirect to an error page // Paymentko page must be created for the specific website @@ -2159,6 +2165,12 @@ if (!empty($doactionsthenredirect)) { } else { $ext_urlko = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG; } - print ""; + + dol_syslog("Now do a redirect to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); + + header("Location: ".$ext_urlko); + exit; + // Redirect in js is not reliable + //print ""; } } From 74f85c86224064da73d3707c1f211396aa1186c0 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 28 Mar 2025 04:27:36 +0100 Subject: [PATCH 13/31] FIX Report by custom groupe was empty --- .../accountancy/class/accountancycategory.class.php | 4 ++-- htdocs/compta/resultat/result.php | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php index fbbdb35e7a8..c5cdcc1de72 100644 --- a/htdocs/accountancy/class/accountancycategory.class.php +++ b/htdocs/accountancy/class/accountancycategory.class.php @@ -784,11 +784,11 @@ class AccountancyCategory // extends CommonObject global $conf, $mysoc; if (empty($mysoc->country_id)) { - dol_print_error(null, 'Call to select_accounting_account with mysoc country not yet defined'); + dol_print_error(null, 'Call to getCats with mysoc country not yet defined'); exit(); } - $sql = "SELECT c.rowid, c.code, c.label, c.formula, c.position, c.category_type, c.sens"; + $sql = "SELECT c.rowid, c.code, c.label, c.formula, c.position, c.category_type, c.sens, c.fk_report"; $sql .= " FROM ".$this->db->prefix().$this->table_element." as c"; $sql .= " WHERE c.active = " . (int) $active; $sql .= " AND c.fk_report=".((int) $id_report); diff --git a/htdocs/compta/resultat/result.php b/htdocs/compta/resultat/result.php index 9a0c75af9f3..6b650051098 100644 --- a/htdocs/compta/resultat/result.php +++ b/htdocs/compta/resultat/result.php @@ -47,6 +47,9 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyreport.class.php'; $langs->loadLangs(array('compta', 'bills', 'donation', 'salaries', 'accountancy')); $id_report = GETPOSTINT('id_report'); +if ($id_report <= 0) { + $id_report = 1; +} $error = 0; @@ -337,6 +340,14 @@ if ($modecompta == 'CREANCES-DETTES') { $totPerAccount = array(); if (!is_array($cats) && $cats < 0) { setEventMessages(null, $AccCat->errors, 'errors'); + } elseif (is_array($cats) && count($cats) == 0) { + print ''; + print ''; + print ''; + print $langs->trans("ErrorNoAccountingCategoryForThisCountry", $mysoc->country_code, $langs->transnoentitiesnoconv("Accountancy"), $langs->transnoentitiesnoconv("Setup"), $langs->transnoentitiesnoconv("AccountingCategory")); + print ''; + print ''; + print ''; } elseif (is_array($cats) && count($cats) > 0) { // Loop on each custom group of accounts foreach ($cats as $cat) { From a8a95cba7566d2f9771431934b8924214396f758 Mon Sep 17 00:00:00 2001 From: Eric - CAP-REL <1468823+rycks@users.noreply.github.com> Date: Fri, 28 Mar 2025 10:19:08 +0100 Subject: [PATCH 14/31] debian build package on bookworm (#33635) --- build/makepack-dolibarr.pl | 181 +++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 88 deletions(-) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index b220311ded1..3ed19cf9f55 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -4,7 +4,7 @@ # \brief Dolibarr package builder (tgz, zip, rpm, deb, exe, aps) # \author (c)2004-2020 Laurent Destailleur # -# This is list of constant you can set to have generated packages moved into a specific dir: +# This is list of constant you can set to have generated packages moved into a specific dir: #DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild' #DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable' #DESTIMODULES='/media/HDDATA1_LD/Mes Sites/Web/Admin1/wwwroot/files/modules' @@ -35,7 +35,7 @@ $PUBLISHSTABLE="$ENV{'DESTISFLOGIN'}\@frs.sourceforge.net:/home/frs/project/doli "RPM_FEDORA"=>"rpmbuild", "RPM_MANDRIVA"=>"rpmbuild", "RPM_OPENSUSE"=>"rpmbuild", -"DEB"=>"dpkg dpatch", +"DEB"=>"dpkg", "FLATPACK"=>"flatpack", "EXEDOLIWAMP"=>"ISCC.exe", "SNAPSHOT"=>"tar" @@ -128,7 +128,7 @@ if (! $TEMP || ! -d $TEMP) { print "$PROG.$Extension aborted.\n"; sleep 2; exit 2; -} +} $BUILDROOT="$TEMP/buildroot"; @@ -171,7 +171,7 @@ $newbuild = $BUILD; $newbuild =~ s/(dev|alpha)/1/gi; # dev $newbuild =~ s/beta(.?)/2/gi; # beta (we want beta1, beta2, betax to be same package name) $newbuild =~ s/rc(.?)/3/gi; # rc (we want rc1, rc2, rcx to be same package name) -if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc. +if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc. # now newbuild is 0-1 or 0-4 for example. Note that for native package (see debian/source/format), we should not use a dash part but to get a better version management $build = $newbuild; $build =~ s/-.*$//g; @@ -189,8 +189,8 @@ for (0..@ARGV-1) { if ($ARGV[$_] =~ /^-*target=(\w+)/i) { $target=$1; $batch=1; } if ($ARGV[$_] =~ /^-*desti=(.+)/i) { $DESTI=$1; } if ($ARGV[$_] =~ /^-*prefix=(.+)/i) { - $PREFIX=$1; - $FILENAMESNAPSHOT.="-".$PREFIX; + $PREFIX=$1; + $FILENAMESNAPSHOT.="-".$PREFIX; } } if ($ENV{"DESTIBETARC"} && $BUILD =~ /[a-z]/i) { $DESTI = $ENV{"DESTIBETARC"}; } # Force output dir if env DESTIBETARC is defined @@ -209,7 +209,7 @@ print "Target directory (DESTI) : $DESTI\n"; # Choose package targets #----------------------- if ($target) { - if ($target eq "ALL") { + if ($target eq "ALL") { foreach my $key (@LISTETARGET) { if ($key ne 'SNAPSHOT' && $key ne 'SF' && $key ne 'ASSO') { $CHOOSEDTARGET{$key}=1; } } @@ -235,10 +235,10 @@ else { printf(" %2d - %-14s (%s)\n",$cpt,"ASSO (publish)","Need ".$REQUIREMENTPUBLISH{"ASSO"}); $cpt=99; printf(" %2d - %-14s (%s)\n",$cpt,"SF (publish)","Need ".$REQUIREMENTPUBLISH{"SF"}); - + # Ask which target to build print "Choose one target number or several separated with space (0 - ".$cpt."): "; - $NUM_SCRIPT=; + $NUM_SCRIPT=; chomp($NUM_SCRIPT); if ($NUM_SCRIPT !~ /^[0-9\s]+$/) { @@ -285,11 +285,11 @@ foreach my $target (sort keys %CHOOSEDTARGET) { print "Error: You asked creation of several rpms. Because all rpm have same name, you must defined an environment variable DESTI to tell packager where it can create subdirs for each generated package.\n"; exit; } - $atleastonerpm=1; - } - foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) + $atleastonerpm=1; + } + foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) { - # Test + # Test print "Test requirement for target $target: Search '$req'... "; $newreq=$req; $newparam=''; if ($newreq eq 'zip') { $newparam.='-h'; } @@ -298,12 +298,12 @@ foreach my $target (sort keys %CHOOSEDTARGET) { print "Test command ".$cmd."... "; $ret=`$cmd`; $coderetour=$?; $coderetour2=$coderetour>>8; - if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) { + if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) { # Not found error, we try in PROGPATH $ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`; $coderetour=$?; $coderetour2=$coderetour>>8; $REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req"; - } + } if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) { # Not found error @@ -332,7 +332,7 @@ $nbofpublishneedchangelog=0; foreach my $target (sort keys %CHOOSEDTARGET) { if ($target eq '-CHKSUM') { $nbofpublishneedchangelog++; } if ($CHOOSEDTARGET{$target} < 0) { next; } - if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM') + if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM') { $nboftargetneedbuildroot++; } @@ -396,10 +396,10 @@ if ($nboftargetok) { print "Go to directory $SOURCE\n"; $olddir=getcwd(); chdir("$SOURCE"); - + print "Clean $SOURCE/htdocs/includes/autoload.php\n"; $ret=`rm -f $SOURCE/htdocs/includes/autoload.php`; - + $ret=`git ls-files . --exclude-standard --others`; if ($ret) { @@ -408,7 +408,7 @@ if ($nboftargetok) { print "Canceled.\n"; exit; } - + print 'Create xml check file with md5 checksum with command php '.$SOURCE.'/build/generate_filelist_xml.php release='.$MAJOR.'.'.$MINOR.'.'.$BUILD."\n"; $ret=`php $SOURCE/build/generate_filelist_xml.php release=$MAJOR.$MINOR.$BUILD`; print $ret."\n"; @@ -426,13 +426,13 @@ if ($nboftargetok) { print "Go to directory $SOURCE\n"; $olddir=getcwd(); chdir("$SOURCE"); - + print 'Run git tag -a -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n"; $ret=`git tag -a -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD" 2>&1`; if ($ret =~ /(already exists|existe déjà)/) { print "WARNING: Tag ".$MAJOR.'.'.$MINOR.'.'.$BUILD." already exists. Overwrite (y/N) ? "; - $QUESTIONOVERWRITETAG=; + $QUESTIONOVERWRITETAG=; chomp($QUESTIONOVERWRITETAG); if ($QUESTIONOVERWRITETAG =~ /(o|y)/) { @@ -451,7 +451,7 @@ if ($nboftargetok) { } chdir("$olddir"); } - + # Update buildroot if required #----------------------------- if ($nboftargetneedbuildroot) @@ -461,7 +461,7 @@ if ($nboftargetok) { print "Delete directory $BUILDROOT\n"; $ret=`rm -fr "$BUILDROOT"`; - + mkdir "$BUILDROOT"; mkdir "$BUILDROOT/$PROJECT"; print "Copy $SOURCE into $BUILDROOT/$PROJECT\n"; @@ -487,7 +487,7 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/phpstan.neon`; $ret=`rm -f $BUILDROOT/$PROJECT/pom.xml`; $ret=`rm -f $BUILDROOT/$PROJECT/README-*.md`; - + $ret=`rm -fr $BUILDROOT/$PROJECT/build/html`; $ret=`rm -f $BUILDROOT/$PROJECT/build/Doli*-*`; $ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr_*.deb`; @@ -554,20 +554,20 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot11.png`; $ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot12.png`; - # Security to avoid to package data files + # Security to avoid to package data files print "Remove documents dir\n"; $ret=`rm -fr $BUILDROOT/$PROJECT/document`; $ret=`rm -fr $BUILDROOT/$PROJECT/documents`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/document`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/documents`; - + print "Remove subdir of custom dir\n"; print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\;\n"; $ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs but not files print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\;\n"; $ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs, even symbolic links, but not files - # Removed known external modules to avoid any error when packaging from env where external modules are tested + # Removed known external modules to avoid any error when packaging from env where external modules are tested $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/abricot*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/accountingexport*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/allscreens*`; @@ -592,15 +592,15 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/webmail*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/theme/common/fontawesome-5/svgs`; - + # Removed other test files $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/public/test`; $ret=`rm -fr $BUILDROOT/$PROJECT/test`; $ret=`rm -fr $BUILDROOT/$PROJECT/Thumbs.db $BUILDROOT/$PROJECT/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/*/Thumbs.db`; $ret=`rm -f $BUILDROOT/$PROJECT/.cvsignore $BUILDROOT/$PROJECT/*/.cvsignore $BUILDROOT/$PROJECT/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.cvsignore`; $ret=`rm -f $BUILDROOT/$PROJECT/.gitignore $BUILDROOT/$PROJECT/*/.gitignore $BUILDROOT/$PROJECT/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.gitignore`; - - # Removed files installed by the awful composer + + # Removed files installed by the awful composer $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/geoip/sample*.*`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/bin`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/ckeditor/ckeditor/adapters`; # Keep this removal in case we embed libraries @@ -639,14 +639,14 @@ if ($nboftargetok) { # Build package for each target #------------------------------ - foreach my $target (sort keys %CHOOSEDTARGET) + foreach my $target (sort keys %CHOOSEDTARGET) { if ($CHOOSEDTARGET{$target} < 0) { next; } if ($target eq '-CHKSUM') { next; } - + print "\nBuild package for target $target\n"; - if ($target eq 'SNAPSHOT') + if ($target eq 'SNAPSHOT') { $NEWDESTI=$DESTI; @@ -670,13 +670,13 @@ if ($nboftargetok) { next; } - if ($target eq 'TGZ') + if ($target eq 'TGZ') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); - if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } + if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } } print "Remove target $FILENAMETGZ.tgz...\n"; @@ -690,7 +690,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$FILENAMETGZ/build/exe`; $ret=`rm -fr $BUILDROOT/$FILENAMETGZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages - + print "Compress $FILENAMETGZ into $FILENAMETGZ.tgz...\n"; $cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMETGZ.tgz\" $FILENAMETGZ"; print "$cmd\n"; @@ -702,14 +702,14 @@ if ($nboftargetok) { next; } - if ($target eq 'XZ') + if ($target eq 'XZ') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } - } + } print "Remove target $FILENAMEXZ.xz...\n"; unlink("$NEWDESTI/$FILENAMEXZ.xz"); @@ -722,7 +722,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$FILENAMEXZ/build/exe`; $ret=`rm -fr $BUILDROOT/$FILENAMEXZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages - + print "Compress $FILENAMEXZ into $FILENAMEXZ.xz...\n"; print "Go to directory $BUILDROOT\n"; @@ -738,15 +738,15 @@ if ($nboftargetok) { $ret=`mv "$BUILDROOT/$FILENAMEXZ.xz" "$NEWDESTI/$FILENAMEXZ.xz"`; next; } - - if ($target eq 'ZIP') + + if ($target eq 'ZIP') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } - } + } print "Remove target $FILENAMEZIP.zip...\n"; unlink("$NEWDESTI/$FILENAMEZIP.zip"); @@ -769,14 +769,14 @@ if ($nboftargetok) { print $cmd."\n"; $ret= `$cmd`; chdir("$olddir"); - + # Move to final dir print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n"; $ret=`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`; next; } - - if ($target =~ /RPM/) # Linux only + + if ($target =~ /RPM/) # Linux only { $NEWDESTI=$DESTI; $subdir="package_rpm_generic"; @@ -787,7 +787,7 @@ if ($nboftargetok) { { mkdir($DESTI.'/'.$subdir); if (-d $DESTI.'/'.$subdir) { $NEWDESTI=$DESTI.'/'.$subdir; } - } + } if ($RPMDIR eq "") { $RPMDIR=$ENV{'HOME'}."/rpmbuild"; } @@ -800,7 +800,7 @@ if ($nboftargetok) { print "Create directory $BUILDROOT/$FILENAMETGZ2\n"; $ret=`rm -fr $BUILDROOT/$FILENAMETGZ2`; - + print "Copy $BUILDROOT/$PROJECT to $BUILDROOT/$FILENAMETGZ2\n"; $cmd="cp -pr '$BUILDROOT/$PROJECT' '$BUILDROOT/$FILENAMETGZ2'"; $ret=`$cmd`; @@ -826,7 +826,7 @@ if ($nboftargetok) { if ($target =~ /FEDO/i) { $BUILDFICSRC="${FILENAME}_fedora.spec"; } if ($target =~ /MAND/i) { $BUILDFICSRC="${FILENAME}_mandriva.spec"; } if ($target =~ /OPEN/i) { $BUILDFICSRC="${FILENAME}_opensuse.spec"; } - + use Date::Language; $lang=Date::Language->new('English'); $datestring = $lang->time2str("%a %b %e %Y", time); @@ -844,7 +844,7 @@ if ($nboftargetok) { } close SPECFROM; close SPECTO; - + print "Copy patch file to $RPMDIR/SOURCES\n"; $ret=`cp "$SOURCE/build/rpm/dolibarr-forrpm.patch" "$RPMDIR/SOURCES"`; $ret=`chmod 644 $RPMDIR/SOURCES/dolibarr-forrpm.patch`; @@ -866,14 +866,14 @@ if ($nboftargetok) { next; } - if ($target eq 'DEB') + if ($target eq 'DEB') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/package_debian-ubuntu'); if (-d $DESTI.'/package_debian-ubuntu') { $NEWDESTI=$DESTI.'/package_debian-ubuntu'; } - } + } $olddir=getcwd(); @@ -954,13 +954,18 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/jquery/plugins/select2/LICENSE`; $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mike42/escpos-php/LICENSE.md`; $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mobiledetect/mobiledetectlib/LICENSE.txt`; - + # Removed files we don't need (already removed) #$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/ckeditor/ckeditor/_source`; - + $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/.codeclimate.yml`; + $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/.pre-commit-config.yaml`; + $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/.vscode`; + $ret=`find $BUILDROOT/$PROJECT.tmp/ -type f -name '.editorconfig' -exec rm {} \\;`; + $ret=`find $BUILDROOT/$PROJECT.tmp/ -type f -name '.travis.yml' -exec rm {} \\;`; + # Rename upstream changelog to match debian rules $ret=`mv $BUILDROOT/$PROJECT.tmp/ChangeLog $BUILDROOT/$PROJECT.tmp/changelog`; - + # Prepare source package (init debian dir) print "Create directory $BUILDROOT/$PROJECT.tmp/debian\n"; $ret=`mkdir "$BUILDROOT/$PROJECT.tmp/debian"`; @@ -998,7 +1003,7 @@ if ($nboftargetok) { $ret=`cp -f "$SOURCE/build/debian/dolibarr.postrm" "$BUILDROOT/$PROJECT.tmp/debian"`; $ret=`cp -f "$SOURCE/build/debian/dolibarr.templates" "$BUILDROOT/$PROJECT.tmp/debian"`; $ret=`cp -f "$SOURCE/build/debian/install.forced.php.install" "$BUILDROOT/$PROJECT.tmp/debian"`; - + # Set owners and permissions #print "Set owners on files/dir\n"; #$ret=`chown -R root.root $BUILDROOT/$PROJECT.tmp`; @@ -1029,8 +1034,8 @@ if ($nboftargetok) { $ret=`$cmd`; $cmd="find $BUILDROOT/$PROJECT.tmp/scripts -name '*.sh' -type f -exec chmod 755 {} \\; "; $ret=`$cmd`; - - + + print "Rename directory $BUILDROOT/$PROJECT.tmp into $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n"; $cmd="mv $BUILDROOT/$PROJECT.tmp $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"; $ret=`$cmd`; @@ -1038,14 +1043,14 @@ if ($nboftargetok) { print "Go into directory $BUILDROOT\n"; chdir("$BUILDROOT"); - + # We need a tarball to be able to build "quilt" debian package (not required for native but we need patch so it is not a native) print "Compress $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build into $BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz...\n"; $cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz\" $PROJECT-$MAJOR.$MINOR.$build"; print $cmd."\n"; $ret=`$cmd`; - # Creation of source package + # Creation of source package print "Go into directory $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n"; chdir("$BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"); #$cmd="dpkg-source -b $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"; @@ -1064,12 +1069,12 @@ if ($nboftargetok) { $ret=`mv $BUILDROOT/*_all.deb "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.dsc "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.orig.tar.gz "$NEWDESTI/"`; - #$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option + #$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option $ret=`mv $BUILDROOT/*.debian.tar.gz "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.changes "$NEWDESTI/"`; next; } - + if ($target eq 'EXEDOLIWAMP') { $NEWDESTI=$DESTI; @@ -1077,22 +1082,22 @@ if ($nboftargetok) { { mkdir($DESTI.'/package_windows'); if (-d $DESTI.'/package_windows') { $NEWDESTI=$DESTI.'/package_windows'; } - } + } print "Remove target $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe...\n"; unlink "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"; - + if ($OS eq 'windows') { print "Check that ISCC.exe is in your PATH.\n"; } else { print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n"; } - + $SOURCEBACK=$SOURCE; $SOURCEBACK =~ s/\//\\/g; print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n"; - + #$ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; open(IN, '<' . $SOURCE."/build/exe/doliwamp/doliwamp.iss") or die $!; open(OUT, '>' . "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss") or die $!; @@ -1105,7 +1110,7 @@ if ($nboftargetok) { close(OUT); print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" on OS $OS\n"; - + if ($OS eq 'windows') { $cmd= "ISCC.exe \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\""; } else { @@ -1119,26 +1124,26 @@ if ($nboftargetok) { print "Move \"$SOURCE\\build\\$FILENAMEEXEDOLIWAMP.exe\" to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n"; rename("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe","$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"); print "Move $SOURCE/build/$FILENAMEEXEDOLIWAMP.exe to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n"; - + use File::Copy; #$ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`; $ret=move("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe", "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"); - + print "Remove tmp file $SOURCE/build/exe/doliwamp/doliwamp.tmp.iss\n"; #$ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; $ret=unlink("$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"); - + next; } } # Publish package for each target #-------------------------------- - foreach my $target (sort keys %CHOOSEDPUBLISH) + foreach my $target (sort keys %CHOOSEDPUBLISH) { if ($CHOOSEDPUBLISH{$target} < 0) { next; } - + print "\nList of files to publish (BUILD=$BUILD)\n"; %filestoscansf=( "$DESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml"=>'none', # none means it won't be published on SF @@ -1196,26 +1201,26 @@ if ($nboftargetok) { print "\n"; } - if ($target eq 'SF' || $target eq 'ASSO') + if ($target eq 'SF' || $target eq 'ASSO') { print "\n"; - + if ($target eq 'SF') { $PUBLISH = $PUBLISHSTABLE; } if ($target eq 'ASSO' && $BUILD =~ /[a-z]/i) { $PUBLISH = $PUBLISHBETARC.'/lastbuild'; } if ($target eq 'ASSO' && $BUILD =~ /^[0-9]+$/) { $PUBLISH = $PUBLISHBETARC.'/stable'; } - + $NEWPUBLISH=$PUBLISH; print "Publish to target $NEWPUBLISH. Click enter or CTRL+C...\n"; # Ask which target to build - $NUM_SCRIPT=; + $NUM_SCRIPT=; chomp($NUM_SCRIPT); print "Create empty dir /tmp/emptydir. We need it to create target dir using rsync.\n"; $ret=`mkdir -p "/tmp/emptydir/"`; - + %filestoscan=%filestoscansf; - + foreach my $file (sort keys %filestoscan) { $found=0; @@ -1225,30 +1230,30 @@ if ($nboftargetok) { if ($target eq 'SF') { if ($filestoscan{$file} eq 'none') { next; - } + } $destFolder="$NEWPUBLISH/$filestoscan{$file}/".$MAJOR.'.'.$MINOR.'.'.$BUILD; } elsif ($target eq 'ASSO' and $NEWPUBLISH =~ /stable/) { $destFolder="$NEWPUBLISH/$filestoscanstableasso{$file}"; - } + } elsif ($target eq 'ASSO' and $NEWPUBLISH !~ /stable/) { $destFolder="$NEWPUBLISH"; - } + } else # No more used { $dirnameonly=$file; - $dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/; + $dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/; $filenameonly=$file; - $filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/; + $filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/; $destFolder="$NEWPUBLISH/$dirnameonly"; } print "\n"; print "Publish file ".$file." to ".$destFolder."\n"; - # mkdir + # mkdir #my $ssh = Net::SSH::Perl->new("frs.sourceforge.net"); - #$ssh->login("$user","$pass"); + #$ssh->login("$user","$pass"); #use String::ShellQuote qw( shell_quote ); #$ssh->cmd('mkdir '.shell_quote($destFolder).' && exit'); @@ -1257,20 +1262,20 @@ if ($nboftargetok) { #$sftp->mkdir($destFolder) #$command="ssh eldy,dolibarr\@frs.sourceforge.net mkdir -p \"$destFolder\""; - #print "$command\n"; + #print "$command\n"; #my $ret=`$command 2>&1`; $command="rsync -s -e 'ssh' --recursive /tmp/emptydir/ \"".$destFolder."\""; - print "$command\n"; + print "$command\n"; my $ret=`$command 2>&1`; $command="rsync -s -e 'ssh' \"$file\" \"".$destFolder."\""; - print "$command\n"; + print "$command\n"; my $ret2=`$command 2>&1`; print "$ret2\n"; } } - } + } } print "\n----- Summary -----\n"; From 70e4d1ccd0dc3c9618894407cd23bed1022b3011 Mon Sep 17 00:00:00 2001 From: Eric - CAP-REL <1468823+rycks@users.noreply.github.com> Date: Fri, 28 Mar 2025 15:00:37 +0100 Subject: [PATCH 15/31] build zip & tar package : add more files on exclude list (#33634) --- build/tgz/tar_exclude.txt | 2 ++ build/zip/zip_exclude.txt | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/build/tgz/tar_exclude.txt b/build/tgz/tar_exclude.txt index 99ad5eafb18..0c134e621b1 100644 --- a/build/tgz/tar_exclude.txt +++ b/build/tgz/tar_exclude.txt @@ -8,6 +8,8 @@ .idea .editorconfig .codeclimate.yml +.pre-commit-config.yaml +.mailmap Thumbs.db build/exe build/html diff --git a/build/zip/zip_exclude.txt b/build/zip/zip_exclude.txt index 88bd22826ff..cd8d98469a2 100644 --- a/build/zip/zip_exclude.txt +++ b/build/zip/zip_exclude.txt @@ -22,3 +22,9 @@ dolibarr*.deb dolibarr*.zip cvschangelogbuilder_dolibarr* dolibarr_install.log +.travis.yml +.vscode +.idea +.editorconfig +.codeclimate.yml +.pre-commit-config.yaml From 1b9ff5ee96ebe0291e73026e1510f6b122a384c9 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 28 Mar 2025 16:02:40 +0100 Subject: [PATCH 16/31] FIX Must make different redirect according to frame or not. --- htdocs/public/payment/paymentko.php | 13 +++++++++---- htdocs/public/payment/paymentok.php | 24 ++++++++++++++++-------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index a19d8e40485..cc1c578a1fb 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -142,6 +142,7 @@ $error = 0; // Check if we have redirtodomain to do. $ws_virtuelhost = null; +$ws_id = 0; $doactionsthenredirect = 0; if ($ws) { $doactionsthenredirect = 1; @@ -150,6 +151,7 @@ if ($ws) { $result = $website->fetch(0, $ws); if ($result > 0) { $ws_virtuelhost = $website->virtualhost; + $ws_id = $website->id; } } @@ -356,8 +358,11 @@ if (!empty($doactionsthenredirect)) { dol_syslog("Now do a redirect to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); - header("Location: ".$ext_urlko); - exit; - // Redirect in js is not reliable - //print ""; + if (getDolGlobalString('WEBSITE_PAYMENT_IN_FRAME_'.$ws_id)) { + // Redirect in js is not reliable + print ""; + } else { + header("Location: ".$ext_urlko); + exit; + } } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 11f23d8e630..76cb7b13b87 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -174,6 +174,7 @@ $error = 0; // Check if we have redirtodomain to do. $ws_virtuelhost = null; +$ws_id = 0; $doactionsthenredirect = 0; if ($ws) { $doactionsthenredirect = 1; @@ -182,6 +183,7 @@ if ($ws) { $result = $website->fetch(0, $ws); if ($result > 0) { $ws_virtuelhost = $website->virtualhost; + $ws_id = $website->id; } } @@ -2153,10 +2155,13 @@ if (!empty($doactionsthenredirect)) { dol_syslog("Now do a redirect to ".$ext_urlok, LOG_DEBUG, 0, '_payment'); - header("Location: ".$ext_urlok); - exit; - // Redirect in js is not reliable - //print ""; + if (getDolGlobalString('WEBSITE_PAYMENT_IN_FRAME_'.$ws_id)) { + // Redirect in js is not reliable + print ""; + } else { + header("Location: ".$ext_urlok); + exit; + } } else { // Redirect to an error page // Paymentko page must be created for the specific website @@ -2168,9 +2173,12 @@ if (!empty($doactionsthenredirect)) { dol_syslog("Now do a redirect to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); - header("Location: ".$ext_urlko); - exit; - // Redirect in js is not reliable - //print ""; + if (getDolGlobalString('WEBSITE_PAYMENT_IN_FRAME_'.$ws_id)) { + // Redirect in js is not reliable + print ""; + } else { + header("Location: ".$ext_urlko); + exit; + } } } From 21ce661927e11c18932c19ce6fb6d976f064e0d6 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 28 Mar 2025 16:14:14 +0100 Subject: [PATCH 17/31] Add a condition for the redirect --- htdocs/public/payment/paymentko.php | 2 +- htdocs/public/payment/paymentok.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index cc1c578a1fb..c08859fe345 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -358,7 +358,7 @@ if (!empty($doactionsthenredirect)) { dol_syslog("Now do a redirect to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); - if (getDolGlobalString('WEBSITE_PAYMENT_IN_FRAME_'.$ws_id)) { + if (getDolGlobalString('MARKETPLACE_PAYMENT_IN_FRAME')) { // TODO Use a property in website module // Redirect in js is not reliable print ""; } else { diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 76cb7b13b87..09f9131b6e2 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -2155,7 +2155,7 @@ if (!empty($doactionsthenredirect)) { dol_syslog("Now do a redirect to ".$ext_urlok, LOG_DEBUG, 0, '_payment'); - if (getDolGlobalString('WEBSITE_PAYMENT_IN_FRAME_'.$ws_id)) { + if (getDolGlobalString('MARKETPLACE_PAYMENT_IN_FRAME')) { // TODO Use a property in website module // Redirect in js is not reliable print ""; } else { @@ -2173,7 +2173,7 @@ if (!empty($doactionsthenredirect)) { dol_syslog("Now do a redirect to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); - if (getDolGlobalString('WEBSITE_PAYMENT_IN_FRAME_'.$ws_id)) { + if (getDolGlobalString('MARKETPLACE_PAYMENT_IN_FRAME')) { // TODO Use a property in website module // Redirect in js is not reliable print ""; } else { From 2945f0d7ae2f94056523aad44826747f1daf7fc9 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 28 Mar 2025 16:28:00 +0100 Subject: [PATCH 18/31] Allow different mode of redirect in website payment --- htdocs/public/payment/paymentko.php | 6 ++++-- htdocs/public/payment/paymentok.php | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index c08859fe345..e1069312d52 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -356,12 +356,14 @@ if (!empty($doactionsthenredirect)) { $ext_urlko = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG; } - dol_syslog("Now do a redirect to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); + if (getDolGlobalInt('MARKETPLACE_PAYMENT_IN_FRAME') == 1) { // TODO Use a property in website module + dol_syslog("Now do a redirect in iframe mode in js to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); - if (getDolGlobalString('MARKETPLACE_PAYMENT_IN_FRAME')) { // TODO Use a property in website module // Redirect in js is not reliable print ""; } else { + dol_syslog("Now do a redirect using Location : ".$ext_urlko, LOG_DEBUG, 0, '_payment'); + header("Location: ".$ext_urlko); exit; } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 09f9131b6e2..fcb4486f99b 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -2153,12 +2153,14 @@ if (!empty($doactionsthenredirect)) { $ext_urlok = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentok&fulltag='.$FULLTAG; } - dol_syslog("Now do a redirect to ".$ext_urlok, LOG_DEBUG, 0, '_payment'); + if (getDolGlobalInt('MARKETPLACE_PAYMENT_IN_FRAME') == 1) { // TODO Use a property in website module + dol_syslog("Now do a redirect in iframe mode in js to ".$ext_urlok, LOG_DEBUG, 0, '_payment'); - if (getDolGlobalString('MARKETPLACE_PAYMENT_IN_FRAME')) { // TODO Use a property in website module // Redirect in js is not reliable print ""; } else { + dol_syslog("Now do a redirect using a Location: ".$ext_urlok, LOG_DEBUG, 0, '_payment'); + header("Location: ".$ext_urlok); exit; } @@ -2171,12 +2173,14 @@ if (!empty($doactionsthenredirect)) { $ext_urlko = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG; } - dol_syslog("Now do a redirect to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); + if (getDolGlobalInt('MARKETPLACE_PAYMENT_IN_FRAME') == 1) { // TODO Use a property in website module + dol_syslog("Now do a redirect in iframe mode in js to ".$ext_urlko, LOG_DEBUG, 0, '_payment'); - if (getDolGlobalString('MARKETPLACE_PAYMENT_IN_FRAME')) { // TODO Use a property in website module // Redirect in js is not reliable print ""; } else { + dol_syslog("Now do a redirect using a Location:".$ext_urlko, LOG_DEBUG, 0, '_payment'); + header("Location: ".$ext_urlko); exit; } From 4f00b49babd8e7fc8aaaa7ab0da6e5fa842cd7e6 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 28 Mar 2025 21:02:27 +0100 Subject: [PATCH 19/31] Fix reliability of ip in logs --- htdocs/core/lib/functions.lib.php | 83 +++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 17355e38a10..05e317ef11a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2446,14 +2446,57 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename = 'ospid' => getmypid() // on linux, max value is defined into cat /proc/sys/kernel/pid_max ); - $remoteip = getUserRemoteIP(); // Get ip when page run on a web server + // For log, we want the reliable IP first. + $remoteip = getUserRemoteIP(1); // Get ip when page run on a web server if (!empty($remoteip)) { $data['ip'] = $remoteip; // This is when server run behind a reverse proxy - if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != $remoteip) { - $data['ip'] = $_SERVER['HTTP_X_FORWARDED_FOR'].' -> '.$data['ip']; - } elseif (!empty($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != $remoteip) { - $data['ip'] = $_SERVER['HTTP_CLIENT_IP'].' -> '.$data['ip']; + // A HTTP_X_FORWARDED_FOR as format "ip real of user, ip of proxy1, ip of proxy2, ..." + // $data['ip'] is last + if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $tmpips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + $data['ip'] = ''; + $foundremoteip = 0; + $j = 0; + foreach ($tmpips as $tmpip) { + $tmpip = trim($tmpip); + if (strtolower($tmpip) == strtolower($remoteip)) { + $foundremoteip = 1; + } + if (empty($data['ip'])) { + $data['ip'] = $tmpip; + } else { + $j++; + $data['ip'] .= (($j == 1) ? ' [via ' : ',').$tmpip; + } + } + if (!$foundremoteip) { + $j++; + $data['ip'] .= (($j == 1) ? ' [via ' : ',').$remoteip; + } + $data['ip'] .= (($j > 0) ? ']' : ''); + } elseif (!empty($_SERVER['HTTP_CLIENT_IP']) ) { + $tmpips = explode(',', $_SERVER['HTTP_CLIENT_IP']); + $data['ip'] = ''; + $foundremoteip = 0; + $j = 0; + foreach ($tmpips as $tmpip) { + $tmpip = trim($tmpip); + if (strtolower($tmpip) == strtolower($remoteip)) { + $foundremoteip = 1; + } + if (empty($data['ip'])) { + $data['ip'] = $tmpip; + } else { + $j++; + $data['ip'] .= (($j == 1) ? ' [via ' : ',').$tmpip; + } + } + if (!$foundremoteip) { + $j++; + $data['ip'] .= (($j == 1) ? ' [via ' : ',').$remoteip; + } + $data['ip'] .= (($j > 0) ? ']' : ''); } } elseif (!empty($_SERVER['SERVER_ADDR'])) { // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) @@ -4635,27 +4678,39 @@ function dol_print_ip($ip, $mode = 0) } /** - * Return the IP of remote user. + * Return the real IP of remote user. * Take HTTP_X_FORWARDED_FOR (defined when using proxy) * Then HTTP_CLIENT_IP if defined (rare) - * Then REMOTE_ADDR (no way to be modified by user but may be wrong if user is using a proxy) + * Then REMOTE_ADDR (the last seerver ip in proxy chain). + * REMOTE_ADDR can't be modified by client and may be the IP of a proxy. + * Note: that if Apache module "remoteip" module is on, $_SERVER["REMOTE_ADDR"] may be replaced y HTTP_X_FORWARDED_FOR directly + * from CF-Connecting-IP, but only if remote is in trusted cloudflare list. * - * @return string Ip of remote user. + * @param int $trusted 0=Default, 1=Trusted value (the last IP that was not altered by client) + * @return string Real IP of remote user. */ -function getUserRemoteIP() +function getUserRemoteIP($trusted = 0) { - if (empty($_SERVER['HTTP_X_FORWARDED_FOR']) || preg_match('/[^0-9\.\:,\[\]]/', $_SERVER['HTTP_X_FORWARDED_FOR'])) { - if (empty($_SERVER['HTTP_CLIENT_IP']) || preg_match('/[^0-9\.\:,\[\]]/', $_SERVER['HTTP_CLIENT_IP'])) { + if ($trusted) { // Return only IP we can rely on (not spoofable by the client) + $ip = (empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']); // value may be the IP of a proxy + // Note that if apache module remoteip has been enabled, REMOTE_ADDR can contain the real client (the value from cloudFlare HTTP_CF_CONNECTING_IP for example) + // if the proxy were added in the list of trusted proxy. + return $ip; + } + + // Try to guess the real IP of client (but this may not be reliable) + if (empty($_SERVER['HTTP_X_FORWARDED_FOR']) || preg_match('/[^0-9\.\:,\[\]\s]/', $_SERVER['HTTP_X_FORWARDED_FOR'])) { + if (empty($_SERVER['HTTP_CLIENT_IP']) || preg_match('/[^0-9\.\:,\[\]\s]/', $_SERVER['HTTP_CLIENT_IP'])) { if (empty($_SERVER["HTTP_CF_CONNECTING_IP"])) { - $ip = (empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']); // value may have been the IP of the proxy and not the client + $ip = (empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']); // value may be the IP of the proxy and not the client } else { $ip = $_SERVER["HTTP_CF_CONNECTING_IP"]; // value here may have been forged by client } } else { - $ip = $_SERVER['HTTP_CLIENT_IP']; // value is clean here but may have been forged by proxy + $ip = preg_replace('/,.*$/', '', $_SERVER['HTTP_CLIENT_IP']); // value is clean here but may have been forged by proxy } } else { - $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; // value is clean here but may have been forged by proxy + $ip = preg_replace('/,.*$/', '', $_SERVER['HTTP_X_FORWARDED_FOR']); // value is clean here but may have been forged by proxy } return $ip; } From e6ebf315edb25d072c090876ec1baeebd6d231f1 Mon Sep 17 00:00:00 2001 From: Eric - CAP-REL <1468823+rycks@users.noreply.github.com> Date: Fri, 28 Mar 2025 23:09:50 +0100 Subject: [PATCH 20/31] package: make dir if needed (#33644) --- build/makepack-dolibarr.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 3ed19cf9f55..e7967211a2a 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -414,6 +414,10 @@ if ($nboftargetok) { print $ret."\n"; # Copy to final dir $NEWDESTI=$DESTI; + if ( !-d "$NEWDESTI/signatures" ) { + use File::Path qw( make_path ); + make_path "$NEWDESTI/signatures" or die "Failed to create path: $NEWDESTI/signatures"; + } print "Copy \"$SOURCE/htdocs/install/filelist-$MAJOR.$MINOR.$BUILD.xml\" to $NEWDESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml\n"; use File::Copy qw(copy); copy "$SOURCE/htdocs/install/filelist-$MAJOR.$MINOR.$BUILD.xml", "$NEWDESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml"; From f48682da436b61f41cedcf0e19d41cfba96ca80c Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Sat, 29 Mar 2025 12:16:56 +0100 Subject: [PATCH 21/31] Fix menu link --- htdocs/core/menus/standard/eldy.lib.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 0e78a5f0cb8..ffa9d644313 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1868,8 +1868,9 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef $i++; } } else { - // Should not happen. Entries are added - $newmenu->add('', $langs->trans("NoReportDefined"), 3, $user->hasRight('accounting', 'comptarapport', 'lire')); + // Should not happen. We keep a link in case it happen to go to the page to explain how to create custom groups. + $newmenu->add("/compta/resultat/result.php?mainmenu=accountancy&leftmenu=accountancy_report", $langs->trans("ByPersonalizedAccountGroups"), 3, $user->hasRight('accounting', 'comptarapport', 'lire')); + //$newmenu->add('', $langs->trans("NoReportDefined"), 3, 0); } } else { dol_print_error($db); From 5c6094aa53d70b6a3e5a59b5eb65458da376b9b6 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Sat, 29 Mar 2025 12:17:37 +0100 Subject: [PATCH 22/31] Comment --- htdocs/accountancy/class/accountancycategory.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php index c5cdcc1de72..a3704753135 100644 --- a/htdocs/accountancy/class/accountancycategory.class.php +++ b/htdocs/accountancy/class/accountancycategory.class.php @@ -618,7 +618,7 @@ class AccountancyCategory // extends CommonObject } /** - * Function to show result of an accounting account from the ledger with a direction and a period + * Function to set the property ->sdc (and ->sdcperaccount) that is the result of an accounting account from the ledger with a direction and a period * * @param int|array $cpt Accounting account or array of accounting account * @param int $date_start Date start From 7c7e4ac74467b2c9ce10059bef95035120addc3f Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Sat, 29 Mar 2025 12:30:27 +0100 Subject: [PATCH 23/31] Fix CI (property dc not defined) --- htdocs/accountancy/class/accountancycategory.class.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php index a3704753135..8c630831b7a 100644 --- a/htdocs/accountancy/class/accountancycategory.class.php +++ b/htdocs/accountancy/class/accountancycategory.class.php @@ -712,7 +712,7 @@ class AccountancyCategory // extends CommonObject * Function to get an array of all active custom groups (llx_c_accunting_categories) with their accounts from the chart of account (ll_accounting_acount) * * @param int $catid Custom group ID - * @return array>|int<-1,-1> Result in table (array), -1 if KO + * @return array>|int<-1,-1> Result in table (array), -1 if KO * @see getCats(), getCptsCat() */ public function getCatsCpts($catid = 0) @@ -756,6 +756,7 @@ class AccountancyCategory // extends CommonObject 'category_type' => $obj->category_type, 'formula' => $obj->formula, 'sens' => $obj->sens, + 'dc' => $obj->sens, 'account_number' => $obj->account_number, 'account_label' => $obj->account_label ); @@ -776,7 +777,7 @@ class AccountancyCategory // extends CommonObject * @param int $categorytype -1=All, 0=Only non computed groups, 1=Only computed groups * @param int $active 1= active, 0=not active * @param int $id_report id of the report - * @return never|array|int Array of groups or -1 if error + * @return never|array|int Array of groups or -1 if error * @see getCatsCpts(), getCptsCat() */ public function getCats($categorytype = -1, $active = 1, $id_report = 1) @@ -817,7 +818,7 @@ class AccountancyCategory // extends CommonObject 'category_type' => $obj->category_type, 'formula' => $obj->formula, 'sens' => $obj->sens, - 'bc' => $obj->sens + 'dc' => $obj->sens ); $i++; } From 85ca2349d74cb10a7ae38b288697ba9b7422d39c Mon Sep 17 00:00:00 2001 From: Vincent Maury Date: Sat, 29 Mar 2025 13:33:16 +0100 Subject: [PATCH 24/31] When Update CommandeFournisseurLigne rang not updated (#33651) whan calling CommandeFournisseurLigne->update() , rang isn't updated Added same thing than in PropalLine->update(), CommandLine->update Co-authored-by: Laurent Destailleur --- htdocs/fourn/class/fournisseur.orderline.class.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/fourn/class/fournisseur.orderline.class.php b/htdocs/fourn/class/fournisseur.orderline.class.php index fe136475cfb..ab9b4f8f2ee 100644 --- a/htdocs/fourn/class/fournisseur.orderline.class.php +++ b/htdocs/fourn/class/fournisseur.orderline.class.php @@ -460,6 +460,9 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql .= ", product_type=".$this->product_type; $sql .= ", special_code=".(!empty($this->special_code) ? $this->special_code : 0); $sql .= ($this->fk_unit ? ", fk_unit='".$this->db->escape($this->fk_unit)."'" : ", fk_unit=null"); + if (!empty($this->rang)) { + $sql .= ", rang=".((int) $this->rang); + } // Multicurrency $sql .= ", multicurrency_subprice=".price2num($this->multicurrency_subprice); From 1bbdd303d3a16f7f2c35787c714fff73addb7cf6 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Sat, 29 Mar 2025 15:32:25 +0100 Subject: [PATCH 25/31] Fix position of drowndown when checkbox column is on left --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index cb19a6e2df1..ceab4925069 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -9501,7 +9501,7 @@ class Form