diff --git a/build/rpm/dolibarr_fedora.spec b/build/rpm/dolibarr_fedora.spec index 9f360c3ef19..110eae0a3a2 100755 --- a/build/rpm/dolibarr_fedora.spec +++ b/build/rpm/dolibarr_fedora.spec @@ -213,6 +213,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/public %_datadir/dolibarr/htdocs/reception %_datadir/dolibarr/htdocs/resource +%_datadir/dolibarr/htdocs/salaries %_datadir/dolibarr/htdocs/societe %_datadir/dolibarr/htdocs/stripe %_datadir/dolibarr/htdocs/supplier_proposal @@ -224,6 +225,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/variants %_datadir/dolibarr/htdocs/webservices %_datadir/dolibarr/htdocs/website +%_datadir/dolibarr/htdocs/zapier %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec index 9c51feba990..ba5c426ea3f 100755 --- a/build/rpm/dolibarr_generic.spec +++ b/build/rpm/dolibarr_generic.spec @@ -293,6 +293,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/public %_datadir/dolibarr/htdocs/reception %_datadir/dolibarr/htdocs/resource +%_datadir/dolibarr/htdocs/salaries %_datadir/dolibarr/htdocs/societe %_datadir/dolibarr/htdocs/stripe %_datadir/dolibarr/htdocs/supplier_proposal @@ -304,6 +305,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/variants %_datadir/dolibarr/htdocs/webservices %_datadir/dolibarr/htdocs/website +%_datadir/dolibarr/htdocs/zapier %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_mandriva.spec b/build/rpm/dolibarr_mandriva.spec index 9f87638e8ba..073ef0389ce 100755 --- a/build/rpm/dolibarr_mandriva.spec +++ b/build/rpm/dolibarr_mandriva.spec @@ -210,6 +210,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/public %_datadir/dolibarr/htdocs/reception %_datadir/dolibarr/htdocs/resource +%_datadir/dolibarr/htdocs/salaries %_datadir/dolibarr/htdocs/societe %_datadir/dolibarr/htdocs/stripe %_datadir/dolibarr/htdocs/supplier_proposal @@ -221,6 +222,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/variants %_datadir/dolibarr/htdocs/webservices %_datadir/dolibarr/htdocs/website +%_datadir/dolibarr/htdocs/zapier %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec index f55ca13906d..be61853e165 100755 --- a/build/rpm/dolibarr_opensuse.spec +++ b/build/rpm/dolibarr_opensuse.spec @@ -221,6 +221,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/public %_datadir/dolibarr/htdocs/reception %_datadir/dolibarr/htdocs/resource +%_datadir/dolibarr/htdocs/salaries %_datadir/dolibarr/htdocs/societe %_datadir/dolibarr/htdocs/stripe %_datadir/dolibarr/htdocs/supplier_proposal @@ -232,6 +233,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/variants %_datadir/dolibarr/htdocs/webservices %_datadir/dolibarr/htdocs/website +%_datadir/dolibarr/htdocs/zapier %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/doc/images/dolibarr_screenshot1_1920x1080.jpg b/doc/images/dolibarr_screenshot1_1920x1080.jpg index 67ddece6df5..bc46b00a130 100644 Binary files a/doc/images/dolibarr_screenshot1_1920x1080.jpg and b/doc/images/dolibarr_screenshot1_1920x1080.jpg differ diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index b244d8be123..b0007395e0a 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -171,6 +171,7 @@ class AccountingAccount extends CommonObject $sql .= " a.rowid = " . (int) $rowid; } elseif ($account_number) { $sql .= " a.account_number = '" . $this->db->escape($account_number) . "'"; + $sql .= " AND a.entity = ".$conf->entity; } if (! empty($limittocurrentchart)) { $sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $this->db->escape($conf->global->CHARTOFACCOUNTS) . ')'; diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index 782b151a5a4..48df5ce374a 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -152,6 +152,8 @@ if ($action == 'validatehistory') { while ($i < min($num_lines, 10000)) { // No more than 10000 at once $objp = $db->fetch_object($result); + $isBuyerInEEC = isInEEC($objp); + // Search suggested account for product/service $suggestedaccountingaccountfor = ''; if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index f6b149de291..d52c4c51f07 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -230,7 +230,7 @@ if (strlen(trim($search_country))) { elseif ($search_country == 'special_eec') $sql .= " AND co.code IN (".$country_code_in_EEC.")"; elseif ($search_country == 'special_eecnotme') $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")"; elseif ($search_country == 'special_noteec') $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")"; - else $sql .= natural_search(array("co.code", "co.label"), $search_country); + else $sql .= natural_search("co.code", $search_country); } if (strlen(trim($search_tvaintra))) { $sql .= natural_search("s.tva_intra", $search_tvaintra); diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index e8b898a455d..d964d348889 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -262,7 +262,7 @@ if (strlen(trim($search_country))) { elseif ($search_country == 'special_eec') $sql .= " AND co.code IN (".$country_code_in_EEC.")"; elseif ($search_country == 'special_eecnotme') $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")"; elseif ($search_country == 'special_noteec') $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")"; - else $sql .= natural_search(array("co.code", "co.label"), $search_country); + else $sql .= natural_search("co.code", $search_country); } if (strlen(trim($search_tvaintra))) { $sql .= natural_search("s.tva_intra", $search_tvaintra); diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php index 1a0844436b6..3bc44698029 100644 --- a/htdocs/accountancy/supplier/index.php +++ b/htdocs/accountancy/supplier/index.php @@ -141,12 +141,14 @@ if ($action == 'validatehistory') { } else { $num_lines = $db->num_rows($result); - $isSellerInEEC = isInEEC($mysoc); + $isBuyerInEEC = isInEEC($mysoc); $i = 0; while ($i < min($num_lines, 10000)) { // No more than 10000 at once $objp = $db->fetch_object($result); + $isSellerInEEC = isInEEC($objp); + // Search suggested account for product/service $suggestedaccountingaccountfor = ''; if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index 7afae1538e7..a035aed2b1f 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -225,7 +225,7 @@ if (strlen(trim($search_country))) { elseif ($search_country == 'special_eec') $sql .= " AND co.code IN (".$country_code_in_EEC.")"; elseif ($search_country == 'special_eecnotme') $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")"; elseif ($search_country == 'special_noteec') $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")"; - else $sql .= natural_search(array("co.code", "co.label"), $search_country); + else $sql .= natural_search("co.code", $search_country); } if (strlen(trim($search_tvaintra))) { $sql .= natural_search("s.tva_intra", $search_tvaintra); diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 33e356dddb4..ecd41f2f9da 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -263,7 +263,7 @@ if (strlen(trim($search_country))) { elseif ($search_country == 'special_eec') $sql .= " AND co.code IN (".$country_code_in_EEC.")"; elseif ($search_country == 'special_eecnotme') $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")"; elseif ($search_country == 'special_noteec') $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")"; - else $sql .= natural_search(array("co.code", "co.label"), $search_country); + else $sql .= natural_search("co.code", $search_country); } if (strlen(trim($search_tvaintra))) { $sql .= natural_search("s.tva_intra", $search_tvaintra); diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 1ec82f7da31..0aa7bcbf6ea 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2752,6 +2752,9 @@ class Adherent extends CommonObject $nbok = 0; $nbko = 0; + $listofmembersok = array(); + $listofmembersko = array(); + $arraydaysbeforeend=explode(';', $daysbeforeendlist); foreach($arraydaysbeforeend as $daysbeforeend) // Loop on each delay { @@ -2768,7 +2771,8 @@ class Adherent extends CommonObject $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year']), $daysbeforeend, 'd'); $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent'; - $sql.= " WHERE datefin = '".$this->db->idate($datetosearchfor)."'"; + $sql.= " WHERE entity = ".$conf->entity; // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only; + $sql.= " AND datefin = '".$this->db->idate($datetosearchfor)."'"; $resql = $this->db->query($sql); if ($resql) @@ -2789,6 +2793,7 @@ class Adherent extends CommonObject if (empty($adherent->email)) { $nbko++; + $listofmembersko[$adherent->id]=$adherent->id; } else { @@ -2830,12 +2835,16 @@ class Adherent extends CommonObject { $error++; $this->error = $cmail->error; - $this->errors += $cmail->errors; + if (! is_null($cmail->errors)) { + $this->errors += $cmail->errors; + } $nbko++; + $listofmembersko[$adherent->id]=$adherent->id; } else { $nbok++; + $listofmembersok[$adherent->id]=$adherent->id; $message = $msg; $sendto = $to; @@ -2894,7 +2903,10 @@ class Adherent extends CommonObject else { $blockingerrormsg="Can't find email template, defined into member module setup, to use for reminding"; + $nbko++; + $listofmembersko[$adherent->id]=$adherent->id; + break; } } @@ -2918,7 +2930,39 @@ class Adherent extends CommonObject { $this->output = 'Found '.($nbok + $nbko).' members to send reminder to.'; $this->output.= ' Send email successfuly to '.$nbok.' members'; - if ($nbko) $this->output.= ' - Canceled for '.$nbko.' member (no email or email sending error)'; + if (is_array($listofmembersok)) { + $listofids = ''; $i = 0; + foreach($listofmembersok as $idmember) { + if ($i > 100) { + $listofids .= ', ...'; + break; + } + if (empty($listofids)) $listofids .= ' ['; + else $listofids .= ', '; + $listofids .= $idmember; + $i++; + } + if ($listofids) $listofids .= ']'; + $this->output .= $listofids; + } + if ($nbko) { + $this->output.= ' - Canceled for '.$nbko.' member (no email or email sending error)'; + if (is_array($listofmembersko)) { + $listofids = ''; $i = 0; + foreach($listofmembersko as $idmember) { + if ($i > 100) { + $listofids .= ', ...'; + break; + } + if (empty($listofids)) $listofids .= ' ['; + else $listofids .= ', '; + $listofids .= $idmember; + $i++; + } + if ($listofids) $listofids .= ']'; + $this->output .= $listofids; + } + } } return 0; diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 49217b55963..b9a787cc67c 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -349,7 +349,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 2e03eed937c..474c6020610 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -758,13 +758,31 @@ else $text = ''; if ($conf->global->MAIN_MAIL_SENDMODE == 'mail') { - $text .= $langs->trans("WarningPHPMail"); + $text .= $langs->trans("WarningPHPMail"); // To encourage to use SMTPS } - //$conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS='1.2.3.4'; - if (!empty($conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS)) + + if ($conf->global->MAIN_MAIL_SENDMODE == 'mail') { - $text .= ($text ? '
' : '').$langs->trans("WarningPHPMail2", $conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS); + // MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS is list of IPs where email is sent from. Example: '1.2.3.4, [aaaa:bbbb:cccc:dddd]'. + if (!empty($conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS)) + { + // List of IP show as record to add in SPF if we use the mail method + $text .= ($text ? '

' : '').$langs->trans("WarningPHPMailSPF", $conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS); + } + } else { + if (!empty($conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS)) + { + // List of IP show as record to add as allowed IP if we use the smtp method + $text .= ($text ? '

' : '').$langs->trans("WarningPHPMail2", $conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS); + } + if (!empty($conf->global->MAIN_EXTERNAL_SMTP_SPF_STRING_TO_ADD)) + { + // List of string to add in SPF if we use the smtp method + $text .= ($text ? '

' : '').$langs->trans("WarningPHPMailSPF", $conf->global->MAIN_EXTERNAL_SMTP_SPF_STRING_TO_ADD); + } } + + if ($text) print info_admin($text); } @@ -840,6 +858,11 @@ else print $formmail->get_form('addfile', 'removefile'); dol_fiche_end(); + + // References + print ''.$langs->trans("EMailsWillHaveMessageID").': '; + print dol_escape_htmltag(''); + print ''; } } diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index 1eddaef9903..fb5ff1df202 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -113,10 +113,12 @@ llxHeader('', $langs->trans("NotificationSetup")); $linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans("NotificationSetup"), $linkback, 'title_setup'); +print ''; print $langs->trans("NotificationsDesc").'
'; print $langs->trans("NotificationsDescUser").'
'; if (!empty($conf->societe->enabled)) print $langs->trans("NotificationsDescContact").'
'; print $langs->trans("NotificationsDescGlobal").'
'; +print '
'; print '
'; print '
'; diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index f4c9076fbd9..26f83f36fd6 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -150,6 +150,12 @@ class DolibarrApi unset($object->context); unset($object->next_prev_filter); + unset($object->region); + unset($object->region_code); + + unset($object->libelle_statut); + unset($object->libelle_paiement); + if ($object->table_element != 'ticket') { unset($object->comments); } diff --git a/htdocs/asset/card.php b/htdocs/asset/card.php index 5c28e7843ba..b4ff4ebac68 100644 --- a/htdocs/asset/card.php +++ b/htdocs/asset/card.php @@ -224,7 +224,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 70036d6a099..87396dccb30 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -449,7 +449,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index acbffa109a2..9540c2b84cd 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1116,7 +1116,7 @@ class Categorie extends CommonObject // Include or exclude leaf including $markafterid from tree if (count($markafterid) > 0) { - $keyfiltercatid = implode('|', $markafterid); + $keyfiltercatid = '(' . implode('|', $markafterid) . ')'; //print "Look to discard category ".$markafterid."\n"; $keyfilter1 = '^'.$keyfiltercatid.'$'; diff --git a/htdocs/comm/action/class/api_agendaevents.class.php b/htdocs/comm/action/class/api_agendaevents.class.php index 0d3c5de514d..271257c3ecc 100644 --- a/htdocs/comm/action/class/api_agendaevents.class.php +++ b/htdocs/comm/action/class/api_agendaevents.class.php @@ -229,7 +229,6 @@ class AgendaEvents extends DolibarrApi * * @return int */ - /* public function put($id, $request_data = null) { if (! DolibarrApiAccess::$user->rights->agenda->myactions->create) { @@ -245,11 +244,11 @@ class AgendaEvents extends DolibarrApi $this->actioncomm->fetch_userassigned(); $this->actioncomm->oldcopy = clone $this->actioncomm; } - if ( ! $result ) { + if (! $result ) { throw new RestException(404, 'actioncomm not found'); } - if ( ! DolibarrApi::_checkAccessToResource('actioncomm',$this->actioncomm->id)) { + if (! DolibarrApi::_checkAccessToResource('actioncomm', $this->actioncomm->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach($request_data as $field => $value) { @@ -257,12 +256,11 @@ class AgendaEvents extends DolibarrApi $this->actioncomm->$field = $value; } - if ($this->actioncomm->update($id, DolibarrApiAccess::$user,1,'','','update')) + if ($this->actioncomm->update(DolibarrApiAccess::$user, 1) > 0) return $this->get($id); return false; } - */ /** * Delete Agenda Event diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 8c46cb162d3..f55861b00cc 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1953,7 +1953,7 @@ if ($action == 'create') } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 7da9fcca7d1..3c1bf672c0f 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2064,7 +2064,7 @@ if ($action == 'create' && $usercancreate) } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); // Note that $action and $object may be modified by hook $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index 57aa50f1568..2ecb59861d9 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -411,8 +411,9 @@ class BankAccounts extends DolibarrApi * @throws RestException * * @url GET {id}/lines + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.import_key:<:'20160101')" */ - public function getLines($id) + public function getLines($id, $sqlfilters = '') { $list = array(); @@ -428,6 +429,18 @@ class BankAccounts extends DolibarrApi $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank "; $sql .= " WHERE fk_account = ".$id; + + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + $sql .= " ORDER BY rowid"; $result = $this->db->query($sql); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index f72a3ed7f13..15200582ced 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3889,7 +3889,7 @@ elseif ($id > 0 || !empty($ref)) } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 4cea8dcad9d..9172993acc7 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4005,6 +4005,7 @@ class Facture extends CommonInvoice if ($generic_facture->hasDelay()) { $response->nbtodolate++; + $response->url_late=DOL_URL_ROOT.'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills'; } } diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 00aa9deb4df..db1ba28c14e 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -387,7 +387,7 @@ if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT'; $sql .= ' f.rowid as id, f.ref, f.ref_client, f.type, f.note_private, f.note_public, f.increment, f.fk_mode_reglement, f.fk_cond_reglement, f.total as total_ht, f.tva as total_vat, f.total_ttc,'; $sql .= ' f.localtax1 as total_localtax1, f.localtax2 as total_localtax2,'; $sql .= ' f.datef as df, f.date_lim_reglement as datelimite, f.module_source, f.pos_source,'; -$sql .= ' f.paye as paye, f.fk_statut,'; +$sql .= ' f.paye as paye, f.fk_statut, f.close_code,'; $sql .= ' f.datec as date_creation, f.tms as date_update, f.date_closing as date_closing,'; $sql .= ' f.retained_warranty, f.retained_warranty_date_limit, f.situation_final, f.situation_cycle_ref, f.situation_counter,'; $sql .= ' s.rowid as socid, s.nom as name, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur,'; @@ -502,7 +502,7 @@ if (!$sall) $sql .= ' GROUP BY f.rowid, f.ref, ref_client, f.type, f.note_private, f.note_public, f.increment, f.fk_mode_reglement, f.fk_cond_reglement, f.total, f.tva, f.total_ttc,'; $sql .= ' f.localtax1, f.localtax2,'; $sql .= ' f.datef, f.date_lim_reglement, f.module_source, f.pos_source,'; - $sql .= ' f.paye, f.fk_statut,'; + $sql .= ' f.paye, f.fk_statut, f.close_code,'; $sql .= ' f.datec, f.tms, f.date_closing,'; $sql .= ' f.retained_warranty, f.retained_warranty_date_limit, f.situation_final, f.situation_cycle_ref, f.situation_counter,'; $sql .= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,'; @@ -987,6 +987,7 @@ if ($resql) $facturestatic->total_tva = $obj->total_vat; $facturestatic->total_ttc = $obj->total_ttc; $facturestatic->statut = $obj->fk_statut; + $facturestatic->close_code = $obj->close_code; $facturestatic->total_ttc = $obj->total_ttc; $facturestatic->paye = $obj->paye; $facturestatic->fk_soc = $obj->fk_soc; @@ -1022,7 +1023,11 @@ if ($resql) $totaldeposits = $facturestatic->getSumDepositsUsed(); $totalpay = $paiement + $totalcreditnotes + $totaldeposits; $remaintopay = price2num($facturestatic->total_ttc - $totalpay); - if ($facturestatic->type == Facture::TYPE_CREDIT_NOTE && $obj->paye == 1) { + + if ($facturestatic->statut == Facture::STATUS_CLOSED && $facturestatic->close_code == 'discount_vat') { // If invoice closed with discount for anticipated payment + $remaintopay = 0; + } + if ($facturestatic->type == Facture::TYPE_CREDIT_NOTE && $obj->paye == 1) { // If credit note closed, we take into account the amount not yet consummed $remaincreditnote = $discount->getAvailableDiscounts($obj->fk_soc, '', 'rc.fk_facture_source='.$facturestatic->id); $remaintopay = -$remaincreditnote; $totalpay = price2num($facturestatic->total_ttc - $remaintopay); @@ -1281,9 +1286,12 @@ if ($resql) $totalarray['val']['totalam'] += $totalpay; } + // Pending amount if (!empty($arrayfields['rtp']['checked'])) { - print ''.(!empty($remaintopay) ?price($remaintopay, 0, $langs) : ' ').''; // TODO Use a denormalized field + print ''; + print (!empty($remaintopay) ? price($remaintopay, 0, $langs) : ' '); + print ''; // TODO Use a denormalized field if (!$i) $totalarray['nbfield']++; if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'rtp'; $totalarray['val']['rtp'] += $remaintopay; diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index 0b8a441dea2..fdb4284e909 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -248,7 +248,7 @@ if ($id > 0 || $ref) } // Call Hook formConfirm - /*$parameters = array(); + /*$parameters = array('formConfirm' => $formconfirm); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm.=$hookmanager->resPrint; elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;*/ diff --git a/htdocs/compta/resultat/result.php b/htdocs/compta/resultat/result.php index 6e91ef53e2b..97b04158e34 100644 --- a/htdocs/compta/resultat/result.php +++ b/htdocs/compta/resultat/result.php @@ -505,7 +505,7 @@ elseif ($modecompta=="BOOKKEEPING") $resultNP = $totPerAccount[$cpt['account_number']]['NP']; $resultN = $totPerAccount[$cpt['account_number']]['N']; - if ($showaccountdetail == 'all' || $resultN > 0) { + if ($showaccountdetail == 'all' || $resultN != 0) { print ''; print ''; print ''; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index fccae47fd89..c80dda1da91 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1356,6 +1356,7 @@ else // Call Hook formConfirm $parameters = array( + 'formConfirm' => $formconfirm, 'id' => $id, //'lineid' => $lineid, ); diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index eb2e55d6279..80afcfacecc 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -103,7 +103,12 @@ abstract class CommonInvoice extends CommonObject $alreadypaid+=$this->getSommePaiement($multicurrency); $alreadypaid+=$this->getSumDepositsUsed($multicurrency); $alreadypaid+=$this->getSumCreditNotesUsed($multicurrency); - return $this->total_ttc - $alreadypaid; + + $remaintopay = ($this->total_ttc - $alreadypaid); + if ($this->statut == self::STATUS_CLOSED && $this->close_code == 'discount_vat') { // If invoice closed with discount for anticipated payment + $remaintopay = 0; + } + return $remaintopay; } /** diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index ef5f5d4e74c..36b83bb32b7 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1324,6 +1324,7 @@ class ExtraFields print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.
'; } } else { + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; $data = $form->select_all_categories(Categorie::$MAP_ID_TO_CODE[$InfoFieldList[5]], '', 'parent', 64, $InfoFieldList[6], 1, 1); $out .= ''; foreach ($data as $data_key => $data_value) { @@ -1550,6 +1551,7 @@ class ExtraFields print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.
'; } } else { + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; $data = $form->select_all_categories(Categorie::$MAP_ID_TO_CODE[$InfoFieldList[5]], '', 'parent', 64, $InfoFieldList[6], 1, 1); $out = $form->multiselectarray($keyprefix . $key . $keysuffix, $data, $value_arr, '', 0, '', 0, '100%'); } diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index c973d589471..7012b813f7d 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -96,12 +96,9 @@ class FormAdmin if ($showcode == 1) $valuetoshow=$key.' - '.$value; if ($showcode == 2) $valuetoshow=$value.' ('.$key.')'; - if ($filter && is_array($filter)) + if ($filter && is_array($filter) && array_key_exists($key, $filter)) { - if ( ! array_key_exists($key, $filter)) - { - $out.= ''; - } + continue; } elseif ($selected == $key) { diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 6de51cfe7ba..a5ba08bb139 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -2154,7 +2154,7 @@ function pdf_getLinkedObjects($object, $outputlangs) $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs); } } - else if ($objecttype == 'fichinter') + elseif ($objecttype == 'fichinter') { $outputlangs->load('interventions'); foreach($objects as $elementobject) diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index b0f7dd94ae8..984e28f4e31 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -216,7 +216,8 @@ class modFacture extends DolibarrModules 's.code_compta_fournisseur'=>'SupplierAccountancyCode', 's.tva_intra'=>'VATIntra', 'f.rowid'=>"InvoiceId", 'f.ref'=>"InvoiceRef", 'f.ref_client'=>'RefCustomer', 'f.type'=>"Type", 'f.datec'=>"InvoiceDateCreation", 'f.datef'=>"DateInvoice", 'f.date_lim_reglement'=>"DateDue", 'f.total'=>"TotalHT", - 'f.total_ttc'=>"TotalTTC", 'f.tva'=>"TotalVAT", 'f.localtax1'=>'LocalTax1', 'f.localtax2'=>'LocalTax2', 'none.rest'=>'Rest', 'f.paye'=>"InvoicePaidCompletely", 'f.fk_statut'=>'InvoiceStatus', + 'f.total_ttc'=>"TotalTTC", 'f.tva'=>"TotalVAT", 'f.localtax1'=>'LocalTax1', 'f.localtax2'=>'LocalTax2', 'f.paye'=>"InvoicePaidCompletely", 'f.fk_statut'=>'InvoiceStatus', 'f.close_code'=>'EarlyClosingReason', 'f.close_note'=>'EarlyClosingComment', + 'none.rest'=>'Rest', 'f.note_private'=>"NotePrivate", 'f.note_public'=>"NotePublic", 'f.fk_user_author'=>'CreatedById', 'uc.login'=>'CreatedByLogin', 'f.fk_user_valid'=>'ValidatedById', 'uv.login'=>'ValidatedByLogin', 'pj.ref'=>'ProjectRef', 'pj.title'=>'ProjectLabel', 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.subprice'=>"LineUnitPrice", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.total_ht'=>"LineTotalHT", 'fd.total_tva'=>"LineTotalVAT", @@ -241,7 +242,8 @@ class modFacture extends DolibarrModules 's.rowid'=>'Numeric', 's.nom'=>'Text', 's.code_client'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 'cd.nom'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.rowid'=>'Numeric', 'f.ref'=>"Text", 'f.ref_client'=>'Text', 'f.type'=>"Numeric", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>"Date", - 'f.total'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.tva'=>"Numeric", 'f.localtax1'=>'Numeric', 'f.localtax2'=>'Numeric', 'none.rest'=>"NumericCompute", 'f.paye'=>"Boolean", 'f.fk_statut'=>'Numeric', + 'f.total'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.tva'=>"Numeric", 'f.localtax1'=>'Numeric', 'f.localtax2'=>'Numeric', 'f.paye'=>"Boolean", 'f.fk_statut'=>'Numeric', 'f.close_code'=>'Text', 'f.close_note'=>'Text', + 'none.rest'=>"NumericCompute", 'f.note_private'=>"Text", 'f.note_public'=>"Text", 'f.fk_user_author'=>'Numeric', 'uc.login'=>'Text', 'f.fk_user_valid'=>'Numeric', 'uv.login'=>'Text', 'pj.ref'=>'Text', 'pj.title'=>'Text', 'fd.rowid'=>'Numeric', 'fd.label'=>'Text', 'fd.description'=>"Text", 'fd.subprice'=>"Numeric", 'fd.tva_tx'=>"Numeric", 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_tva'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.date_start'=>"Date", 'fd.date_end'=>"Date", @@ -263,7 +265,7 @@ class modFacture extends DolibarrModules 'f.fk_user_author'=>'user', 'uc.login'=>'user', 'f.fk_user_valid'=>'user', 'uv.login'=>'user' ); $this->export_special_array[$r] = array('none.rest'=>'getRemainToPay'); - $this->export_dependencies_array[$r] = array('invoice_line'=>'fd.rowid', 'product'=>'fd.rowid', 'none.rest'=>array('f.rowid', 'f.total_ttc')); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + $this->export_dependencies_array[$r] = array('invoice_line'=>'fd.rowid', 'product'=>'fd.rowid', 'none.rest'=>array('f.rowid', 'f.total_ttc', 'f.close_code')); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them $keyforselect = 'facture'; $keyforelement = 'invoice'; $keyforaliasextra = 'extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; $keyforselect = 'facturedet'; $keyforelement = 'invoice_line'; $keyforaliasextra = 'extra2'; @@ -289,6 +291,7 @@ class modFacture extends DolibarrModules if (isset($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' AND sc.fk_user = '.$user->id; $r++; + $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = 'CustomersInvoicesAndPayments'; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_icon[$r] = 'invoice'; @@ -300,7 +303,8 @@ class modFacture extends DolibarrModules 's.code_compta_fournisseur'=>'SupplierAccountancyCode', 's.tva_intra'=>'VATIntra', 'f.rowid'=>"InvoiceId", 'f.ref'=>"InvoiceRef", 'f.ref_client'=>'RefCustomer', 'f.type'=>"Type", 'f.datec'=>"InvoiceDateCreation", 'f.datef'=>"DateInvoice", 'f.date_lim_reglement'=>"DateDue", 'f.total'=>"TotalHT", - 'f.total_ttc'=>"TotalTTC", 'f.tva'=>"TotalVAT", 'f.localtax1'=>'LocalTax1', 'f.localtax2'=>'LocalTax2', 'none.rest'=>'Rest', 'f.paye'=>"InvoicePaidCompletely", 'f.fk_statut'=>'InvoiceStatus', + 'f.total_ttc'=>"TotalTTC", 'f.tva'=>"TotalVAT", 'f.localtax1'=>'LocalTax1', 'f.localtax2'=>'LocalTax2', 'f.paye'=>"InvoicePaidCompletely", 'f.fk_statut'=>'InvoiceStatus', 'f.close_code'=>'EarlyClosingReason', 'f.close_note'=>'EarlyClosingComment', + 'none.rest'=>'Rest', 'f.note_private'=>"NotePrivate", 'f.note_public'=>"NotePublic", 'f.fk_user_author'=>'CreatedById', 'uc.login'=>'CreatedByLogin', 'f.fk_user_valid'=>'ValidatedById', 'uv.login'=>'ValidatedByLogin', 'pj.ref'=>'ProjectRef', 'pj.title'=>'ProjectLabel', 'p.rowid'=>'PaymentId', 'p.ref'=>'PaymentRef', 'p.amount'=>'AmountPayment', 'pf.amount'=>'AmountPaymentDistributedOnInvoice', 'p.datep'=>'DatePayment', 'p.num_paiement'=>'PaymentNumber', @@ -325,9 +329,10 @@ class modFacture extends DolibarrModules 's.rowid'=>'Numeric', 's.nom'=>'Text', 's.code_client'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 'cd.nom'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.rowid'=>"Numeric", 'f.ref'=>"Text", 'f.ref_client'=>'Text', 'f.type'=>"Numeric", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>"Date", - 'f.total'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.tva'=>"Numeric", 'f.localtax1'=>'Numeric', 'f.localtax2'=>'Numeric', 'none.rest'=>'NumericCompute', 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', + 'f.total'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.tva'=>"Numeric", 'f.localtax1'=>'Numeric', 'f.localtax2'=>'Numeric', 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', 'f.close_code'=>'Text', 'f.close_note'=>'Text', + 'none.rest'=>'NumericCompute', 'f.note_private'=>"Text", 'f.note_public'=>"Text", 'f.fk_user_author'=>'Numeric', 'uc.login'=>'Text', 'f.fk_user_valid'=>'Numeric', 'uv.login'=>'Text', - 'pj.ref'=>'Text', 'p.amount'=>'Numeric', 'pf.amount'=>'Numeric', 'p.rowid'=>'Numeric', 'p.ref'=>'Text', 'p.title'=>'Text', 'p.datep'=>'Date', 'p.num_paiement'=>'Numeric', + 'pj.ref'=>'Text', 'pj.title'=>'Text', 'p.amount'=>'Numeric', 'pf.amount'=>'Numeric', 'p.rowid'=>'Numeric', 'p.ref'=>'Text', 'p.title'=>'Text', 'p.datep'=>'Date', 'p.num_paiement'=>'Numeric', 'p.fk_bank'=>'Numeric', 'p.note'=>'Text', 'pt.code'=>'Text', 'pt.libelle'=>'text', 'ba.ref'=>'Text' ); if (! empty($conf->cashdesk->enabled) || ! empty($conf->takepos->enabled) || ! empty($conf->global->INVOICE_SHOW_POS)) @@ -338,12 +343,12 @@ class modFacture extends DolibarrModules $this->export_entities_array[$r] = array( 's.rowid'=>"company", 's.nom'=>'company', 's.code_client'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 'cd.nom'=>'company', 's.phone'=>'company', 's.siren'=>'company', 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', - 's.tva_intra'=>'company', 'pj.ref'=>'project', 'p.title'=>'project', 'p.rowid'=>'payment', 'p.ref'=>'payment', 'p.amount'=>'payment', 'pf.amount'=>'payment', 'p.datep'=>'payment', + 's.tva_intra'=>'company', 'pj.ref'=>'project', 'pj.title'=>'project', 'p.rowid'=>'payment', 'p.ref'=>'payment', 'p.amount'=>'payment', 'pf.amount'=>'payment', 'p.datep'=>'payment', 'p.num_paiement'=>'payment', 'pt.code'=>'payment', 'pt.libelle'=>'payment', 'p.note'=>'payment', 'f.fk_user_author'=>'user', 'uc.login'=>'user', 'f.fk_user_valid'=>'user', 'uv.login'=>'user', 'p.fk_bank'=>'account', 'ba.ref'=>'account' ); $this->export_special_array[$r] = array('none.rest'=>'getRemainToPay'); - $this->export_dependencies_array[$r] = array('payment'=>'p.rowid', 'none.rest'=>array('f.rowid', 'f.total_ttc')); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + $this->export_dependencies_array[$r] = array('payment'=>'p.rowid', 'none.rest'=>array('f.rowid', 'f.total_ttc', 'f.close_code')); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them, or just to have field we need $keyforselect = 'facture'; $keyforelement = 'invoice'; $keyforaliasextra = 'extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; $this->export_sql_start[$r]='SELECT DISTINCT '; diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 0844cff2057..e6968109bf7 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -2013,6 +2013,9 @@ class EmailCollector extends CommonObject // TEXT if ($p->type == 0 && $data) { + if(!empty($params['charset'])) { + $data = $this->convertStringEncoding($data, $params['charset']); + } // Messages may be split in different parts because of inline attachments, // so append parts together with blank row. if (strtolower($p->subtype) == 'plain') @@ -2028,6 +2031,9 @@ class EmailCollector extends CommonObject // There are no PHP functions to parse embedded messages, // so this just appends the raw source to the main message. elseif ($p->type == 2 && $data) { + if(!empty($params['charset'])) { + $data = $this->convertStringEncoding($data, $params['charset']); + } $plainmsg .= $data."\n\n"; } @@ -2039,4 +2045,28 @@ class EmailCollector extends CommonObject } } } + + /** + * Converts a string from one encoding to another. + * + * @param string $string String to convert + * @param string $fromEncoding String encoding + * @param string $toEncoding String return encoding + * @return string Converted string if conversion was successful, or the original string if not + * @throws Exception + */ + protected function convertStringEncoding($string, $fromEncoding, $toEncoding = 'UTF-8') + { + if(!$string || $fromEncoding == $toEncoding) { + return $string; + } + $convertedString = function_exists('iconv') ? @iconv($fromEncoding, $toEncoding . '//IGNORE', $string) : null; + if(!$convertedString && extension_loaded('mbstring')) { + $convertedString = @mb_convert_encoding($string, $toEncoding, $fromEncoding); + } + if(!$convertedString) { + throw new Exception('Mime string encoding conversion failed'); + } + return $convertedString; + } } diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 0b9682f5f06..66b47ab563f 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1693,7 +1693,7 @@ elseif ($id || $ref) } // Call Hook formConfirm - $parameters = array(); + $parameters = array('formConfirm' => $formconfirm); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index 4834152127f..5039af22e84 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -261,7 +261,7 @@ if ($id > 0 || !empty($ref)) } // Call Hook formConfirm - $parameters = array(); + $parameters = array('formConfirm' => $formconfirm); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index 0e673ffdf30..60e5eafcb48 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -501,6 +501,9 @@ class ExpenseReports extends DolibarrApi // phpcs:enable $object = parent::_cleanObjectDatas($object); + unset($object->cond_reglement); + unset($object->shipping_method_id); + unset($object->barcode_type); unset($object->barcode_type_code); unset($object->barcode_type_label); diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php index 06813b03ae5..b43fddad60d 100644 --- a/htdocs/exports/class/export.class.php +++ b/htdocs/exports/class/export.class.php @@ -660,6 +660,7 @@ class Export } $tmpobjforcomputecall->id = $obj->f_rowid; $tmpobjforcomputecall->total_ttc = $obj->f_total_ttc; + $tmpobjforcomputecall->close_code = $obj->f_close_code; $remaintopay=$tmpobjforcomputecall->getRemainToPay(); } $obj->$alias=$remaintopay; diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index ffbed97a75c..525a5b17c9e 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -1186,7 +1186,7 @@ if ($step == 5 && $datatoexport) print $objexport->array_export_module[0]->getName(); print ''; - // Lot de donnees a exporter + // Dataset to export print ''.$langs->trans("DatasetToExport").''; print ''; $icon = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index d2a4171eb4f..c096a889ab4 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1168,7 +1168,7 @@ elseif ($id > 0 || !empty($ref)) if (!$formconfirm) { - $parameters = array('lineid'=>$lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid'=>$lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index e6562dbf928..b64bd1277c0 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2234,6 +2234,7 @@ class FactureFournisseur extends CommonInvoice if ($facturestatic->hasDelay()) { $response->nbtodolate++; + $response->url_late=DOL_URL_ROOT.'/fourn/facture/list.php?option=late&mainmenu=billing&leftmenu=suppliers_bills'; } } $this->db->free($resql); diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 59c01d95297..9adad176ab2 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1907,7 +1907,7 @@ elseif (!empty($object->id)) $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1); } - $parameters = array('lineid'=>$lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid'=>$lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index d7a258b517e..ffdfb07baa0 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -2406,7 +2406,7 @@ else if (!$formconfirm) { - $parameters = array('lineid'=>$lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid'=>$lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/install/doctemplates/websites/website_template-corporate.zip b/htdocs/install/doctemplates/websites/website_template-corporate.zip index f83fecc2c2e..9ef5f4aee5a 100644 Binary files a/htdocs/install/doctemplates/websites/website_template-corporate.zip and b/htdocs/install/doctemplates/websites/website_template-corporate.zip differ diff --git a/htdocs/install/medias/background_dolibarr.jpg b/htdocs/install/medias/background_dolibarr.jpg index b57e1a84814..6c4cc11460d 100644 Binary files a/htdocs/install/medias/background_dolibarr.jpg and b/htdocs/install/medias/background_dolibarr.jpg differ diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 3c351467284..5cac95078c0 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -472,6 +472,7 @@ Use3StepsApproval=By default, Purchase Orders need to be created and approved by UseDoubleApproval=Use a 3 steps approval when amount (without tax) is higher than... WarningPHPMail=WARNING: It is often better to setup outgoing emails to use the email server of your provider instead of the default setup. Some email providers (like Yahoo) do not allow you to send an email from another server than their own server. Your current setup uses the server of the application to send email and not the server of your email provider, so some recipients (the one compatible with the restrictive DMARC protocol), will ask your email provider if they can accept your email and some email providers (like Yahoo) may respond "no" because the server is not theirs, so few of your sent Emails may not be accepted (be careful also of your email provider's sending quota).
If your Email provider (like Yahoo) has this restriction, you must change Email setup to choose the other method "SMTP server" and enter the SMTP server and credentials provided by your Email provider. WarningPHPMail2=If your email SMTP provider need to restrict email client to some IP addresses (very rare), this is the IP address of the mail user agent (MUA) for your ERP CRM application: %s. +WarningPHPMailSPF=If the domain name in your sender email address is protected by SPF (ask you email provider), you must include the following IPs in the SPF record of the DNS of your domain: %s. ClickToShowDescription=Click to show description DependsOn=This module needs the module(s) RequiredBy=This module is required by module(s) @@ -1970,3 +1971,4 @@ 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. FeatureNotAvailableWithReceptionModule=Feature not available when module Reception is enabled EmailTemplate=Template for email +EMailsWillHaveMessageID=Emails will have a tag 'References' matching this syntax \ No newline at end of file diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 83ebdece24b..6e26ecb6835 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -519,6 +519,8 @@ TerreNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoice MarsNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for replacement invoices, %syymm-nnnn for down payment invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 TerreNumRefModelError=A bill starting with $syymm already exists and is not compatible with this model of sequence. Remove it or rename it to activate this module. CactusNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for credit notes and %syymm-nnnn for down payment invoices where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 +EarlyClosingReason=Early closing reason +EarlyClosingComment=Early closing note ##### Types de contacts ##### TypeContact_facture_internal_SALESREPFOLL=Representative following-up customer invoice TypeContact_facture_external_BILLING=Customer invoice contact diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 8540612f3a7..cc87e83d5c0 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -311,7 +311,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 13f359f43cc..46f347618f4 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -122,7 +122,7 @@ $search_all=trim(GETPOST("search_all", 'alpha')); $search=array(); foreach($object->fields as $key => $val) { - if (GETPOST('search_'.$key, 'alpha')) $search[$key]=GETPOST('search_'.$key, 'alpha'); + if (GETPOST('search_'.$key, 'alpha') !== '') $search[$key]=GETPOST('search_'.$key, 'alpha'); } // List of fields to search into when doing a "search in all" diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index bb3b19511ea..abaf216b7ab 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -406,7 +406,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 0d7fb48e45c..873b154ffeb 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -442,7 +442,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index 0c913834738..3d389cf7eb2 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -240,7 +240,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index f43f1fc3b1c..b6021c82cb8 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -174,7 +174,7 @@ if ($object->id > 0) } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/product/stock/card.php b/htdocs/product/stock/card.php index d6a1914afc5..99dc1978886 100644 --- a/htdocs/product/stock/card.php +++ b/htdocs/product/stock/card.php @@ -362,7 +362,7 @@ else } // Call Hook formConfirm - $parameters = array(); + $parameters = array('formConfirm' => $formconfirm); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index eaec20db955..b2723a0ce6a 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -1277,7 +1277,7 @@ elseif ($id || $ref) } if (!$formconfirm) { - $parameters = array(); + $parameters = array('formConfirm' => $formconfirm); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/resource/class/dolresource.class.php b/htdocs/resource/class/dolresource.class.php index 7e2f11e1bf5..4af42ea8ff2 100644 --- a/htdocs/resource/class/dolresource.class.php +++ b/htdocs/resource/class/dolresource.class.php @@ -615,7 +615,7 @@ class Dolresource extends CommonObject $sql .= ' AND '.$key.' = \''.$this->db->idate($value).'\''; } else { - $sql .= ' AND '.$key.' LIKE \'%'.$value.'%\''; + $sql .= ' AND '.$key.' LIKE \'%'.$this->db->escape($value).'%\''; } } } @@ -697,7 +697,7 @@ class Dolresource extends CommonObject $sql .= ' AND '.$key.' = \''.$this->db->idate($value).'\''; } else { - $sql .= ' AND '.$key.' LIKE \'%'.$value.'%\''; + $sql .= ' AND '.$key.' LIKE \'%'.$this->db->escape($value).'%\''; } } } diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 36415c0b951..2053e19dc72 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -52,20 +52,20 @@ $extrafields = new ExtraFields($db); $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); if (!is_array($search_array_options)) $search_array_options = array(); -$search_ref = GETPOST("search_ref"); -$search_type = GETPOST("search_type"); +$search_ref = GETPOST("search_ref", 'alpha'); +$search_type = GETPOST("search_type", 'alpha'); $filter = array(); if ($search_ref != '') { - $param .= '&search_ref='.$search_ref; + $param.='&search_ref='.urlencode($search_ref); $filter['t.ref'] = $search_ref; } if ($search_type != '') { - $param .= '&search_type='.$search_type; + $param.='&search_type='.urlencode($search_type); $filter['ty.label'] = $search_type; } -if ($search_label != '') $param .= '&search_label='.$search_label; + // Add $param from extra fields foreach ($search_array_options as $key => $val) { @@ -83,7 +83,7 @@ foreach ($search_array_options as $key => $val) $filter['ef.'.$tmpkey] = natural_search('ef.'.$tmpkey, $crit, $mode_search); } } -if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.$contextpage; +if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); $hookmanager->initHooks(array('resourcelist')); @@ -131,7 +131,6 @@ include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) // Both test are required to be compatible with all browsers { $search_ref = ""; - $search_label = ""; $search_type = ""; $search_array_options = array(); $filter = array(); diff --git a/htdocs/stripe/charge.php b/htdocs/stripe/charge.php index 77bd1d918bf..d198555e421 100644 --- a/htdocs/stripe/charge.php +++ b/htdocs/stripe/charge.php @@ -139,6 +139,10 @@ if (!$rowid) $type = $langs->trans("card"); } elseif ($charge->payment_method_details->type=='three_d_secure'){ $type = $langs->trans("card3DS"); + } elseif ($charge->payment_method_details->type=='sepa_debit'){ + $type = $langs->trans("sepadebit"); + } elseif ($charge->payment_method_details->type=='ideal'){ + $type = $langs->trans("iDEAL"); } if (! empty($charge->payment_intent)) { diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index f01ad4c0b1b..5067a4935bc 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1441,7 +1441,7 @@ if ($action == 'create') } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/website/websiteaccount_card.php b/htdocs/website/websiteaccount_card.php index 64fbd96dd61..36eb72dd916 100644 --- a/htdocs/website/websiteaccount_card.php +++ b/htdocs/website/websiteaccount_card.php @@ -211,7 +211,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/htdocs/zapier/hook_card.php b/htdocs/zapier/hook_card.php index c2eaa616cae..d4dec007d86 100644 --- a/htdocs/zapier/hook_card.php +++ b/htdocs/zapier/hook_card.php @@ -247,7 +247,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Call Hook formConfirm - $parameters = array('lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; diff --git a/test/phpunit/PaypalTest.php b/test/phpunit/PaypalTest.php index 438cbaa9309..96bfbefdf17 100644 --- a/test/phpunit/PaypalTest.php +++ b/test/phpunit/PaypalTest.php @@ -135,7 +135,7 @@ class PaypalTest extends PHPUnit\Framework\TestCase $langs=$this->savlangs; $db=$this->savdb; - $urltotest=getPaypalPaymentUrl(1, 'free'); + $urltotest=getPaypalPaymentUrl(0, 'free'); print "urltotest=".$urltotest."\n"; $result=getURLContent($urltotest, 'GET');