diff --git a/.gitignore b/.gitignore index 371c8be2f5e..e4790fe7b4e 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,4 @@ yarn.lock package-lock.json doc/install.lock +/factory/ diff --git a/ChangeLog b/ChangeLog index 103157f34fd..a0091c2c42a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,160 @@ English Dolibarr ChangeLog -------------------------------------------------------------- + +***** ChangeLog for 14.0.5 compared to 14.0.4 ***** + +FIX: 13.0: printFieldListWhere called twice on same query +FIX: 14.0.4 fatal error on cron list. +FIX: #19476 +FIX: #19564 +FIX: #19651 +FIX: Accountancy - SQL error on subledger account search in journal +FIX: apply eldy's suggestion to not overwrite existing extrafields of $line +FIX: Can't close a down payment if paid with credit notes. +FIX: better compatibility with multicompany +FIX: contact card: bad colspan value for separator extrafield in creation/modification form +FIX: discounts are applied both when fetching the best supplier price and when displaying it +FIX: double display for contact categorie on societe create card +FIX: fatal error on cron list. +FIX: holiday list: only mass delete if leave request is not in draft, canceled or refused, like in card +FIX: holiday mass deletion: correct return of record deleted +FIX: Holiday month report +FIX: info tab on customer invoice record not found +FIX: line extrafields are inoperative in dispatch cards even when they exist +FIX: list of categories in stats of supplier invoices +FIX: missing default value for more comprehensive +FIX: multicurrency: fields in discount unitialized when creating deposit +FIX: Navigation on bank transaction list +FIX: Can't edit a bank transaction due to bad permission check. +FIX: Option MAIN_DIRECT_STATUS_UPDATE broken. Ajax on/off not saving value in DB after updating to version >=12 +FIX: postgresql compatibility, "" as is not authorized +FIX: printFieldListWhere called twice (at different locations) for the same SQL query, can result in syntax errors +FIX: select too large into addrights (pb of missing parenthesis) +FIX: set optional from post, we can't untick boolean field on product card +FIX: Take into consideration work leave over serveral months +FIX: test if method exist on wrong object +FIX: title for nature of third party in company list +FIX: Urgent onglet contact inaccessible depuis une facture +FIX: wrong syntax of sql request + +***** ChangeLog for 14.0.4 compared to 14.0.3 ***** + +FIX: $totalarray is overwritten, totals were lost +FIX: 13.0 - due to a typo in the 'mode' parameter, the "first name" column of the list of members displays the full name +FIX: 13.0: end date required to edit a ticket message +FIX: 13.0 feedback of PR #18993: make ticket messages punctual events with attr percentage = -1 +FIX: 13.0 PR #18993: add comment on modified part +FIX: 13.0: sometimes firstname was mistyped as fistname +FIX: 14.0 - civility field of private third party creation form has inadequate width +FIX: 14.0 - civility field width inadequate due to select2 calculating the width while the field has no width (display: none) +FIX: 14.0 - due to a typo in the 'mode' parameter, the "first name" co… +FIX: #18634 : Problem of virtual stock with reception module enabled +FIX: #18695 Added ref_ext to supplier invoice +FIX: #18698 Supplier invoice list - "alert" checkbox not working +FIX: #18735 +FIX: #18767 : Adherent delete +FIX: #18797 +FIX: #18854 +FIX: #18875 in v14 +FIX: #18910 +FIX: #18910 : MRP List SQL query syntax error with more than one extrafileds. +FIX: #18912 Accountancy - SQL error when custom group is added without country defined +FIX: #18934 on-registration in the extrafieldsline database for deliveries +FIX: #18968 +FIX: #19008 +FIX: #19014 - the properties of some fields are not updated when you submit the form +FIX: #19210 +FIX: #19214 : PostgreSQL error on admin/limits.php +FIX: #19241 Project - Fix display salary in overview +FIX: #19305 +FIX: 2 columns for total labels +FIX: Accountancy - Format Quadra export - Missing line type C to create automaticly a subledger account with label +FIX: Accountancy - If deposit invoice is used, force binding in deposit accounting account to solve transaction +FIX: Accountancy - Missing specific filename for export on format FEC2, Ciel & repare it +FIX: Accountancy - Option of export popup are inverted +FIX: Accountancy - PHP8 +FIX: Accountancy - Product admin - SQL error when we affect accounting account with product_perentity activated +FIX: Accountancy simplified - Salaries are not present in report +FIX: Accountancy - Some correction on export name +FIX: Accountancy - Trunc code_journal to 2 in format XIMPORT (Ciel, Sage50) +FIX: add warehouse in projects' overview count +FIX: also on customer index for automatic binding +FIX: Attachment of pdf into shipment when sending email +FIX: autocalculation of the supplier price in main currency. +FIX: avoid warning if $categories is an id +FIX: bad sign of amount stored for multicurrency columns on credit notes +FIX: Bad use of a forced contact of another company on PDF/ODT documents +FIX: Bad use of dol_concatdesc() +FIX: Button text on proposal card for create a invoice +FIX: calculateCosts of BOM must not be included into fetch +FIX: calculation of balance in conciliation page on desc sorting. +FIX: card.php +FIX: Change date format of the inventorycode to be equal as mass stock transfert +FIX: check if greater 0 +FIX: close cash with some terminals in TakePOS +FIX: compatibility with Multicompany +FIX: consistent UX when calling a tab from the invoice card with empty ref/id +FIX: default language defined for IN country +FIX: Expense report - In edit mode, field qty doesn't accept decimal unlike the create mode +FIX: fetch of product with modulebuilder load too much data +FIX: filter for export of accounting documents +FIX: Filter on categories +FIX: generate documents with PDF options +FIX: indentation +FIX: init hookmanager after loading $conf values +FIX: invoice: inpossible to create an invoice because of very bad check + warnings when trying to print tabs for invoice with no ID +FIX: legal issue on expense report pdf (must also show price without tax) +FIX: list of categories in stats of supplier invoices +FIX: load tranlate array after setting lang +FIX: lost superadmin grade after edit user card +FIX: missing filter status=1 on rss feeds +FIX: missing permission check reported by me@lainwir3d.net on product api +FIX: missing return status +FIX: missing sql filter by entity +FIX: move fetch_optionnal into $ac_static->fetch() +FIX: only a superadmin can modify entity +FIX: only ones value is return for dictionaries +FIX: optional visibility on create card +FIX: payment style and html5 tags +FIX: payment using wrong type in takepos when too many payment mode +FIX: PR#18931 Remove useless explicit call to dol_shutdown +FIX: Product accountancy affectation with product_perentity activated (PR #18620) +FIX: products/services card: hidden extrafields were overridden +FIX: project task list: extrafields could not be displayed +FIX: Propal list - Problem of pagination on date +FIX: reload user lang +FIX: Remove not complete order from the virtual stock +FIX: Replenish: SQL error when no warehouse has been created + Warning when there are no warehouses +FIX: resource list : Use standard code to handle list filters +FIX: restrictedArea for payment delete +FIX: Ret PR +FIX: second approval back in stable feature as is the setting for minimum amount (last part from PR#14286) +FIX: selected lines on supplier invoice create +FIX: Selection of type "people" for membership must hide the company +FIX: select list of orders not complete when field type of company is on +FIX: show end hours in events linked to objects +FIX: support of localtax on expense report +FIX: task time: can't filter by user with pgsql + show error message +FIX: task time: keep on using natural_search +FIX: tcpdf vulnerability to roman numeral bomb, cf. tecnickom/TCPDF issue #315 +FIX: Test when date of invoie is in future (pb with TZ and offset) +FIX: Ticket - Card - Wrong font awesome library +FIX: Ticket - Duplicate field project when we create ticket from project +FIX: translation into email for member at membership validation. +FIX: Travis Sanitize SQL +FIX: unprivileged user can see task associated with a not allowed project +FIX: URGENT: impossible to create an invoice +FIX: Use of accent into filename of GED +FIX: user date timezone offset +FIX: User salary card - translation problem +FIX: user without permission can set ticket subject +FIX: We need a default price base type in variant creation case with multiprices when parent has been created with only one level price +FIX: wrong array key value +FIX: wrong check +FIX: wrong position of error message +Sync transifex. + ***** ChangeLog for 14.0.3 compared to 14.0.2 ***** FIX: #18698 Supplier invoice list - "alert" checkbox not working @@ -356,7 +510,8 @@ Following changes may create regressions for some external modules, but were nec * Removed deprecated substitution key __REFCLIENT__ (replaced with __REF_CLIENT__) * Removed constant MAIN_COUNTRIES_IN_EEC. You can now set if country is in Europe or not from the dictionary of countries. * v14 seems to work correctly on PHP v8 but it generates a lot of verbose warnings. Currently, v14 i snot yet officialy supported with PHP 8. - +* To execute shell or command line command, your code must never use method like exec, shell_exec, popen, .. but must use the built-in + method executeCLI() available into core/class/utils.class.php ***** ChangeLog for 13.0.5 compared to 13.0.4 ***** diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile index dca74e9e720..e39f96b0b27 100644 --- a/build/docker/Dockerfile +++ b/build/docker/Dockerfile @@ -39,15 +39,13 @@ RUN chmod +x /usr/local/bin/docker-run.sh RUN pecl install xdebug && docker-php-ext-enable xdebug RUN echo 'zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so"' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_autostart=1' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_enable=1' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.default_enable=1' >> ${PHP_INI_DIR}/php.ini -#RUN echo 'xdebug.remote_host=docker.host' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_port=9000' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_connect_back=1' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.profiler_enable=0' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_log="/tmp/xdebug.log"' >> ${PHP_INI_DIR}/php.ini -#RUN echo 'localhost docker.host' >> /etc/hosts +RUN echo 'xdebug.mode=debug' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.start_with_request=yes' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.client_host=host.docker.internal' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.client_port=9003' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.discover_client_host=true' >> ${PHP_INI_DIR}/php.ini +#RUN echo 'xdebug.log="/tmp/xdebug.log"' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.idekey="netbeans-xdebug"' >> ${PHP_INI_DIR}/php.ini # set up sendmail config, to use maildev RUN echo "account default" > /etc/msmtprc diff --git a/build/docker/docker-compose.yml b/build/docker/docker-compose.yml index 2167f069f25..8994043cd8a 100644 --- a/build/docker/docker-compose.yml +++ b/build/docker/docker-compose.yml @@ -46,6 +46,9 @@ services: networks: - internal-pod - external-pod + extra_hosts: + - "localhost.localdomain:127.0.0.1" + - "host.docker.internal:host-gateway" mail: image: maildev/maildev diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index 58ffa9bd150..6056a310be7 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -198,7 +198,7 @@ if ($action == 'update') { $nb_exists = $db->num_rows($resql_exists); if ($nb_exists <= 0) { // insert - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_perentity (fk_product, entity, '" . $db->escape($accountancy_field_name) . "')"; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_perentity (fk_product, entity, " . $db->escape($accountancy_field_name) . ")"; $sql .= " VALUES (" . ((int) $productid) . ", " . ((int) $conf->entity) . ", '" . $db->escape($accounting->account_number) . "')"; } else { $obj_exists = $db->fetch_object($resql_exists); diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index ec01d9c697c..52ac288856b 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -333,10 +333,6 @@ if (empty($reshook)) { $filter['t.numero_compte<='] = $search_accountancy_code_end; $param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end); } - if (!empty($search_accountancy_aux_code)) { - $filter['t.subledger_account'] = $search_accountancy_aux_code; - $param .= '&search_accountancy_aux_code='.urlencode($search_accountancy_aux_code); - } if (!empty($search_accountancy_aux_code_start)) { $filter['t.subledger_account>='] = $search_accountancy_aux_code_start; $param .= '&search_accountancy_aux_code_start='.urlencode($search_accountancy_aux_code_start); @@ -533,14 +529,12 @@ if (count($filter) > 0) { $sqlwhere[] = $key.'=\''.$db->idate($value).'\''; } elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') { $sqlwhere[] = $key.'\''.$db->idate($value).'\''; - } elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=') { + } elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') { $sqlwhere[] = $key.'\''.$db->escape($value).'\''; } elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') { $sqlwhere[] = $key.'='.$value; - } elseif ($key == 't.numero_compte') { + } elseif ($key == 't.subledger_account' || $key == 't.numero_compte') { $sqlwhere[] = $key.' LIKE \''.$db->escape($value).'%\''; - } elseif ($key == 't.subledger_account') { - $sqlwhere[] = natural_search($key, $value, 0, 1); } elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') { $sqlwhere[] = $key.'\''.$db->idate($value).'\''; } elseif ($key == 't.tms>=' || $key == 't.tms<=') { diff --git a/htdocs/accountancy/class/accountancyimport.class.php b/htdocs/accountancy/class/accountancyimport.class.php index ece843515e2..ea88534b6ed 100644 --- a/htdocs/accountancy/class/accountancyimport.class.php +++ b/htdocs/accountancy/class/accountancyimport.class.php @@ -55,8 +55,8 @@ class AccountancyImport $fieldname = $fieldArr[1]; } - $debit = trim($arrayrecord[11]['val']); - $credit = trim($arrayrecord[12]['val']); + $debit = floatval(trim($arrayrecord[11]['val'])); + $credit = floatval(trim($arrayrecord[12]['val'])); if (!empty($debit)) { $amount = $debit; } else { @@ -86,7 +86,7 @@ class AccountancyImport $fieldname = $fieldArr[1]; } - $debit = trim($arrayrecord[11]['val']); + $debit = floatval(trim($arrayrecord[11]['val'])); if (!empty($debit)) { $sens = 'D'; } else { diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 43dcce8c646..5635df3c8e7 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -331,7 +331,7 @@ class BookKeeping extends CommonObject if (empty($this->piece_num)) { $sqlnum = "SELECT MAX(piece_num)+1 as maxpiecenum"; $sqlnum .= " FROM ".MAIN_DB_PREFIX.$this->table_element; - $sqlnum .= " WHERE entity = ".$conf->entity; // Do not use getEntity for accounting features + $sqlnum .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features $resqlnum = $this->db->query($sqlnum); if ($resqlnum) { @@ -736,7 +736,7 @@ class BookKeeping extends CommonObject $sql .= " t.date_validated as date_validation"; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.$mode.' as t'; $sql .= ' WHERE 1 = 1'; - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features if (null !== $ref) { $sql .= " AND t.ref = '".$this->db->escape($ref)."'"; } else { @@ -881,7 +881,7 @@ class BookKeeping extends CommonObject } $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; $sql .= ' WHERE 1 = 1'; - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features if (count($sqlwhere) > 0) { $sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere); } @@ -1037,7 +1037,7 @@ class BookKeeping extends CommonObject } } } - $sql .= ' WHERE t.entity IN ('.getEntity('accountancy').')'; + $sql .= ' WHERE t.entity = ' . ((int) $conf->entity); // Do not use getEntity for accounting features if ($showAlreadyExportMovements == 0) { $sql .= " AND t.date_export IS NULL"; } @@ -1157,7 +1157,7 @@ class BookKeeping extends CommonObject } } } - $sql .= ' WHERE entity IN ('.getEntity('accountancy').')'; + $sql .= ' WHERE entity = ' . ((int) $conf->entity); // Do not use getEntity for accounting features if (count($sqlwhere) > 0) { $sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere); } @@ -1454,7 +1454,7 @@ class BookKeeping extends CommonObject */ public function deleteByYearAndJournal($delyear = 0, $journal = '', $mode = '', $delmonth = 0) { - global $langs; + global $conf, $langs; if (empty($delyear) && empty($journal)) { $this->error = 'ErrorOneFieldRequired'; @@ -1475,7 +1475,7 @@ class BookKeeping extends CommonObject if (!empty($journal)) { $sql .= " AND code_journal = '".$this->db->escape($journal)."'"; } - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features // Exclusion of validated entries at the time of deletion $sql .= " AND date_validated IS NULL"; @@ -1514,7 +1514,7 @@ class BookKeeping extends CommonObject $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql .= " WHERE piece_num = ".(int) $piecenum; $sql .= " AND date_validated IS NULL"; // For security, exclusion of validated entries at the time of deletion - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features $resql = $this->db->query($sql); @@ -1636,7 +1636,7 @@ class BookKeeping extends CommonObject } $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql .= " WHERE piece_num = ".$piecenum; - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(__METHOD__, LOG_DEBUG); $result = $this->db->query($sql); @@ -1674,9 +1674,9 @@ class BookKeeping extends CommonObject global $conf; $sql = "SELECT MAX(piece_num)+1 as max FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; - $sql .= " WHERE entity IN (".getEntity('accountancy').")"; + $sql .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features - dol_syslog(get_class($this)."getNextNumMvt sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this)."::getNextNumMvt sql=".$sql, LOG_DEBUG); $result = $this->db->query($sql); if ($result) { @@ -1717,7 +1717,7 @@ class BookKeeping extends CommonObject } $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql .= " WHERE piece_num = ".$piecenum; - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(__METHOD__, LOG_DEBUG); $result = $this->db->query($sql); @@ -1780,7 +1780,7 @@ class BookKeeping extends CommonObject $sql .= " montant as amount, sens, fk_user_author, import_key, code_journal, piece_num,"; $sql .= " date_validated as date_validation"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; - $sql .= " WHERE entity IN (".getEntity('accountancy').")"; + $sql .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(get_class($this)."::export_bookkeeping", LOG_DEBUG); @@ -1836,6 +1836,8 @@ class BookKeeping extends CommonObject */ public function transformTransaction($direction = 0, $piece_num = '') { + global $conf; + $error = 0; $this->db->begin(); @@ -1855,14 +1857,14 @@ class BookKeeping extends CommonObject $sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,'; $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.$next_piecenum.", '".$this->db->idate($now)."'"; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->errors[] = 'Error '.$this->db->lasterror(); dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); } - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -1870,7 +1872,7 @@ class BookKeeping extends CommonObject dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); } } elseif ($direction == 1) { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -1885,14 +1887,14 @@ class BookKeeping extends CommonObject $sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,'; $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->errors[] = 'Error '.$this->db->lasterror(); dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); } - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -1947,7 +1949,7 @@ class BookKeeping extends CommonObject $sql .= " AND aa.active = 1"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version"; $sql .= " AND asy.rowid = ".((int) $pcgver); - $sql .= " AND ab.entity IN (".getEntity('accountancy').")"; + $sql .= " AND ab.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features $sql .= " ORDER BY account_number ASC"; dol_syslog(get_class($this)."::select_account", LOG_DEBUG); @@ -2011,7 +2013,7 @@ class BookKeeping extends CommonObject $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as parent ON aa.account_parent = parent.rowid AND parent.active = 1"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as root ON parent.account_parent = root.rowid AND root.active = 1"; $sql .= " WHERE aa.account_number = '".$this->db->escape($account)."'"; - $sql .= " AND aa.entity IN (".getEntity('accountancy').")"; + $sql .= " AND aa.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(get_class($this)."::select_account sql=".$sql, LOG_DEBUG); $resql = $this->db->query($sql); @@ -2051,7 +2053,7 @@ class BookKeeping extends CommonObject $sql .= " AND asy.rowid = ".((int) $pcgver); $sql .= " AND aa.active = 1"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as cat ON aa.fk_accounting_category = cat.rowid"; - $sql .= " WHERE aa.entity IN (".getEntity('accountancy').")"; + $sql .= " WHERE aa.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(get_class($this)."::select_account sql=".$sql, LOG_DEBUG); $resql = $this->db->query($sql); diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index 0ee9c865603..c233134f562 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -170,6 +170,8 @@ if ($action == 'validatehistory') { } else { $num_lines = $db->num_rows($result); + $facture_static = new Facture($db); + $isSellerInEEC = isInEEC($mysoc); $i = 0; @@ -213,6 +215,18 @@ if ($action == 'validatehistory') { } } + // Manage Deposit + if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT)) { + if ($objp->description == "(DEPOSIT)" || $objp->ftype == $facture_static::TYPE_DEPOSIT) { + $accountdeposittoventilated = new AccountingAccount($db); + $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1); + $objp->code_sell_l = $accountdeposittoventilated->ref; + $objp->code_sell_p = ''; + $objp->code_sell_t = ''; + $objp->aarowid_suggest = $accountdeposittoventilated->rowid; + } + } + if ($objp->aarowid_suggest > 0) { $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."facturedet"; $sqlupdate .= " SET fk_code_ventilation = ".((int) $objp->aarowid_suggest); @@ -389,6 +403,7 @@ if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { } $sql .= " AND aa.account_number IS NOT NULL"; $sql .= " GROUP BY fd.fk_code_ventilation,aa.account_number,aa.label"; +$sql .= ' ORDER BY aa.account_number'; dol_syslog('htdocs/accountancy/customer/index.php'); $resql = $db->query($sql); @@ -506,16 +521,23 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange print ''.$langs->trans('MonthShort'.str_pad($j, 2, '0', STR_PAD_LEFT)).''; } print ''.$langs->trans("Total").''; - $sql = "SELECT '".$db->escape($langs->trans("Vide"))."' AS marge,"; for ($i = 1; $i <= 12; $i++) { $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1; if ($j > 12) { $j -= 12; } - $sql .= " SUM(".$db->ifsql('MONTH(f.datef)='.$j, '(fd.total_ht-(fd.qty * fd.buy_price_ht))', '0').") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).","; + $sql .= ' + SUM('.$db->ifsql('MONTH(f.datef)='.$j, + ' ('. + $db->ifsql('fd.total_ht < 0', + ' (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))', + ' (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))' + ).')', + 0).') AS month'.str_pad($j, 2, '0', STR_PAD_LEFT).','; } $sql .= " SUM((fd.total_ht-(fd.qty * fd.buy_price_ht))) as total"; + $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = fd.fk_facture"; $sql .= " WHERE f.datef >= '".$db->idate($search_date_start)."'"; @@ -532,7 +554,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange } else { $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_DEPOSIT.", ".Facture::TYPE_SITUATION.")"; } - dol_syslog('htdocs/accountancy/customer/index.php'); $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 5ce9f5e13e8..2be7cd5f4ca 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -637,11 +637,15 @@ if ($result) { } // Manage Deposit - if ($objp->description == "(DEPOSIT)") { - $accountdeposittoventilated = new AccountingAccount($db); - $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1); - $objp->code_sell_l = $accountdeposittoventilated->ref; - $objp->aarowid_suggest = $accountdeposittoventilated->rowid; + if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT)) { + if ($objp->description == "(DEPOSIT)" || $objp->ftype == $facture_static::TYPE_DEPOSIT) { + $accountdeposittoventilated = new AccountingAccount($db); + $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1); + $objp->code_sell_l = $accountdeposittoventilated->ref; + $objp->code_sell_p = ''; + $objp->code_sell_t = ''; + $objp->aarowid_suggest = $accountdeposittoventilated->rowid; + } } if (!empty($objp->code_sell_p)) { diff --git a/htdocs/accountancy/expensereport/index.php b/htdocs/accountancy/expensereport/index.php index 0e3bda39521..2d9c8ac4f1c 100644 --- a/htdocs/accountancy/expensereport/index.php +++ b/htdocs/accountancy/expensereport/index.php @@ -188,6 +188,7 @@ $sql .= " AND er.fk_statut IN (".ExpenseReport::STATUS_APPROVED.", ".ExpenseRepo $sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy $sql .= " AND aa.account_number IS NULL"; $sql .= " GROUP BY erd.fk_code_ventilation,aa.account_number,aa.label"; +$sql .= ' ORDER BY aa.account_number'; dol_syslog('/accountancy/expensereport/index.php:: sql='.$sql); $resql = $db->query($sql); diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php index 585121f7c36..9ea8fd0a307 100644 --- a/htdocs/accountancy/supplier/index.php +++ b/htdocs/accountancy/supplier/index.php @@ -300,6 +300,7 @@ $sql .= " AND ffd.product_type <= 2"; $sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy $sql .= " AND aa.account_number IS NULL"; $sql .= " GROUP BY ffd.fk_code_ventilation,aa.account_number,aa.label"; +$sql .= ' ORDER BY aa.account_number'; dol_syslog('htdocs/accountancy/supplier/index.php'); $resql = $db->query($sql); diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 6b8a3fbc267..fd500b34775 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -312,7 +312,7 @@ if (empty($reshook)) { $object->public = GETPOST("public", 'alpha'); // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost(null, $object); + $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET'); if ($ret < 0) { $error++; } diff --git a/htdocs/adherents/stats/index.php b/htdocs/adherents/stats/index.php index ed79978552f..7bf395e9bcc 100644 --- a/htdocs/adherents/stats/index.php +++ b/htdocs/adherents/stats/index.php @@ -195,9 +195,7 @@ foreach ($data as $val) { } print ''; print ''; - //print ''; - print $year; - //print ''; + print ''.$year.''; print ''; print ''.$val['nb'].''; print ''.price(price2num($val['total'], 'MT'), 1).''; diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 1316a337610..d9ab62336a1 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -943,8 +943,10 @@ if ($rowid > 0) { } if (!$datefrom) { $datefrom = $object->datevalid; - if ($object->datefin > 0) { + if ($object->datefin > 0 && dol_time_plus_duree($object->datefin, $defaultdelay, $defaultdelayunit) > dol_now()) { $datefrom = dol_time_plus_duree($object->datefin, 1, 'd'); + } else { + $datefrom = dol_get_first_day(dol_print_date(time(), "%Y")); } } print $form->selectDate($datefrom, '', '', '', '', "subscription", 1, 1); diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index 7146e89648e..4c9935b76a8 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -311,6 +311,7 @@ print ''; print ''; print ''; print ''; +print ''; print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $subscription->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 76099ff7d66..bdae16901c1 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -180,7 +180,7 @@ if ($action == 'update' && $user->rights->adherent->configurer) { $object->vote = (boolean) trim($vote); // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost(null, $object); + $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET'); if ($ret < 0) { $error++; } diff --git a/htdocs/admin/dolistore/class/dolistore.class.php b/htdocs/admin/dolistore/class/dolistore.class.php index 5e7a229fee3..f672cf05a52 100644 --- a/htdocs/admin/dolistore/class/dolistore.class.php +++ b/htdocs/admin/dolistore/class/dolistore.class.php @@ -267,9 +267,9 @@ class Dolistore // add image or default ? if ($product->id_default_image != '') { - $image_url = DOL_URL_ROOT.'/admin/dolistore/ajax/image.php?id_product='.((int) $product->id).'&id_image='.((int) $product->id_default_image); - $images = ''; - $images .= ''; + $image_url = DOL_URL_ROOT.'/admin/dolistore/ajax/image.php?id_product='.urlencode(((int) $product->id)).'&id_image='.urlencode(((int) $product->id_default_image)); + $images = ''; + $images .= ''; } else { $images = ''; } @@ -277,14 +277,15 @@ class Dolistore // free or pay ? if ($product->price > 0) { $price = '

