diff --git a/dev/tools/codespell/codespell-dict.txt b/dev/tools/codespell/codespell-dict.txt index f26d7250488..05904974269 100644 --- a/dev/tools/codespell/codespell-dict.txt +++ b/dev/tools/codespell/codespell-dict.txt @@ -36,6 +36,7 @@ nowraponalls->nowraponall oddevene->oddeven oddseven->oddeven opacitymediuem->opacitymedium +opend->opened pictofiwedwidth->pictofixedwidth pictofixedwith->pictofixedwidth shippin->shipping diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 6eb05106686..bb38c246127 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2011-2017 Juanjo Menent * Copyright (C) 2015 Marcos García * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2024 MDW * Copyright (C) 2024 William Mead * @@ -1883,7 +1883,7 @@ class ActionComm extends CommonObject $color = 'style="color: #'.$this->type_color.' !important;"'; } if ($this->type_picto) { - $imgpicto = img_picto($titlealt.'rr', $this->type_picto, '', 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); + $imgpicto = img_picto($titlealt, $this->type_picto, '', 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); } else { if ($this->type_code == 'AC_RDV') { $imgpicto = img_picto($titlealt, 'meeting', $color, 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 238121bb533..1c3856d360e 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -18,7 +18,7 @@ * Copyright (C) 2023 Nick Fragoulis * Copyright (C) 2023 Joachim Kueter * Copyright (C) 2024 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * Copyright (C) 2024 Solution Libre SAS * Copyright (C) 2024 William Mead * @@ -1271,7 +1271,7 @@ if (in_array($massaction, array('presend', 'predelete', 'makepayment'))) { } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); -// Show the new button only when this page is not opend from the Extended POS +// Show the new button only when this page is not opened from the Extended POS $newcardbutton = ''; if ($contextpage != 'poslist') { $url = DOL_URL_ROOT.'/compta/facture/card.php?action=create'; @@ -1389,7 +1389,7 @@ if (!empty($moreforfilter)) { $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields -// Show the massaction checkboxes only when this page is not opend from the Extended POS +// Show the massaction checkboxes only when this page is not opened from the Extended POS if ($massactionbutton && $contextpage != 'poslist') { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); } @@ -2791,7 +2791,7 @@ if ($num > 0) { } } - // Action column (Show the massaction button only when this page is not opend from the Extended POS) + // Action column (Show the massaction button only when this page is not opened from the Extended POS) if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; @@ -2844,7 +2844,7 @@ print ''."\n"; print ''."\n"; -// Show the file area only when this page is not opend from the Extended POS +// Show the file area only when this page is not opened from the Extended POS if ($contextpage != 'poslist') { $hidegeneratedfilelistifempty = 1; if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) { diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index 07f5dd234e9..902af2d6e2a 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -570,28 +570,33 @@ if ($result >= 0) { * List of unpaid invoices */ - $sql = 'SELECT f.rowid as facid, f.ref, f.total_ht, f.total_tva, f.total_ttc, f.multicurrency_code, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc, f.type,'; - $sql .= ' f.datef as df, f.fk_soc as socid, f.date_lim_reglement as dlr'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'facture as f'; - $sql .= ' WHERE f.entity IN ('.getEntity('facture').')'; - $sql .= ' AND (f.fk_soc = '.((int) $facture->socid); + $sql = "SELECT f.rowid as facid, f.ref, f.total_ht, f.total_tva, f.total_ttc, f.multicurrency_code, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc, f.type,"; + $sql .= " f.datef as df, f.fk_soc as socid, f.date_lim_reglement as dlr"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql .= " WHERE f.entity IN (".getEntity('facture').")"; + $sql .= " AND (f.fk_soc = ".((int) $facture->socid); // Can pay invoices of all child of parent company if (getDolGlobalString('FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS') && !empty($facture->thirdparty->parent)) { - $sql .= ' OR f.fk_soc IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'societe WHERE parent = '.((int) $facture->thirdparty->parent).')'; + $sql .= " OR f.fk_soc IN (SELECT rowid FROM ".MAIN_DB_PREFIX."societe WHERE parent = ".((int) $facture->thirdparty->parent).")"; } // Can pay invoices of all child of myself if (getDolGlobalString('FACTURE_PAYMENTS_ON_SUBSIDIARY_COMPANIES')) { - $sql .= ' OR f.fk_soc IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'societe WHERE parent = '.((int) $facture->thirdparty->id).')'; + $sql .= " OR f.fk_soc IN (SELECT rowid FROM ".MAIN_DB_PREFIX."societe WHERE parent = ".((int) $facture->thirdparty->id).")"; } - $sql .= ') AND f.paye = 0'; - $sql .= ' AND f.fk_statut = 1'; // Statut=0 => not validated, Statut=2 => canceled + $sql .= ") AND f.paye = 0"; + $sql .= " AND f.fk_statut = 1"; // Statut=0 => not validated, Statut=2 => canceled if ($facture->type != Facture::TYPE_CREDIT_NOTE) { - $sql .= ' AND type IN (0,1,3,5)'; // Standard invoice, replacement, deposit, situation + $sql .= " AND type IN (0,1,3,5)"; // Standard invoice, replacement, deposit, situation } else { - $sql .= ' AND type = 2'; // If paying back a credit note, we show all credit notes + $sql .= " AND type = 2"; // If paying back a credit note, we show all credit notes + } + if (!getDolGlobalInt('FACTURE_PAYMENTS_INVOICE_REQUESTED_SORT_FIRST')) { + // Sort invoices by date and serial number: the older one comes first + $sql .= " ORDER BY f.datef ASC, f.ref ASC"; + } else { + // The requested invoice sort first + $sql .= " ORDER BY f.rowid = ".((int) $facid)." DESC, f.datef ASC, f.ref ASC"; } - // Sort invoices by date and serial number: the older one comes first - $sql .= ' ORDER BY f.datef ASC, f.ref ASC'; $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/compta/paiement_charge.php b/htdocs/compta/paiement_charge.php index aa477454751..03474f1c454 100644 --- a/htdocs/compta/paiement_charge.php +++ b/htdocs/compta/paiement_charge.php @@ -1,6 +1,6 @@ - * Copyright (C) 2016-2024 Frédéric France + * Copyright (C) 2016-2025 Frédéric France * Copyright (C) 2022 Alexandre Spangaro * Copyright (C) 2024 MDW * @@ -229,7 +229,7 @@ if ($action == 'create') { print ''.$langs->trans('AccountToDebit').''; print ''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - print $form->select_comptes(GETPOSTISSET("accountid") ? GETPOSTINT("accountid") : $charge->accountid, "accountid", 0, '', 2, '', 0, 'maxwidth500 widthcentpercentminusx', 1); // Show opend bank account list + print $form->select_comptes(GETPOSTISSET("accountid") ? GETPOSTINT("accountid") : $charge->accountid, "accountid", 0, '', 2, '', 0, 'maxwidth500 widthcentpercentminusx', 1); // Show opened bank account list print ''; // Number diff --git a/htdocs/compta/paiement_vat.php b/htdocs/compta/paiement_vat.php index 3012d287a28..dd4744dca2c 100644 --- a/htdocs/compta/paiement_vat.php +++ b/htdocs/compta/paiement_vat.php @@ -1,6 +1,6 @@ - * Copyright (C) 2016-2024 Frédéric France + * Copyright (C) 2016-2025 Frédéric France * Copyright (C) 2021 Gauthier VERDOL * Copyright (C) 2024 MDW * @@ -229,7 +229,7 @@ if ($action == 'create') { print ''.$langs->trans('AccountToDebit').''; print ''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(GETPOSTINT("accountid") ? GETPOSTINT("accountid") : $tva->accountid, "accountid", 0, '', 1, '', 0, 'maxwidth500 widthcentpercentminusx'); // Show opend bank account list + $form->select_comptes(GETPOSTINT("accountid") ? GETPOSTINT("accountid") : $tva->accountid, "accountid", 0, '', 1, '', 0, 'maxwidth500 widthcentpercentminusx'); // Show opened bank account list print ''; // Number diff --git a/htdocs/core/boxes/box_funnel_of_prospection.php b/htdocs/core/boxes/box_funnel_of_prospection.php index d6cff6b37c4..6f58aa82ace 100644 --- a/htdocs/core/boxes/box_funnel_of_prospection.php +++ b/htdocs/core/boxes/box_funnel_of_prospection.php @@ -1,7 +1,7 @@ * Copyright (C) 2014 Marcos García - * Copyright (C) 2015 Frederic France + * Copyright (C) 2015-2025 Frédéric France * Copyright (C) 2016 Juan José Menent * Copyright (C) 2020 Pierre Ardoin * Copyright (C) 2024 MDW @@ -143,7 +143,7 @@ class box_funnel_of_prospection extends ModeleBoxes $sql .= " FROM ".MAIN_DB_PREFIX."projet as p, ".MAIN_DB_PREFIX."c_lead_status as cls"; $sql .= " WHERE p.entity IN (".getEntity('project').")"; $sql .= " AND p.fk_opp_status = cls.rowid"; - $sql .= " AND p.fk_statut = 1"; // Opend projects only + $sql .= " AND p.fk_statut = 1"; // Opened projects only $sql .= " AND cls.code NOT IN ('LOST', 'WON')"; $sql .= " GROUP BY p.fk_opp_status, cls.code"; $resql = $this->db->query($sql); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 12ba56bbe58..61560bd4371 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1065,7 +1065,8 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null // Check type of variable and make sanitization according to this if (preg_match('/^array/', $check)) { // If 'array' or 'array:restricthtml' or 'array:aZ09' or 'array:intcomma' if (!is_array($out) || empty($out)) { - $out = array(); + $out = explode(',', $out); + $tmpcheck = 'alphanohtml'; } else { $tmparray = explode(':', $check); if (!empty($tmparray[1])) { @@ -1073,9 +1074,9 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null } else { $tmpcheck = 'alphanohtml'; } - foreach ($out as $outkey => $outval) { - $out[$outkey] = sanitizeVal($outval, $tmpcheck, $filter, $options); - } + } + foreach ($out as $outkey => $outval) { + $out[$outkey] = sanitizeVal($outval, $tmpcheck, $filter, $options); } } else { // If field name is 'search_xxx' then we force the add of space after each < and > (when following char is numeric) because it means diff --git a/htdocs/install/mysql/migration/21.0.0-22.0.0.sql b/htdocs/install/mysql/migration/21.0.0-22.0.0.sql index a629c3c313e..0a4b4487eaa 100644 --- a/htdocs/install/mysql/migration/21.0.0-22.0.0.sql +++ b/htdocs/install/mysql/migration/21.0.0-22.0.0.sql @@ -48,3 +48,5 @@ ALTER TABLE llx_holiday_config ADD COLUMN entity integer DEFAULT 1 NOT NULL AFTE ALTER TABLE llx_holiday_config ADD UNIQUE INDEX idx_holiday_config (entity, name); ALTER TABLE llx_societe_account ADD COLUMN ip varchar(250); + +ALTER TABLE llx_product ADD COLUMN packaging integer DEFAULT NULL; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index f75a4f4ef3f..74e13e24694 100644 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -110,5 +110,6 @@ create table llx_product price_autogen tinyint DEFAULT 0, fk_project integer DEFAULT NULL, -- Used when product was generated by a project or is specific to a project mandatory_period tinyint DEFAULT 0, -- is used to signal to the user that the start and end dates are mandatory for this type of product the fk_product_type == 1 (service) (non-blocking action) - last_main_doc varchar(255) + last_main_doc varchar(255), + packaging integer DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 0542f2ac060..b87d3e0c148 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -1253,6 +1253,7 @@ CommercialAffected=Sales representative assigned CommercialsDisaffected=Sales representatives unlinked CommercialDisaffected=Sales representative unlinked Message=Message +Emailing=Emailing Progression=Progress YourMessage=Your message YourMessageHasBeenReceived=Your message has been received. We will answer or contact you as soon as possible. diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 4e072122887..db15cac8665 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -778,6 +778,7 @@ if ($id > 0) { } // Emit payment + // TODO check if loan schedule is created ($echeances->lines > 0) if (($object->paid == 0 || $object->paid == 2) && ((price2num($object->capital) > 0 && round($staytopay) < 0) || (price2num($object->capital) > 0 && round($staytopay) > 0)) && $user->hasRight('loan', 'write')) { print ''; } diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php index 435e95efa60..edc2c4e144b 100644 --- a/htdocs/loan/payment/payment.php +++ b/htdocs/loan/payment/payment.php @@ -1,6 +1,6 @@ - * Copyright (C) 2015-2024 Frédéric France + * Copyright (C) 2015-2025 Frédéric France * Copyright (C) 2020 Maxime DEMAREST * * This program is free software; you can redistribute it and/or modify @@ -62,7 +62,12 @@ if (!$user->hasRight('loan', 'write')) { $loan = new Loan($db); $loan->fetch($chid); +$line_id = 0; $echance = 0; +$amount_capital = 0; +$amount_insurance = 0; +$amount_interest = 0; + $ls = new LoanSchedule($db); // grab all loanschedule $res = $ls->fetchAll($chid); @@ -317,7 +322,7 @@ if ($action == 'create') { print ''.$langs->trans('AccountToDebit').''; print ''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(GETPOSTISSET("accountid") ? GETPOSTINT("accountid") : $loan->accountid, "accountid", 0, 'courant = '.Account::TYPE_CURRENT, 1); // Show opend bank account list + $form->select_comptes(GETPOSTISSET("accountid") ? GETPOSTINT("accountid") : $loan->accountid, "accountid", 0, 'courant = '.Account::TYPE_CURRENT, 1); // Show opened bank account list print ''; // Number diff --git a/htdocs/projet/graph_opportunities.inc.php b/htdocs/projet/graph_opportunities.inc.php index 9d976d9aba7..78d3ead854d 100644 --- a/htdocs/projet/graph_opportunities.inc.php +++ b/htdocs/projet/graph_opportunities.inc.php @@ -1,7 +1,7 @@ - * Copyright (C) 2024 MDW - * Copyright (C) 2024 Frédéric France +/* Copyright (C) 2013-2020 Laurent Destailleur + * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +34,7 @@ if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) { $sql = "SELECT p.fk_opp_status as opp_status, cls.code, COUNT(p.rowid) as nb, SUM(p.opp_amount) as opp_amount, SUM(p.opp_amount * p.opp_percent) as ponderated_opp_amount"; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status as cls ON p.fk_opp_status = cls.rowid"; // If lead status has been removed, we must show it in stats as unknown $sql .= " WHERE p.entity IN (".getEntity('project').")"; - $sql .= " AND p.fk_statut = 1"; // Opend projects only + $sql .= " AND p.fk_statut = 1"; // Opened projects only if ($mine || !$user->hasRight('projet', 'all', 'lire')) { $sql .= " AND p.rowid IN (".$db->sanitize($projectsListId).")"; } diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 8563d7f1857..fa047705614 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2019 Laurent Destailleur * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2024 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -965,7 +965,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- print ''; } - // Show the massaction checkboxes only when this page is not opend from the Extended POS + // Show the massaction checkboxes only when this page is not opened from the Extended POS if ($massactionbutton && $contextpage != 'poslist') { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); } diff --git a/htdocs/salaries/paiement_salary.php b/htdocs/salaries/paiement_salary.php index f084e5e1a07..fe14dc68319 100644 --- a/htdocs/salaries/paiement_salary.php +++ b/htdocs/salaries/paiement_salary.php @@ -1,6 +1,6 @@ - * Copyright (C) 2016-2024 Frédéric France + * Copyright (C) 2016-2025 Frédéric France * Copyright (C) 2021 Gauthier VERDOL * Copyright (C) 2024 MDW * @@ -237,7 +237,7 @@ if ($action == 'create') { print ''.$langs->trans('AccountToDebit').''; print ''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(GETPOSTISSET("accountid") ? GETPOSTINT("accountid") : $salary->accountid, "accountid", 0, '', 1); // Show opend bank account list + $form->select_comptes(GETPOSTISSET("accountid") ? GETPOSTINT("accountid") : $salary->accountid, "accountid", 0, '', 1); // Show opened bank account list print ''; // Number diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index cce3e430b6c..bd82817b05e 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -11,7 +11,7 @@ * Copyright (C) 2017 Juanjo Menent * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2020 Open-Dsi - * Copyright (C) 2021-2024 Frédéric France + * Copyright (C) 2021-2025 Frédéric France * Copyright (C) 2022 Anthony Berton * Copyright (C) 2023 William Mead * Copyright (C) 2024 MDW @@ -1189,7 +1189,7 @@ if ($contextpage == 'poslist' && $type == 't' && (getDolGlobalString('PRODUIT_MU print get_htmloutput_mesg(img_warning('default').' '.$langs->trans("BecarefullChangeThirdpartyBeforeAddProductToInvoice"), [], 'warning', 1); } -// Show the new button only when this page is not opend from the Extended POS (pop-up window) +// Show the new button only when this page is not opened from the Extended POS (pop-up window) // but allow it too, when a user has the rights to create a new customer if ($contextpage != 'poslist') { $url = DOL_URL_ROOT.'/societe/card.php?action=create'.$typefilter; @@ -1890,7 +1890,7 @@ while ($i < $imaxinloop) { } print '>'; - // Action column (Show the massaction button only when this page is not opend from the Extended POS) + // Action column (Show the massaction button only when this page is not opened from the Extended POS) if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; if (($massactionbutton || $massaction) && $contextpage != 'poslist') { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined @@ -2303,7 +2303,7 @@ while ($i < $imaxinloop) { $totalarray['nbfield']++; } } - // Action column (Show the massaction button only when this page is not opend from the Extended POS) + // Action column (Show the massaction button only when this page is not opened from the Extended POS) if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; if (($massactionbutton || $massaction) && $contextpage != 'poslist') { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined diff --git a/htdocs/stripe/admin/stripe.php b/htdocs/stripe/admin/stripe.php index eb08aac811d..77999453856 100644 --- a/htdocs/stripe/admin/stripe.php +++ b/htdocs/stripe/admin/stripe.php @@ -3,8 +3,8 @@ * Copyright (C) 2017 Olivier Geffroy * Copyright (C) 2017 Saasprov * Copyright (C) 2018-2022 Thibault FOUCART - * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2018-2025 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -386,7 +386,9 @@ $form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_PAYMENTS'), 'S print ''; -// Param to record automatically payouts (received from IPN payout.payed and payout.created) +// Param to record automatically payouts (received from IPN payout.paid and payout.created) +// https://docs.stripe.com/api/events/types#event_types-payout.created +// https://docs.stripe.com/api/events/types#event_types-payout.paid print ''; print $langs->trans("StripeAutoRecordPayout").''; if ($conf->use_javascript_ajax) {