'.price(price2num($product->price, 'MT'), 0, $langs, 1, -1, -1, 'EUR').' '.$langs->trans("HT").'

'; - $download_link = ''; + $download_link = ''; } else { $price = '

'.$langs->trans('Free').'

'; - $download_link = ''; - $download_link .= '

'; + $download_link = ''; + $download_link .= '

'; } - //checking versions + // Set and check version + $version = ''; if ($this->version_compare($product->dolibarr_min, DOL_VERSION) <= 0) { if ($this->version_compare($product->dolibarr_max, DOL_VERSION) >= 0) { //compatible @@ -319,14 +320,21 @@ class Dolistore //.'
'.$langs->trans("SeeInMarkerPlace").' //output template - $html .= ' -
'.dol_escape_htmltag($newapp.$images).'
-

'.dol_escape_htmltag($product->name->language[$this->lang - 1]) - .'
'.dol_escape_htmltag($version).'

- '.dol_print_date(dol_stringtotime($product->date_upd), 'dayhour').' - '.$langs->trans('Ref').': '.dol_escape_htmltag($product->reference).' - '.dol_escape_htmltag($langs->trans('Id')).': '.((int) $product->id).'

'.dol_escape_htmltag($product->description_short->language[$this->lang - 1]).''; + $html .= ''; + $html .= '
'; + $html .= $newapp.$images; // No dol_escape_htmltag, it is already escape html + $html .= '
'; + $html .= '

'; + $html .= dol_escape_htmltag($product->name->language[$this->lang - 1]); + $html .= '
'; + $html .= $version; // No dol_escape_htmltag, it is already escape html + $html .= '

'; + $html .= ' '.dol_print_date(dol_stringtotime($product->date_upd), 'dayhour').' - '.$langs->trans('Ref').': '.dol_escape_htmltag($product->reference).' - '.dol_escape_htmltag($langs->trans('Id')).': '.((int) $product->id).'

'.dol_escape_htmltag($product->description_short->language[$this->lang - 1]).''; // do not load if display none //$html .= ''.$product->description->language[$this->lang - 1].''; - $html .= ''.dol_escape_htmltag($price).''; + $html .= ''; + $html .= $price; + $html .= ''; $html .= ''.$download_link.''; $html .= ''; } diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index cf4c250a678..a4c6f27c4b2 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -417,7 +417,7 @@ print ''; // Show bugtrack link print ''.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; -print ''; +print ''; print ''; print ' '; print ''; diff --git a/htdocs/admin/limits.php b/htdocs/admin/limits.php index 4a599499053..a65c1cb5696 100644 --- a/htdocs/admin/limits.php +++ b/htdocs/admin/limits.php @@ -237,7 +237,7 @@ if (empty($mysoc->country_code)) { $sql = "SELECT taux as vat_rate, t.code as vat_code, t.localtax1 as localtax_rate1, t.localtax2 as localtax_rate2"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; - $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='".$db->escape($mysoc->country_code)."' AND (t.taux <> 0 OR t.localtax1 <>0 OR t.localtax2 <>0)"; + $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='".$db->escape($mysoc->country_code)."' AND (t.taux <> 0 OR t.localtax1 <> '0' OR t.localtax2 <> '0')"; $sql .= " ORDER BY t.taux ASC"; $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 7d8bc2f22b1..0adc526d69e 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -225,6 +225,9 @@ if (!empty($conf->contrat->enabled) && !empty($user->rights->contrat->lire)) { if (!empty($conf->ticket->enabled) && !empty($user->rights->ticket->read)) { $elementList['ticket_send'] = img_picto('', 'ticket', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToTicket')); } +if (!empty($conf->expensereport->enabled) && !empty($user->rights->expensereport->lire)) { + $elementList['expensereport_send'] = img_picto('', 'trip', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToTExpenseReport')); +} if (!empty($conf->agenda->enabled)) { $elementList['actioncomm_send'] = img_picto('', 'action', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToSendEventPush')); } diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 00142deb9e8..236c8c0b28e 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -526,7 +526,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { $moreforfilter = '
'; - $moreforfilter .= '