From 2fdc6d9461bbc8b6943ac8e6ecad5e65ba86cda5 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 4 Jun 2021 11:35:12 +0200 Subject: [PATCH 01/28] NEW : rewrite bind accountancy code finding on customer invoice --- htdocs/accountancy/admin/account.php | 2 +- .../class/accountingaccount.class.php | 556 ++++++++++++------ htdocs/accountancy/customer/list.php | 189 ++---- 3 files changed, 420 insertions(+), 327 deletions(-) diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 6f510ad3706..1f7f8892cad 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -195,7 +195,7 @@ if (empty($reshook)) { } elseif ($action == 'enable' && $permissiontoadd) { if ($accounting->fetch($id)) { $mode = GETPOST('mode', 'int'); - $result = $accounting->account_activate($id, $mode); + $result = $accounting->accountActivate($id, $mode); } $action = 'update'; if ($result < 0) { diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 28601380ac1..c4a11fb6565 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -26,6 +26,9 @@ * \brief File of class to manage accounting accounts */ +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; /** * Class to manage accounting accounts */ @@ -140,6 +143,11 @@ class AccountingAccount extends CommonObject */ public $reconcilable; + /** + * @var array cache array + */ + private $accountingaccount_codetotid_cache = array(); + /** * Constructor * @@ -150,83 +158,14 @@ class AccountingAccount extends CommonObject global $conf; $this->db = $db; - $this->next_prev_filter = 'fk_pcg_version IN (SELECT pcg_version FROM '.MAIN_DB_PREFIX.'accounting_system WHERE rowid='.$conf->global->CHARTOFACCOUNTS.')'; // Used to add a filter in Form::showrefnav method - } - - /** - * Load record in memory - * - * @param int $rowid Id - * @param string $account_number Account number - * @param int|boolean $limittocurrentchart 1 or true=Load record only if it is into current active char of account - * @param string $limittoachartaccount 'ABC'=Load record only if it is into chart account with code 'ABC' (better and faster than previous parameter if you have chart of account code). - * @return int <0 if KO, 0 if not found, Id of record if OK and found - */ - public function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0, $limittoachartaccount = '') - { - global $conf; - - if ($rowid || $account_number) { - $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.account_number, a.account_parent, a.label, a.labelshort, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active, a.reconcilable"; - $sql .= ", ca.label as category_label"; - $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as a"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as ca ON a.fk_accounting_category = ca.rowid"; - $sql .= " WHERE"; - if ($rowid) { - $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).')'; - } - if (!empty($limittoachartaccount)) { - $sql .= " AND a.fk_pcg_version = '".$this->db->escape($limittoachartaccount)."'"; - } - - dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $obj = $this->db->fetch_object($result); - - if ($obj) { - $this->id = $obj->rowid; - $this->rowid = $obj->rowid; - $this->ref = $obj->account_number; - $this->datec = $obj->datec; - $this->tms = $obj->tms; - $this->fk_pcg_version = $obj->fk_pcg_version; - $this->pcg_type = $obj->pcg_type; - $this->account_number = $obj->account_number; - $this->account_parent = $obj->account_parent; - $this->label = $obj->label; - $this->labelshort = $obj->labelshort; - $this->account_category = $obj->fk_accounting_category; - $this->account_category_label = $obj->category_label; - $this->fk_user_author = $obj->fk_user_author; - $this->fk_user_modif = $obj->fk_user_modif; - $this->active = $obj->active; - $this->status = $obj->active; - $this->reconcilable = $obj->reconcilable; - - return $this->id; - } else { - return 0; - } - } else { - $this->error = "Error ".$this->db->lasterror(); - $this->errors[] = "Error ".$this->db->lasterror(); - } - } - return -1; + $this->next_prev_filter = 'fk_pcg_version IN (SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $conf->global->CHARTOFACCOUNTS . ')'; // Used to add a filter in Form::showrefnav method } /** * Insert new accounting account in chart of accounts * - * @param User $user User making action - * @param int $notrigger Disable triggers + * @param User $user User making action + * @param int $notrigger Disable triggers * @return int <0 if KO, >0 if OK */ public function create($user, $notrigger = 0) @@ -259,7 +198,7 @@ class AccountingAccount extends CommonObject // Put here code to add control on parameters values // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX."accounting_account("; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account("; $sql .= "datec"; $sql .= ", entity"; $sql .= ", fk_pcg_version"; @@ -273,31 +212,31 @@ class AccountingAccount extends CommonObject $sql .= ", active"; $sql .= ", reconcilable"; $sql .= ") VALUES ("; - $sql .= " '".$this->db->idate($now)."'"; - $sql .= ", ".$conf->entity; - $sql .= ", ".(empty($this->fk_pcg_version) ? 'NULL' : "'".$this->db->escape($this->fk_pcg_version)."'"); - $sql .= ", ".(empty($this->pcg_type) ? 'NULL' : "'".$this->db->escape($this->pcg_type)."'"); - $sql .= ", ".(empty($this->account_number) ? 'NULL' : "'".$this->db->escape($this->account_number)."'"); - $sql .= ", ".(empty($this->account_parent) ? 0 : (int) $this->account_parent); - $sql .= ", ".(empty($this->label) ? "''" : "'".$this->db->escape($this->label)."'"); - $sql .= ", ".(empty($this->labelshort) ? "''" : "'".$this->db->escape($this->labelshort)."'"); - $sql .= ", ".(empty($this->account_category) ? 0 : (int) $this->account_category); - $sql .= ", ".$user->id; - $sql .= ", ".(int) $this->active; - $sql .= ", ".(int) $this->reconcilable; + $sql .= " '" . $this->db->idate($now) . "'"; + $sql .= ", " . $conf->entity; + $sql .= ", " . (empty($this->fk_pcg_version) ? 'NULL' : "'" . $this->db->escape($this->fk_pcg_version) . "'"); + $sql .= ", " . (empty($this->pcg_type) ? 'NULL' : "'" . $this->db->escape($this->pcg_type) . "'"); + $sql .= ", " . (empty($this->account_number) ? 'NULL' : "'" . $this->db->escape($this->account_number) . "'"); + $sql .= ", " . (empty($this->account_parent) ? 0 : (int) $this->account_parent); + $sql .= ", " . (empty($this->label) ? "''" : "'" . $this->db->escape($this->label) . "'"); + $sql .= ", " . (empty($this->labelshort) ? "''" : "'" . $this->db->escape($this->labelshort) . "'"); + $sql .= ", " . (empty($this->account_category) ? 0 : (int) $this->account_category); + $sql .= ", " . $user->id; + $sql .= ", " . (int) $this->active; + $sql .= ", " . (int) $this->reconcilable; $sql .= ")"; $this->db->begin(); - dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this) . "::create sql=" . $sql, LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $error++; - $this->errors[] = "Error ".$this->db->lasterror(); + $this->errors[] = "Error " . $this->db->lasterror(); } if (!$error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."accounting_account"); + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account"); // Uncomment this and change MYOBJECT to your own tag if you // want this action to call a trigger. @@ -313,8 +252,8 @@ class AccountingAccount extends CommonObject // Commit or rollback if ($error) { foreach ($this->errors as $errmsg) { - dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); - $this->error .= ($this->error ? ', '.$errmsg : $errmsg); + dol_syslog(get_class($this) . "::create " . $errmsg, LOG_ERR); + $this->error .= ($this->error ? ', ' . $errmsg : $errmsg); } $this->db->rollback(); return -1 * $error; @@ -327,7 +266,7 @@ class AccountingAccount extends CommonObject /** * Update record * - * @param User $user Use making update + * @param User $user Use making update * @return int <0 if KO, >0 if OK */ public function update($user) @@ -339,20 +278,20 @@ class AccountingAccount extends CommonObject $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account "; - $sql .= " SET fk_pcg_version = ".($this->fk_pcg_version ? "'".$this->db->escape($this->fk_pcg_version)."'" : "null"); - $sql .= " , pcg_type = ".($this->pcg_type ? "'".$this->db->escape($this->pcg_type)."'" : "null"); - $sql .= " , account_number = '".$this->db->escape($this->account_number)."'"; - $sql .= " , account_parent = ".(int) $this->account_parent; - $sql .= " , label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "''"); - $sql .= " , labelshort = ".($this->labelshort ? "'".$this->db->escape($this->labelshort)."'" : "''"); - $sql .= " , fk_accounting_category = ".(empty($this->account_category) ? 0 : (int) $this->account_category); - $sql .= " , fk_user_modif = ".((int) $user->id); - $sql .= " , active = ".(int) $this->active; - $sql .= " , reconcilable = ".(int) $this->reconcilable; - $sql .= " WHERE rowid = ".((int) $this->id); + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null"); + $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null"); + $sql .= " , account_number = '" . $this->db->escape($this->account_number) . "'"; + $sql .= " , account_parent = " . (int) $this->account_parent; + $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "''"); + $sql .= " , labelshort = " . ($this->labelshort ? "'" . $this->db->escape($this->labelshort) . "'" : "''"); + $sql .= " , fk_accounting_category = " . (empty($this->account_category) ? 0 : (int) $this->account_category); + $sql .= " , fk_user_modif = " . ((int) $user->id); + $sql .= " , active = " . (int) $this->active; + $sql .= " , reconcilable = " . (int) $this->reconcilable; + $sql .= " WHERE rowid = " . ((int) $this->id); - dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this) . "::update sql=" . $sql, LOG_DEBUG); $result = $this->db->query($sql); if ($result) { $this->db->commit(); @@ -364,38 +303,6 @@ class AccountingAccount extends CommonObject } } - /** - * Check usage of accounting code - * - * @return int <0 if KO, >0 if OK - */ - public function checkUsage() - { - global $langs; - - $sql = "(SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facturedet"; - $sql .= " WHERE fk_code_ventilation=".$this->id.")"; - $sql .= "UNION"; - $sql .= " (SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facture_fourn_det"; - $sql .= " WHERE fk_code_ventilation=".$this->id.")"; - - dol_syslog(get_class($this)."::checkUsage sql=".$sql, LOG_DEBUG); - $resql = $this->db->query($sql); - - if ($resql) { - $num = $this->db->num_rows($resql); - if ($num > 0) { - $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse'); - return 0; - } else { - return 1; - } - } else { - $this->error = $this->db->lasterror(); - return -1; - } - } - /** * Delete object in database * @@ -413,22 +320,22 @@ class AccountingAccount extends CommonObject $this->db->begin(); if (!$error) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."accounting_account"; - $sql .= " WHERE rowid=".((int) $this->id); + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account"; + $sql .= " WHERE rowid=" . ((int) $this->id); - dol_syslog(get_class($this)."::delete sql=".$sql); + dol_syslog(get_class($this) . "::delete sql=" . $sql); $resql = $this->db->query($sql); if (!$resql) { $error++; - $this->errors[] = "Error ".$this->db->lasterror(); + $this->errors[] = "Error " . $this->db->lasterror(); } } // Commit or rollback if ($error) { foreach ($this->errors as $errmsg) { - dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); - $this->error .= ($this->error ? ', '.$errmsg : $errmsg); + dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR); + $this->error .= ($this->error ? ', ' . $errmsg : $errmsg); } $this->db->rollback(); return -1 * $error; @@ -441,23 +348,55 @@ class AccountingAccount extends CommonObject } } + /** + * Check usage of accounting code + * + * @return int <0 if KO, >0 if OK + */ + public function checkUsage() + { + global $langs; + + $sql = "(SELECT fk_code_ventilation FROM " . MAIN_DB_PREFIX . "facturedet"; + $sql .= " WHERE fk_code_ventilation=" . $this->id . ")"; + $sql .= "UNION"; + $sql .= " (SELECT fk_code_ventilation FROM " . MAIN_DB_PREFIX . "facture_fourn_det"; + $sql .= " WHERE fk_code_ventilation=" . $this->id . ")"; + + dol_syslog(get_class($this) . "::checkUsage sql=" . $sql, LOG_DEBUG); + $resql = $this->db->query($sql); + + if ($resql) { + $num = $this->db->num_rows($resql); + if ($num > 0) { + $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse'); + return 0; + } else { + return 1; + } + } else { + $this->error = $this->db->lasterror(); + return -1; + } + } + /** * Return clicable name (with picto eventually) * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param int $withlabel 0=No label, 1=Include label of account - * @param int $nourl 1=Disable url - * @param string $moretitle Add more text to title tooltip - * @param int $notooltip 1=Disable tooltip - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @param int $withcompletelabel 0=Short label (field short label), 1=Complete label (field label) - * @param string $option 'ledger', 'journals', 'accountcard' - * @return string String with URL + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @param int $withlabel 0=No label, 1=Include label of account + * @param int $nourl 1=Disable url + * @param string $moretitle Add more text to title tooltip + * @param int $notooltip 1=Disable tooltip + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @param int $withcompletelabel 0=Short label (field short label), 1=Complete label (field label) + * @param string $option 'ledger', 'journals', 'accountcard' + * @return string String with URL */ public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '') { global $langs, $conf; - require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -465,15 +404,16 @@ class AccountingAccount extends CommonObject $result = ''; - $url = ''; $labelurl = ''; + $url = ''; + $labelurl = ''; if (empty($option) || $option == 'ledger') { - $url = DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start='.urlencode($this->account_number).'&search_accountancy_code_end='.urlencode($this->account_number); + $url = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number); $labelurl = $langs->trans("ShowAccountingAccountInLedger"); } elseif ($option == 'journals') { - $url = DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?search_accountancy_code_start='.urlencode($this->account_number).'&search_accountancy_code_end='.urlencode($this->account_number); + $url = DOL_URL_ROOT . '/accountancy/bookkeeping/list.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number); $labelurl = $langs->trans("ShowAccountingAccountInJournals"); } elseif ($option == 'accountcard') { - $url = DOL_URL_ROOT.'/accountancy/admin/card.php?id='.urlencode($this->id); + $url = DOL_URL_ROOT . '/accountancy/admin/card.php?id=' . urlencode($this->id); $labelurl = $langs->trans("ShowAccountingAccount"); } @@ -495,29 +435,29 @@ class AccountingAccount extends CommonObject $labeltoshow = $this->labelshort; } - $label = ''.$labelurl.''; + $label = '' . $labelurl . ''; if (!empty($this->account_number)) { - $label .= '
'.$langs->trans('AccountAccounting').': '.length_accountg($this->account_number); + $label .= '
' . $langs->trans('AccountAccounting') . ': ' . length_accountg($this->account_number); } if (!empty($labeltoshow)) { - $label .= '
'.$langs->trans('Label').': '.$labeltoshow; + $label .= '
' . $langs->trans('Label') . ': ' . $labeltoshow; } if ($moretitle) { - $label .= ' - '.$moretitle; + $label .= ' - ' . $moretitle; } $linkclose = ''; if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $labelurl; - $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"'; $linkclose .= ' class="classfortooltip"'; } - $linkstart = ''; + $linkstart = ''; $linkend = ''; if ($nourl) { @@ -528,17 +468,17 @@ class AccountingAccount extends CommonObject $label_link = length_accountg($this->account_number); if ($withlabel) { - $label_link .= ' - '.($nourl ? '' : '').$labeltoshow.($nourl ? '' : ''); + $label_link .= ' - ' . ($nourl ? '' : '') . $labeltoshow . ($nourl ? '' : ''); } if ($withpicto) { - $result .= ($linkstart.img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1).$linkend); + $result .= ($linkstart . img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1) . $linkend); } if ($withpicto && $withpicto != 2) { $result .= ' '; } if ($withpicto != 2) { - $result .= $linkstart.$label_link.$linkend; + $result .= $linkstart . $label_link . $linkend; } return $result; } @@ -552,10 +492,10 @@ class AccountingAccount extends CommonObject public function info($id) { $sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'accounting_account as a'; - $sql .= ' WHERE a.rowid = '.((int) $id); + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a'; + $sql .= ' WHERE a.rowid = ' . ((int) $id); - dol_syslog(get_class($this).'::info sql='.$sql); + dol_syslog(get_class($this) . '::info sql=' . $sql); $result = $this->db->query($sql); if ($result) { @@ -584,8 +524,8 @@ class AccountingAccount extends CommonObject /** * Deactivate an account (for status active or status reconcilable) * - * @param int $id Id - * @param int $mode 0=field active, 1=field reconcilable + * @param int $id Id + * @param int $mode 0=field active, 1=field reconcilable * @return int <0 if KO, >0 if OK */ public function accountDeactivate($id, $mode = 0) @@ -600,11 +540,11 @@ class AccountingAccount extends CommonObject if ($result > 0) { $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account "; - $sql .= "SET ".$fieldtouse." = '0'"; - $sql .= " WHERE rowid = ".$this->db->escape($id); + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql .= "SET " . $fieldtouse . " = '0'"; + $sql .= " WHERE rowid = " . $this->db->escape($id); - dol_syslog(get_class($this)."::accountDeactivate ".$fieldtouse." sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this) . "::accountDeactivate " . $fieldtouse . " sql=" . $sql, LOG_DEBUG); $result = $this->db->query($sql); if ($result) { @@ -620,15 +560,15 @@ class AccountingAccount extends CommonObject } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Account activated * - * @param int $id Id - * @param int $mode 0=field active, 1=field reconcilable + * @param int $id Id + * @param int $mode 0=field active, 1=field reconcilable * @return int <0 if KO, >0 if OK */ - public function account_activate($id, $mode = 0) + public function accountActivate($id, $mode = 0) { // phpcs:enable $this->db->begin(); @@ -638,11 +578,11 @@ class AccountingAccount extends CommonObject $fieldtouse = 'reconcilable'; } - $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account"; - $sql .= " SET ".$fieldtouse." = '1'"; - $sql .= " WHERE rowid = ".$this->db->escape($id); + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account"; + $sql .= " SET " . $fieldtouse . " = '1'"; + $sql .= " WHERE rowid = " . $this->db->escape($id); - dol_syslog(get_class($this)."::account_activate ".$fieldtouse." sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this) . "::accountActivate " . $fieldtouse . " sql=" . $sql, LOG_DEBUG); $result = $this->db->query($sql); if ($result) { $this->db->commit(); @@ -654,12 +594,11 @@ class AccountingAccount extends CommonObject } } - /** * Retourne le libelle du statut d'un user (actif, inactif) * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status */ public function getLibStatut($mode = 0) { @@ -670,9 +609,9 @@ class AccountingAccount extends CommonObject /** * Renvoi le libelle d'un statut donne * - * @param int $status Id status - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status + * @param int $status Id status + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status */ public function LibStatut($status, $mode = 0) { @@ -694,9 +633,9 @@ class AccountingAccount extends CommonObject } } elseif ($mode == 2) { if ($status == 1) { - return img_picto($langs->trans('Enabled'), 'statut4').' '.$langs->trans('Enabled'); + return img_picto($langs->trans('Enabled'), 'statut4') . ' ' . $langs->trans('Enabled'); } elseif ($status == 0) { - return img_picto($langs->trans('Disabled'), 'statut5').' '.$langs->trans('Disabled'); + return img_picto($langs->trans('Disabled'), 'statut5') . ' ' . $langs->trans('Disabled'); } } elseif ($mode == 3) { if ($status == 1) { @@ -706,16 +645,241 @@ class AccountingAccount extends CommonObject } } elseif ($mode == 4) { if ($status == 1) { - return img_picto($langs->trans('Enabled'), 'statut4').' '.$langs->trans('Enabled'); + return img_picto($langs->trans('Enabled'), 'statut4') . ' ' . $langs->trans('Enabled'); } elseif ($status == 0) { - return img_picto($langs->trans('Disabled'), 'statut5').' '.$langs->trans('Disabled'); + return img_picto($langs->trans('Disabled'), 'statut5') . ' ' . $langs->trans('Disabled'); } } elseif ($mode == 5) { if ($status == 1) { - return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'), 'statut4'); + return $langs->trans('Enabled') . ' ' . img_picto($langs->trans('Enabled'), 'statut4'); } elseif ($status == 0) { - return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'), 'statut5'); + return $langs->trans('Disabled') . ' ' . img_picto($langs->trans('Disabled'), 'statut5'); } } } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + + /** + * Return Suggest accounting accounts to bind + * + * @param Societe $thirdparty Societe Object seller or Buyers + * @param Product $product Product object sell or buy + * @param Facture $facture Facture + * @param FactureLigne $factureDet Facture Det + * @param array $accountingAccount array of Account account + * + * @return array Accounting accounts suggested + */ + public function getAccountingCodeToBind(Societe $thirdparty, Product $product, Facture $facture, FactureLigne $factureDet, $accountingAccount = array()) + { + global $mysoc, $conf; + global $hookmanager; + + // Instantiate hooks for external modules + $hookmanager->initHooks(array('accoutancyBindingCalculation')); + + // Execute hook accoutancyBindingCalculation + $parameters = array('thirdparty' => $thirdparty, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount); + $reshook = $hookmanager->executeHooks('accoutancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks + + if (empty($reshook)) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; + $isBuyerInEEC = isInEEC($thirdparty); + $isSellerInEEC = isInEEC($mysoc); + $code_sell_l = ''; + $code_sell_p = ''; + $code_sell_t = ''; + $suggestedid = ''; + + // Level 1: Search suggested default account for product/service + $suggestedaccountingaccountbydefaultfor = ''; + if ($factureDet->product_type == 1) { + if ($thirdparty->country_code == $mysoc->country_code || empty($thirdparty->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + $code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = ''; + } else { + if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT + $code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'eecwithvat'; + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($thirdparty->tva_intra)) { // European intravat sale, without VAT intra community number + $code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; + } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + $code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'eec'; + } else { // Foreign sale + $code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'export'; + } + } + } elseif ($factureDet->product_type == 0) { + if ($thirdparty->country_code == $mysoc->country_code || empty($thirdparty->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + $code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = ''; + } else { + if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT + $code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'eecwithvat'; + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($thirdparty->tva_intra)) { // European intravat sale, without VAT intra community number + $code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; + } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + $code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'eec'; + } else { + $code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'export'; + } + } + } + if ($code_sell_l == -1) { + $code_sell_l = ''; + } + + // Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) + $suggestedaccountingaccountfor = ''; + if (($thirdparty->country_code == $mysoc->country_code) || empty($thirdparty->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + $code_sell_p = $product->accountancy_code_sell; + $suggestedid = $accountingAccount['dom']; + $suggestedaccountingaccountfor = ''; + } else { + if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with VAT + $code_sell_p = $product->accountancy_code_sell; + $suggestedid = $accountingAccount['dom']; + $suggestedaccountingaccountfor = 'eecwithvat'; + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($thirdparty->tva_intra)) { // European intravat sale, without VAT intra community number + $code_sell_p = $product->accountancy_code_sell; + $suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ? + $suggestedaccountingaccountfor = 'eecwithoutvatnumber'; + } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + $code_sell_p = $product->accountancy_code_sell_intra; + $suggestedid = $accountingAccount['intra']; + $suggestedaccountingaccountfor = 'eec'; + } else { // Foreign sale + $code_sell_p = $product->accountancy_code_sell_export; + $suggestedid = $accountingAccount['export']; + $suggestedaccountingaccountfor = 'export'; + } + } + + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { + if (!empty($thirdparty->code_compta)) { + $code_sell_t = $thirdparty->code_compta; + $suggestedid = $accountingAccount['thirdparty']; + $suggestedaccountingaccountfor = ''; + } + } + + // Manage Deposit + if ($factureDet->desc == "(DEPOSIT)") { + $accountdeposittoventilated = new self($this->db); + $result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1); + if ($result < 0) { + return -1; + } + + $code_sell_l = $accountdeposittoventilated->ref; + $suggestedid = $accountdeposittoventilated->rowid; + } + + if (empty($suggestedid) && empty($code_sell_p) && !empty($code_sell_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) { + if (empty($this->accountingaccount_codetotid_cache[$code_sell_l])) { + $tmpaccount = new self($this->db); + $result = $tmpaccount->fetch(0, $code_sell_l, 1); + if ($result < 0) { + return -1; + } + if ($tmpaccount->id > 0) { + $suggestedid = $tmpaccount->id; + } + $this->accountingaccount_codetotid_cache[$code_sell_l] = $tmpaccount->id; + } else { + $suggestedid = $this->accountingaccount_codetotid_cache[$code_sell_l]; + } + } + } else { + if (is_array($hookmanager->resArray) && !empty($hookmanager->resArray)) { + return $hookmanager->resArray; + } + } + return array( + 'suggestedaccountingaccountbydefaultfor' => $suggestedaccountingaccountbydefaultfor, + 'suggestedaccountingaccountfor' => $suggestedaccountingaccountfor, + 'suggestedid' => $suggestedid, + 'code_sell_l' => $code_sell_l, + 'code_sell_p' => $code_sell_p, + 'code_sell_t' => $code_sell_t, + ); + } + + /** + * Load record in memory + * + * @param int $rowid Id + * @param string $account_number Account number + * @param int|boolean $limittocurrentchart 1 or true=Load record only if it is into current active char of account + * @param string $limittoachartaccount 'ABC'=Load record only if it is into chart account with code 'ABC' (better and faster than previous parameter if you have chart of account code). + * @return int <0 if KO, 0 if not found, Id of record if OK and found + */ + public function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0, $limittoachartaccount = '') + { + global $conf; + + if ($rowid || $account_number) { + $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.account_number, a.account_parent, a.label, a.labelshort, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active, a.reconcilable"; + $sql .= ", ca.label as category_label"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as a"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_accounting_category as ca ON a.fk_accounting_category = ca.rowid"; + $sql .= " WHERE"; + if ($rowid) { + $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) . ')'; + } + if (!empty($limittoachartaccount)) { + $sql .= " AND a.fk_pcg_version = '" . $this->db->escape($limittoachartaccount) . "'"; + } + + dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) { + $obj = $this->db->fetch_object($result); + + if ($obj) { + $this->id = $obj->rowid; + $this->rowid = $obj->rowid; + $this->ref = $obj->account_number; + $this->datec = $obj->datec; + $this->tms = $obj->tms; + $this->fk_pcg_version = $obj->fk_pcg_version; + $this->pcg_type = $obj->pcg_type; + $this->account_number = $obj->account_number; + $this->account_parent = $obj->account_parent; + $this->label = $obj->label; + $this->labelshort = $obj->labelshort; + $this->account_category = $obj->fk_accounting_category; + $this->account_category_label = $obj->category_label; + $this->fk_user_author = $obj->fk_user_author; + $this->fk_user_modif = $obj->fk_user_modif; + $this->active = $obj->active; + $this->status = $obj->active; + $this->reconcilable = $obj->reconcilable; + + return $this->id; + } else { + return 0; + } + } else { + $this->error = "Error " . $this->db->lasterror(); + $this->errors[] = "Error " . $this->db->lasterror(); + } + } + return -1; + } } diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 4df8d6b9b15..e165cc3d8b1 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -45,6 +45,7 @@ $massaction = GETPOST('massaction', 'alpha'); $show_files = GETPOST('show_files', 'int'); $confirm = GETPOST('confirm', 'alpha'); $toselect = GETPOST('toselect', 'array'); +$optioncss = GETPOST('optioncss', 'alpha'); // Select Box $mesCasesCochees = GETPOST('toselect', 'array'); @@ -96,6 +97,7 @@ if (!$sortorder) { $hookmanager->initHooks(array('accountancycustomerlist')); $formaccounting = new FormAccounting($db); +$accountingAccount = new AccountingAccount($db); $chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version'); @@ -510,17 +512,17 @@ if ($result) { $thirdpartystatic = new Societe($db); $facture_static = new Facture($db); + $facture_static_det = new FactureLigne($db); $product_static = new Product($db); - $isSellerInEEC = isInEEC($mysoc); $accountingaccount_codetotid_cache = array(); while ($i < min($num_lines, $limit)) { $objp = $db->fetch_object($result); - $objp->code_sell_l = ''; - $objp->code_sell_p = ''; + $code_sell_l = ''; + $code_sell_p = ''; $thirdpartystatic->id = $objp->socid; $thirdpartystatic->name = $objp->name; @@ -532,6 +534,8 @@ if ($result) { $thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur; $thirdpartystatic->email = $objp->email; $thirdpartystatic->country_code = $objp->country_code; + $thirdpartystatic->tva_intra = $objp->tva_intra; + $thirdpartystatic->code_compta = $objp->company_code_sell; $product_static->ref = $objp->product_ref; $product_static->id = $objp->product_id; @@ -545,158 +549,96 @@ if ($result) { $product_static->accountancy_code_buy = $objp->code_buy; $product_static->accountancy_code_buy_intra = $objp->code_buy_intra; $product_static->accountancy_code_buy_export = $objp->code_buy_export; + $product_static->tva_tx = $objp->tva_tx_prod; + $product_static->tva_tx = $objp->tva_tx_prod; $facture_static->ref = $objp->ref; $facture_static->id = $objp->facid; $facture_static->type = $objp->ftype; + $facture_static->datef = $objp->datef; + + $facture_static_det->id = $objp->rowid; + $facture_static_det->total_ht = $objp->total_ht; + $facture_static_det->tva_tx = $objp->tva_tx_line; + $facture_static_det->vat_src_code = $objp->vat_src_code; + $facture_static_det->product_type = $objp->type_l; + $facture_static_det->desc = $objp->description; + + $accoutinAccountArray = array( + 'dom'=>$objp->aarowid, + 'intra'=>$objp->aarowid_intra, + 'export'=>$objp->aarowid_export, + 'thirdparty' =>$objp->aarowid_thirdparty); $code_sell_p_notset = ''; $code_sell_t_notset = ''; - $objp->aarowid_suggest = ''; // Will be set later - $isBuyerInEEC = isInEEC($objp); - - // Level 1: Search suggested default account for product/service - $suggestedaccountingaccountbydefaultfor = ''; - if ($objp->type_l == 1) { - 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) - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = ''; - } else { - if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with a VAT - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; - } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = 'eec'; - } else { // Foreign sale - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = 'export'; - } - } - } elseif ($objp->type_l == 0) { - 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) - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = ''; - } else { - if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with a VAT - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; - } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = 'eec'; - } else { - $objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : ''); - $suggestedaccountingaccountbydefaultfor = 'export'; - } - } - } - if ($objp->code_sell_l == -1) { - $objp->code_sell_l = ''; - } - - // Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) - $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) - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = $objp->aarowid; - $suggestedaccountingaccountfor = ''; + $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $product_static, $facture_static, $facture_static_det, $accoutinAccountArray); + if (!is_array($return) && $return<0) { + setEventMessage($accountingAccount->error, 'errors'); } else { - if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with VAT - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = $objp->aarowid; - $suggestedaccountingaccountfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = $objp->aarowid; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ? - $suggestedaccountingaccountfor = 'eecwithoutvatnumber'; - } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale - $objp->code_sell_p = $objp->code_sell_intra; - $objp->aarowid_suggest = $objp->aarowid_intra; - $suggestedaccountingaccountfor = 'eec'; - } else { // Foreign sale - $objp->code_sell_p = $objp->code_sell_export; - $objp->aarowid_suggest = $objp->aarowid_export; - $suggestedaccountingaccountfor = 'export'; - } + $suggestedid=$return['suggestedid']; + $suggestedaccountingaccountfor=$return['suggestedaccountingaccountfor']; + $suggestedaccountingaccountbydefaultfor=$return['suggestedaccountingaccountbydefaultfor']; + $code_sell_l=$return['code_sell_l']; + $code_sell_p=$return['code_sell_p']; + $code_sell_t=$return['code_sell_t']; } - // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) - if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { - if (!empty($objp->company_code_sell)) { - $objp->code_sell_t = $objp->company_code_sell; - $objp->aarowid_suggest = $objp->aarowid_thirdparty; - $suggestedaccountingaccountfor = ''; - } - } - - // 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($objp->code_sell_p)) { + if (!empty($code_sell_p)) { // Value was defined previously } else { $code_sell_p_notset = 'color:orange'; } - if (empty($objp->code_sell_l) && empty($objp->code_sell_p)) { + if (empty($code_sell_l) && empty($code_sell_p)) { $code_sell_p_notset = 'color:red'; } if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber' && empty($code_sell_p_notset)) { $code_sell_p_notset = 'color:orange'; } - // $objp->code_sell_l is now default code of product/service - // $objp->code_sell_p is now code of product/service - // $objp->code_sell_t is now code of thirdparty + // $code_sell_l is now default code of product/service + // $code_sell_p is now code of product/service + // $code_sell_t is now code of thirdparty print ''; // Line id - print ''.$objp->rowid.''; + print ''.$facture_static_det->id.''; // Ref Invoice print ''.$facture_static->getNomUrl(1).''; - print ''.dol_print_date($db->jdate($objp->datef), 'day').''; + print ''.dol_print_date($db->jdate($facture_static->datef), 'day').''; // Ref Product print ''; if ($product_static->id > 0) { print $product_static->getNomUrl(1); } - if ($objp->product_label) { - print '
'.$objp->product_label.''; + if ($product_static->label) { + print '
'.$product_static->label.''; } print ''; // Description print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; - print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); + print $form->textwithtooltip(dol_trunc($text, $trunclength), $facture_static_det->desc); print ''; print ''; - print price($objp->total_ht); + print price($facture_static_det->total_ht); print ''; // Vat rate - if ($objp->vat_tx_l != $objp->vat_tx_p) { + $code_vat_differ=''; + if ($product_static->tva_tx !== $facture_static_det->tva_tx) { $code_vat_differ = 'font-weight:bold; text-decoration:blink; color:red'; } print ''; - print vatrate($objp->tva_tx_line.($objp->vat_src_code ? ' ('.$objp->vat_src_code.')' : '')); + print vatrate($facture_static_det->tva_tx.($facture_static_det->vat_src_code ? ' ('.$facture_static_det->vat_src_code.')' : '')); print ''; // Thirdparty @@ -704,27 +646,27 @@ if ($result) { // Country print ''; - $labelcountry = ($objp->country_code && ($langs->trans("Country".$objp->country_code) != "Country".$objp->country_code)) ? $langs->trans("Country".$objp->country_code) : $objp->country_label; + $labelcountry = ($thirdpartystatic->country_code && ($langs->trans("Country".$thirdpartystatic->country_code) != "Country".$thirdpartystatic->country_code)) ? $langs->trans("Country".$thirdpartystatic->country_code) : $objp->country_label; print $labelcountry; print ''; // VAT Num - print ''.$objp->tva_intra.''; + print ''.$thirdpartystatic->tva_intra.''; // Found accounts print ''; - $s = '1. '.(($objp->type_l == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': '; + $s = '1. '.(($facture_static_det->product_type == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': '; $shelp = ''; if ($suggestedaccountingaccountbydefaultfor == 'eec') { $shelp .= $langs->trans("SaleEEC"); } elseif ($suggestedaccountingaccountbydefaultfor == 'export') { $shelp .= $langs->trans("SaleExport"); } - $s .= ($objp->code_sell_l > 0 ? length_accountg($objp->code_sell_l) : ''.$langs->trans("NotDefined").''); + $s .= ($code_sell_l > 0 ? length_accountg($code_sell_l) : ''.$langs->trans("NotDefined").''); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); - if ($objp->product_id > 0) { + if ($product_static->id > 0) { print '
'; - $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; + $s = '2. '.(($facture_static_det->product_type == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; $shelp = ''; $ttype = 'help'; if ($suggestedaccountingaccountfor == 'eec') { $shelp = $langs->trans("SaleEEC"); @@ -736,12 +678,12 @@ if ($result) { } elseif ($suggestedaccountingaccountfor == 'export') { $shelp = $langs->trans("SaleExport"); } - $s .= (empty($objp->code_sell_p) ? ''.$langs->trans("NotDefined").'' : length_accountg($objp->code_sell_p)); + $s .= (empty($code_sell_p) ? ''.$langs->trans("NotDefined").'' : length_accountg($code_sell_p)); print $form->textwithpicto($s, $shelp, 1, $ttype, '', 0, 2, '', 1); } else { if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { print '
'; - $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; + $s = '2. '.(($facture_static_det->product_type == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; $shelp = ''; $s .= $langs->trans("NotDefined"); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); @@ -749,29 +691,16 @@ if ($result) { } if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { print '
'; - $s = '3. '.(($objp->type_l == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': '; + $s = '3. '.(($facture_static_det->product_type == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': '; $shelp = ''; - $s .= ($objp->code_sell_t > 0 ? length_accountg($objp->code_sell_t) : ''.$langs->trans("NotDefined").''); + $s .= ($code_sell_t > 0 ? length_accountg($code_sell_t) : ''.$langs->trans("NotDefined").''); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); } print ''; // Suggested accounting account print ''; - $suggestedid = $objp->aarowid_suggest; - if (empty($suggestedid) && empty($objp->code_sell_p) && !empty($objp->code_sell_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) { - if (empty($accountingaccount_codetotid_cache[$objp->code_sell_l])) { - $tmpaccount = new AccountingAccount($db); - $tmpaccount->fetch(0, $objp->code_sell_l, 1); - if ($tmpaccount->id > 0) { - $suggestedid = $tmpaccount->id; - } - $accountingaccount_codetotid_cache[$objp->code_sell_l] = $tmpaccount->id; - } else { - $suggestedid = $accountingaccount_codetotid_cache[$objp->code_sell_l]; - } - } - print $formaccounting->select_account($suggestedid, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'); + print $formaccounting->select_account($suggestedid, 'codeventil'.$facture_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'); print ''; // Column with checkbox @@ -780,7 +709,7 @@ if ($result) { if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') { $ischecked = 0; } - print ''; + print ''; print ''; print ''; From 729ca70bf396d05b3cf75abe5a28b2fafcf92df7 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 4 Jun 2021 12:20:52 +0200 Subject: [PATCH 02/28] NEW : rewrite bind accountancy code finding on sales invoice --- .../class/accountingaccount.class.php | 15 +-- htdocs/accountancy/customer/index.php | 101 ++++++++++++------ htdocs/accountancy/customer/list.php | 6 +- htdocs/societe/card.php | 12 ++- 4 files changed, 90 insertions(+), 44 deletions(-) diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index c4a11fb6565..9f5c7799037 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -739,24 +739,24 @@ class AccountingAccount extends CommonObject // Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) $suggestedaccountingaccountfor = ''; - if (($thirdparty->country_code == $mysoc->country_code) || empty($thirdparty->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + if ((($thirdparty->country_code == $mysoc->country_code) || empty($thirdparty->country_code)) && !empty($product->accountancy_code_sell)) { // If buyer in same country than seller (if not defined, we assume it is same country) $code_sell_p = $product->accountancy_code_sell; $suggestedid = $accountingAccount['dom']; - $suggestedaccountingaccountfor = ''; + $suggestedaccountingaccountfor = 'prodserv'; } else { - if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with VAT + if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0 && !empty($product->accountancy_code_sell)) { // European intravat sale, but with VAT $code_sell_p = $product->accountancy_code_sell; $suggestedid = $accountingAccount['dom']; $suggestedaccountingaccountfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($thirdparty->tva_intra)) { // European intravat sale, without VAT intra community number + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($thirdparty->tva_intra) && !empty($product->accountancy_code_sell)) { // European intravat sale, without VAT intra community number $code_sell_p = $product->accountancy_code_sell; $suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ? $suggestedaccountingaccountfor = 'eecwithoutvatnumber'; - } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + } elseif ($isSellerInEEC && $isBuyerInEEC && !empty($product->accountancy_code_sell_intra)) { // European intravat sale $code_sell_p = $product->accountancy_code_sell_intra; $suggestedid = $accountingAccount['intra']; $suggestedaccountingaccountfor = 'eec'; - } else { // Foreign sale + } elseif (!empty($product->accountancy_code_sell_export)) { // Foreign sale $code_sell_p = $product->accountancy_code_sell_export; $suggestedid = $accountingAccount['export']; $suggestedaccountingaccountfor = 'export'; @@ -768,7 +768,7 @@ class AccountingAccount extends CommonObject if (!empty($thirdparty->code_compta)) { $code_sell_t = $thirdparty->code_compta; $suggestedid = $accountingAccount['thirdparty']; - $suggestedaccountingaccountfor = ''; + $suggestedaccountingaccountfor = 'thridparty'; } } @@ -782,6 +782,7 @@ class AccountingAccount extends CommonObject $code_sell_l = $accountdeposittoventilated->ref; $suggestedid = $accountdeposittoventilated->rowid; + $suggestedaccountingaccountfor = 'deposit'; } if (empty($suggestedid) && empty($code_sell_p) && !empty($code_sell_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) { diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index d33f5e12312..2bb2903eefa 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; // Load translation files required by the page $langs->loadLangs(array("compta", "bills", "other", "main", "accountancy")); @@ -46,6 +47,7 @@ if (!$user->rights->accounting->bind->write) { accessforbidden(); } +$accountingAccount = new AccountingAccount($db); $month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); if (GETPOST("year", 'int')) { @@ -166,49 +168,82 @@ if ($action == 'validatehistory') { $isSellerInEEC = isInEEC($mysoc); + $thirdpartystatic = new Societe($db); + $facture_static = new Facture($db); + $facture_static_det = new FactureLigne($db); + $product_static = new Product($db); + $i = 0; while ($i < min($num_lines, 10000)) { // No more than 10000 at once $objp = $db->fetch_object($result); - $isBuyerInEEC = isInEEC($objp); // This make a database request but there is a cache into $conf->cache['country_code_in_EEC'] + $thirdpartystatic->id = $objp->socid; + $thirdpartystatic->name = $objp->name; + $thirdpartystatic->client = $objp->client; + $thirdpartystatic->fournisseur = $objp->fournisseur; + $thirdpartystatic->code_client = $objp->code_client; + $thirdpartystatic->code_compta_client = $objp->code_compta_client; + $thirdpartystatic->code_fournisseur = $objp->code_fournisseur; + $thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur; + $thirdpartystatic->email = $objp->email; + $thirdpartystatic->country_code = $objp->country_code; + $thirdpartystatic->tva_intra = $objp->tva_intra; + $thirdpartystatic->code_compta = $objp->company_code_sell; - // Level 2: Search suggested account for product/service (similar code exists in page list.php to make manual binding) - $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) - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = $objp->aarowid; - $suggestedaccountingaccountfor = ''; + $product_static->ref = $objp->product_ref; + $product_static->id = $objp->product_id; + $product_static->type = $objp->type; + $product_static->label = $objp->product_label; + $product_static->status = $objp->status; + $product_static->status_buy = $objp->status_buy; + $product_static->accountancy_code_sell = $objp->code_sell; + $product_static->accountancy_code_sell_intra = $objp->code_sell_intra; + $product_static->accountancy_code_sell_export = $objp->code_sell_export; + $product_static->accountancy_code_buy = $objp->code_buy; + $product_static->accountancy_code_buy_intra = $objp->code_buy_intra; + $product_static->accountancy_code_buy_export = $objp->code_buy_export; + $product_static->tva_tx = $objp->tva_tx_prod; + $product_static->tva_tx = $objp->tva_tx_prod; + + $facture_static->ref = $objp->ref; + $facture_static->id = $objp->facid; + $facture_static->type = $objp->ftype; + $facture_static->datef = $objp->datef; + + $facture_static_det->id = $objp->rowid; + $facture_static_det->total_ht = $objp->total_ht; + $facture_static_det->tva_tx = $objp->tva_tx_line; + $facture_static_det->vat_src_code = $objp->vat_src_code; + $facture_static_det->product_type = $objp->type_l; + $facture_static_det->desc = $objp->description; + + $accoutinAccountArray = array( + 'dom'=>$objp->aarowid, + 'intra'=>$objp->aarowid_intra, + 'export'=>$objp->aarowid_export, + 'thirdparty' =>$objp->aarowid_thirdparty); + + $code_sell_p_notset = ''; + $code_sell_t_notset = ''; + + $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $product_static, $facture_static, $facture_static_det, $accoutinAccountArray); + if (!is_array($return) && $return<0) { + setEventMessage($accountingAccount->error, 'errors'); } else { - if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with VAT - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = $objp->aarowid; - $suggestedaccountingaccountfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = 0; // There is a doubt, no automatic binding - $suggestedaccountingaccountfor = 'eecwithoutvatnumber'; - } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale - $objp->code_sell_p = $objp->code_sell_intra; - $objp->aarowid_suggest = $objp->aarowid_intra; - $suggestedaccountingaccountfor = 'eec'; - } else { // Foreign sale - $objp->code_sell_p = $objp->code_sell_export; - $objp->aarowid_suggest = $objp->aarowid_export; - $suggestedaccountingaccountfor = 'export'; + $suggestedid=$return['suggestedid']; + $suggestedaccountingaccountfor=$return['suggestedaccountingaccountfor']; + + if (!empty($suggestedid) && $suggestedaccountingaccountfor<>'') { + $suggestedid=$return['suggestedid']; + } else { + $suggestedid=0; } } - // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) - if (!empty($objp->company_code_sell)) { - $objp->code_sell_t = $objp->company_code_sell; - $objp->aarowid_suggest = $objp->aarowid_thirdparty; - $suggestedaccountingaccountfor = ''; - } - - if ($objp->aarowid_suggest > 0) { + if ($suggestedid > 0) { $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."facturedet"; - $sqlupdate .= " SET fk_code_ventilation = ".((int) $objp->aarowid_suggest); - $sqlupdate .= " WHERE fk_code_ventilation <= 0 AND product_type <= 2 AND rowid = ".((int) $objp->rowid); + $sqlupdate .= " SET fk_code_ventilation = ".((int) $suggestedid); + $sqlupdate .= " WHERE fk_code_ventilation <= 0 AND product_type <= 2 AND rowid = ".((int) $facture_static_det->id); $resqlupdate = $db->query($sqlupdate); if (!$resqlupdate) { diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index e165cc3d8b1..c58df26edc2 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -584,6 +584,7 @@ if ($result) { $code_sell_p=$return['code_sell_p']; $code_sell_t=$return['code_sell_t']; } + //var_dump($return); if (!empty($code_sell_p)) { // Value was defined previously @@ -705,8 +706,9 @@ if ($result) { // Column with checkbox print ''; - $ischecked = $objp->aarowid_suggest; - if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') { + if (!empty($suggestedid) && $suggestedaccountingaccountfor<>'') { + $ischecked=1; + } elseif ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') { $ischecked = 0; } print ''; diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index aa8205bfa99..1c7871d4b1c 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -490,10 +490,18 @@ if (empty($reshook)) { $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); if (GETPOSTISSET('accountancy_code_sell')) { - $object->accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + if (GETPOST('accountancy_code_sell', 'int')==-1) { + $object->accountancy_code_sell = 0; + } else { + $object->accountancy_code_sell = GETPOST('accountancy_code_sell', 'int'); + } } if (GETPOSTISSET('accountancy_code_buy')) { - $object->accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + if (GETPOST('accountancy_code_buy', 'int')==-1) { + $object->accountancy_code_buy = 0; + } else { + $object->accountancy_code_buy = GETPOST('accountancy_code_buy', 'int'); + } } // Incoterms From ac6e108be6e5643dfd993a7be283b64e2f97b872 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 4 Jun 2021 12:27:49 +0200 Subject: [PATCH 03/28] fix syntax --- .../class/accountingaccount.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 9f5c7799037..1827549020f 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -800,19 +800,19 @@ class AccountingAccount extends CommonObject $suggestedid = $this->accountingaccount_codetotid_cache[$code_sell_l]; } } + return array( + 'suggestedaccountingaccountbydefaultfor' => $suggestedaccountingaccountbydefaultfor, + 'suggestedaccountingaccountfor' => $suggestedaccountingaccountfor, + 'suggestedid' => $suggestedid, + 'code_sell_l' => $code_sell_l, + 'code_sell_p' => $code_sell_p, + 'code_sell_t' => $code_sell_t, + ); } else { if (is_array($hookmanager->resArray) && !empty($hookmanager->resArray)) { return $hookmanager->resArray; } } - return array( - 'suggestedaccountingaccountbydefaultfor' => $suggestedaccountingaccountbydefaultfor, - 'suggestedaccountingaccountfor' => $suggestedaccountingaccountfor, - 'suggestedid' => $suggestedid, - 'code_sell_l' => $code_sell_l, - 'code_sell_p' => $code_sell_p, - 'code_sell_t' => $code_sell_t, - ); } /** From 709a2975637759716e745943645d408e7b3f93c7 Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Mon, 30 Aug 2021 14:45:42 +0200 Subject: [PATCH 04/28] NEW : Allow drag and drop on kits --- htdocs/core/ajax/row.php | 2 + htdocs/core/class/commonobject.class.php | 11 +++-- htdocs/langs/en_US/products.lang | 3 +- htdocs/langs/fr_FR/products.lang | 1 + htdocs/product/class/product.class.php | 59 +++++++++++++++++------- htdocs/product/composition/card.php | 28 +++++++++-- 6 files changed, 79 insertions(+), 25 deletions(-) diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php index 95518cbbf66..1afd5f8b206 100644 --- a/htdocs/core/ajax/row.php +++ b/htdocs/core/ajax/row.php @@ -99,6 +99,8 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) $perm = 1; } elseif ($table_element_line == 'ecm_files' && $fk_element == 'fk_ticket' && !empty($user->rights->ticket->write)) { $perm = 1; + } elseif ($table_element_line == 'product_association' && $fk_element == 'fk_product' && !empty($user->rights->produit->creer)) { + $perm = 1; } else { $tmparray = explode('_', $table_element_line); $tmpmodule = $tmparray[0]; $tmpobject = preg_replace('/line$/', '', $tmparray[1]); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 5cdb83194f4..22aa26ceb62 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3021,7 +3021,7 @@ abstract class CommonObject * * @param int $rowid Id of line * @param int $rang Position - * @return void + * @return int */ public function updateRangOfLine($rowid, $rang) { @@ -3037,10 +3037,13 @@ abstract class CommonObject dol_syslog(get_class($this)."::updateRangOfLine", LOG_DEBUG); if (!$this->db->query($sql)) { dol_print_error($this->db); + return -1; + } else { + $parameters=array('rowid'=>$rowid, 'rang'=>$rang, 'fieldposition' => $fieldposition); + $action=''; + $reshook = $hookmanager->executeHooks('afterRankOfLineUpdate', $parameters, $this, $action); + return 1; } - $parameters=array('rowid'=>$rowid, 'rang'=>$rang, 'fieldposition' => $fieldposition); - $action=''; - $reshook = $hookmanager->executeHooks('afterRankOfLineUpdate', $parameters, $this, $action); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index ae199f4136b..31aa253af93 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -400,4 +400,5 @@ DeleteLinkedProduct=Delete the child product linked to the combination PMPValue=Weighted average price PMPValueShort=WAP DefaultBOM=Default BOM -DefaultBOMDesc=The default BOM recommended to use to manufacture this product. This field can be set only if nature of product is '%s'. \ No newline at end of file +DefaultBOMDesc=The default BOM recommended to use to manufacture this product. This field can be set only if nature of product is '%s'. +Rank=Rank diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 013d75d2ec0..f67cfd8423d 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -399,3 +399,4 @@ ProductSupplierExtraFields=Attributs supplémentaires (Prix fournisseur) DeleteLinkedProduct=Supprimer le produit enfant lié à la combinaison PMPValue=Prix moyen pondéré (PMP) PMPValueShort=PMP +Rank=Rang diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e51c553809d..5681cf2571a 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4014,22 +4014,27 @@ class Product extends CommonObject dol_print_error($this->db); return -1; } else { - $result = $this->db->query($sql); - if ($result) { - $num = $this->db->num_rows($result); - if ($num > 0) { - $this->error = "isFatherOfThis"; + //Selection of the highest row + $sql = 'SELECT MAX(rang) as max_rank FROM '.MAIN_DB_PREFIX.'product_association'; + $sql .= ' WHERE fk_product_pere = '.$id_pere; + $resql = $this->db->query($sql); + if ($resql > 0) { + $obj = $this->db->fetch_object($resql); + $rank = $obj->max_rank + 1; + //Addition of a product with the highest rank +1 + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty,incdec,rang)'; + $sql .= ' VALUES ('.$id_pere.', '.$id_fils.', '.$qty.', '.$incdec.', '.$rank.')'; + if (! $this->db->query($sql)) { + dol_print_error($this->db); return -1; - } else { - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty,incdec)'; - $sql .= ' VALUES ('.((int) $id_pere).', '.((int) $id_fils).', '.((float) $qty).', '.((int) $incdec).')'; - if (!$this->db->query($sql)) { - dol_print_error($this->db); - return -1; - } else { - return 1; - } } + else + { + return 1; + } + } else { + dol_print_error($this->db); + return -1; } } } @@ -4102,6 +4107,24 @@ class Product extends CommonObject return -1; } + //Updated ranks so that none are missing + $sqlrank = 'SELECT rowid, rang FROM '.MAIN_DB_PREFIX.'product_association'; + $sqlrank.= ' WHERE fk_product_pere = '.$fk_parent; + $sqlrank.= ' ORDER BY rang'; + $resqlrank = $this->db->query($sqlrank); + if ($resqlrank) { + $cpt = 0; + while ($objrank = $this->db->fetch_object($resqlrank)){ + $cpt++; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'product_association'; + $sql.= ' SET rang ='.$cpt; + $sql.= ' WHERE rowid ='.$objrank->rowid; + if (! $this->db->query($sql)) { + dol_print_error($this->db); + return -1; + } + } + } return 1; } @@ -4666,12 +4689,14 @@ class Product extends CommonObject } $sql = "SELECT p.rowid, p.ref, p.label as label, p.fk_product_type,"; - $sql .= " pa.qty as qty, pa.fk_product_fils as id, pa.incdec"; + $sql .= " pa.qty as qty, pa.fk_product_fils as id, pa.incdec,"; + $sql .= " pa.rowid as fk_association, pa.rang"; $sql .= " FROM ".MAIN_DB_PREFIX."product as p,"; $sql .= " ".MAIN_DB_PREFIX."product_association as pa"; $sql .= " WHERE p.rowid = pa.fk_product_fils"; $sql .= " AND pa.fk_product_pere = ".((int) $id); $sql .= " AND pa.fk_product_fils <> ".((int) $id); // This should not happens, it is to avoid infinite loop if it happens + $sql.= " ORDER BY pa.rang"; dol_syslog(get_class($this).'::getChildsArbo id='.$id.' level='.$level, LOG_DEBUG); @@ -4698,7 +4723,9 @@ class Product extends CommonObject 2=>$rec['fk_product_type'], 3=>$this->db->escape($rec['label']), 4=>$rec['incdec'], - 5=>$rec['ref'] + 5=>$rec['ref'], + 6=>$rec['fk_association'], + 7=>$rec['rang'] ); //$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty'],2=>$rec['fk_product_type']); //$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']); diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index 000e5da6cbc..d1e59482d44 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -132,6 +132,8 @@ if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->se setEventMessages('RecordSaved', null); } $action = ''; + header("Location: ".$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; } @@ -268,8 +270,18 @@ if ($id > 0 || !empty($ref)) { $prodsfather = $object->getFather(); // Parent Products $object->get_sousproduits_arbo(); // Load $object->sousprods + $parent_label = $object->label; $prods_arbo = $object->get_arbo_each_prod(); + $tmpid = $id; + if (! empty($conf->use_javascript_ajax)) { + $nboflines = $prods_arbo; + $table_element_line='product_association'; + + include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; + } + $id = $tmpid; + $nbofsubsubproducts = count($prods_arbo); // This include sub sub product into nb $prodschild = $object->getChildsArbo($id, 1); $nbofsubproducts = count($prodschild); // This include only first level of childs @@ -323,9 +335,10 @@ if ($id > 0 || !empty($ref)) { print ''; print ''; - print ''; + print '
'; - print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -335,6 +348,7 @@ if ($id > 0 || !empty($ref)) { } print ''; print ''; + print ''; print ''."\n"; $totalsell = 0; @@ -343,7 +357,9 @@ if ($id > 0 || !empty($ref)) { $productstatic->fetch($value['id']); if ($value['level'] <= 1) { - print ''; + print ''; + + print ''; $notdefined = 0; $nb_of_subproduct = $value['nb']; @@ -407,6 +423,8 @@ if ($id > 0 || !empty($ref)) { print ''; } + print ''; print ''."\n"; } else { $hide = ''; @@ -414,10 +432,11 @@ if ($id > 0 || !empty($ref)) { $hide = ' hideobject'; // By default, we do not show this. It makes screen very difficult to understand } - print ''; + print ''; //$productstatic->ref=$value['label']; $productstatic->ref = $value['ref']; + print ''; print ''; print ''; + print ''; print ''."\n"; } From 73b4f0df51ee6ca9b030c8436e411e0efe41587f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 30 Aug 2021 13:38:55 +0000 Subject: [PATCH 05/28] Fixing style errors. --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 5681cf2571a..27582a533bd 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4114,7 +4114,7 @@ class Product extends CommonObject $resqlrank = $this->db->query($sqlrank); if ($resqlrank) { $cpt = 0; - while ($objrank = $this->db->fetch_object($resqlrank)){ + while ($objrank = $this->db->fetch_object($resqlrank)) { $cpt++; $sql = 'UPDATE '.MAIN_DB_PREFIX.'product_association'; $sql.= ' SET rang ='.$cpt; From 317876eb0c3b6d0ed11f78c50be12dccecabf9ae Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Mon, 30 Aug 2021 15:48:22 +0200 Subject: [PATCH 06/28] NEW : Update SQL : install and migration --- htdocs/install/mysql/migration/14.0.0-15.0.0.sql | 1 + htdocs/install/mysql/tables/llx_product_association.sql | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 1d9dd28f9d7..349b7e3a617 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -57,6 +57,7 @@ ALTER TABLE llx_categorie_ticket ADD CONSTRAINT fk_categorie_ticket_categorie_ro ALTER TABLE llx_categorie_ticket ADD CONSTRAINT fk_categorie_ticket_ticket_rowid FOREIGN KEY (fk_ticket) REFERENCES llx_ticket (rowid); ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN ref_fourn varchar(128); ALTER TABLE llx_product_customer_price MODIFY COLUMN ref_customer varchar(128); +ALTER TABLE llx_product_association ADD COLUMN rang int; -- -- add action trigger INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('ORDER_SUPPLIER_CANCEL','Supplier order request canceled','Executed when a supplier order is canceled','order_supplier',13); diff --git a/htdocs/install/mysql/tables/llx_product_association.sql b/htdocs/install/mysql/tables/llx_product_association.sql index 91cc14882f1..5447446695f 100644 --- a/htdocs/install/mysql/tables/llx_product_association.sql +++ b/htdocs/install/mysql/tables/llx_product_association.sql @@ -23,6 +23,7 @@ create table llx_product_association fk_product_pere integer NOT NULL DEFAULT 0, -- id du produit maitre fk_product_fils integer NOT NULL DEFAULT 0, -- id du sous-produit qty double NULL, - incdec integer DEFAULT 1 -- when set to 1 changing stock of product will change stock of linked product too + incdec integer DEFAULT 1, -- when set to 1 changing stock of product will change stock of linked product too + range integer, )ENGINE=innodb; From 7794a01a0b3fe65e46518276675b3d56e2b6df32 Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Mon, 30 Aug 2021 15:51:59 +0200 Subject: [PATCH 07/28] FIX : Stickler-ci --- htdocs/product/class/product.class.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 27582a533bd..c41228bbd4a 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4027,9 +4027,7 @@ class Product extends CommonObject if (! $this->db->query($sql)) { dol_print_error($this->db); return -1; - } - else - { + } else { return 1; } } else { From 08364d249247682d2c270d0dd99184e3ff315a0e Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Mon, 30 Aug 2021 16:08:07 +0200 Subject: [PATCH 08/28] FIX : Travis --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index c41228bbd4a..82bf28cb7ca 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4023,7 +4023,7 @@ class Product extends CommonObject $rank = $obj->max_rank + 1; //Addition of a product with the highest rank +1 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty,incdec,rang)'; - $sql .= ' VALUES ('.$id_pere.', '.$id_fils.', '.$qty.', '.$incdec.', '.$rank.')'; + $sql .= ' VALUES ('.$id_pere.', '.$id_fils.', '.$this->db->escape($qty).', '.$incdec.', '.$rank.')'; if (! $this->db->query($sql)) { dol_print_error($this->db); return -1; From fb183f4f5d45e928ac898fa5e758f834f6fe5b34 Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Mon, 30 Aug 2021 16:13:51 +0200 Subject: [PATCH 09/28] FIX : Travis --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 82bf28cb7ca..4d8990a12f1 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4023,7 +4023,7 @@ class Product extends CommonObject $rank = $obj->max_rank + 1; //Addition of a product with the highest rank +1 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty,incdec,rang)'; - $sql .= ' VALUES ('.$id_pere.', '.$id_fils.', '.$this->db->escape($qty).', '.$incdec.', '.$rank.')'; + $sql .= ' VALUES ('.$id_pere.', '.$id_fils.', '.$qty.', '.$incdec.', '.$this->db->escape($rank).')'; if (! $this->db->query($sql)) { dol_print_error($this->db); return -1; From f44ae62eb34b2fe794f901013eb20f95311f369d Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Mon, 30 Aug 2021 16:59:09 +0200 Subject: [PATCH 10/28] FIX : Travis --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 4d8990a12f1..bc348925244 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4107,7 +4107,7 @@ class Product extends CommonObject //Updated ranks so that none are missing $sqlrank = 'SELECT rowid, rang FROM '.MAIN_DB_PREFIX.'product_association'; - $sqlrank.= ' WHERE fk_product_pere = '.$fk_parent; + $sqlrank.= ' WHERE fk_product_pere = '.$this->db->escape($fk_parent); $sqlrank.= ' ORDER BY rang'; $resqlrank = $this->db->query($sqlrank); if ($resqlrank) { From 58845082b1a861e2d643350801ee8e14eb7cd5a0 Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Mon, 30 Aug 2021 17:20:50 +0200 Subject: [PATCH 11/28] FIX : Travis --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index bc348925244..508059e9e34 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4116,7 +4116,7 @@ class Product extends CommonObject $cpt++; $sql = 'UPDATE '.MAIN_DB_PREFIX.'product_association'; $sql.= ' SET rang ='.$cpt; - $sql.= ' WHERE rowid ='.$objrank->rowid; + $sql.= ' WHERE rowid ='.$this->db->escape($objrank->rowid); if (! $this->db->query($sql)) { dol_print_error($this->db); return -1; From ef2bb99476090a7600d19fc2ef71c10b4d46af35 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Sep 2021 16:29:08 +0200 Subject: [PATCH 12/28] Update commonobject.class.php --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 22aa26ceb62..70effea53b3 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3021,7 +3021,7 @@ abstract class CommonObject * * @param int $rowid Id of line * @param int $rang Position - * @return int + * @return int <0 if KO, >0 if OK */ public function updateRangOfLine($rowid, $rang) { From 3b236f677d68031c6e2e3597d512bc9b3d45fa30 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Sep 2021 16:31:16 +0200 Subject: [PATCH 13/28] Update llx_product_association.sql --- htdocs/install/mysql/tables/llx_product_association.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_product_association.sql b/htdocs/install/mysql/tables/llx_product_association.sql index 5447446695f..f97e2aa6a0b 100644 --- a/htdocs/install/mysql/tables/llx_product_association.sql +++ b/htdocs/install/mysql/tables/llx_product_association.sql @@ -24,6 +24,6 @@ create table llx_product_association fk_product_fils integer NOT NULL DEFAULT 0, -- id du sous-produit qty double NULL, incdec integer DEFAULT 1, -- when set to 1 changing stock of product will change stock of linked product too - range integer, + rang integer DEFAULT 0 )ENGINE=innodb; From 4b7b54e196f8d07246d4d73bb199129182a6dbcd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Sep 2021 16:32:25 +0200 Subject: [PATCH 14/28] Update 14.0.0-15.0.0.sql --- htdocs/install/mysql/migration/14.0.0-15.0.0.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 349b7e3a617..cd6cbeae3e6 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -57,7 +57,7 @@ ALTER TABLE llx_categorie_ticket ADD CONSTRAINT fk_categorie_ticket_categorie_ro ALTER TABLE llx_categorie_ticket ADD CONSTRAINT fk_categorie_ticket_ticket_rowid FOREIGN KEY (fk_ticket) REFERENCES llx_ticket (rowid); ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN ref_fourn varchar(128); ALTER TABLE llx_product_customer_price MODIFY COLUMN ref_customer varchar(128); -ALTER TABLE llx_product_association ADD COLUMN rang int; +ALTER TABLE llx_product_association ADD COLUMN rang integer DEFAULT 0; -- -- add action trigger INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('ORDER_SUPPLIER_CANCEL','Supplier order request canceled','Executed when a supplier order is canceled','order_supplier',13); From e7eb17177db432f54856897f2d1e7d97b8ebc0ea Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 10 Sep 2021 15:52:54 +0200 Subject: [PATCH 15/28] merge --- .../class/accountingaccount.class.php | 101 ------------------ 1 file changed, 101 deletions(-) diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index ff9dcf14cdb..7ec07d1f15b 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -449,38 +449,6 @@ class AccountingAccount extends CommonObject } } - /** - * Check usage of accounting code - * - * @return int <0 if KO, >0 if OK - */ - public function checkUsage() - { - global $langs; - - $sql = "(SELECT fk_code_ventilation FROM " . MAIN_DB_PREFIX . "facturedet"; - $sql .= " WHERE fk_code_ventilation=" . $this->id . ")"; - $sql .= "UNION"; - $sql .= " (SELECT fk_code_ventilation FROM " . MAIN_DB_PREFIX . "facture_fourn_det"; - $sql .= " WHERE fk_code_ventilation=" . $this->id . ")"; - - dol_syslog(get_class($this) . "::checkUsage sql=" . $sql, LOG_DEBUG); - $resql = $this->db->query($sql); - - if ($resql) { - $num = $this->db->num_rows($resql); - if ($num > 0) { - $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse'); - return 0; - } else { - return 1; - } - } else { - $this->error = $this->db->lasterror(); - return -1; - } - } - /** * Return clicable name (with picto eventually) * @@ -915,73 +883,4 @@ class AccountingAccount extends CommonObject } } } - - /** - * Load record in memory - * - * @param int $rowid Id - * @param string $account_number Account number - * @param int|boolean $limittocurrentchart 1 or true=Load record only if it is into current active char of account - * @param string $limittoachartaccount 'ABC'=Load record only if it is into chart account with code 'ABC' (better and faster than previous parameter if you have chart of account code). - * @return int <0 if KO, 0 if not found, Id of record if OK and found - */ - public function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0, $limittoachartaccount = '') - { - global $conf; - - if ($rowid || $account_number) { - $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.account_number, a.account_parent, a.label, a.labelshort, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active, a.reconcilable"; - $sql .= ", ca.label as category_label"; - $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as a"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_accounting_category as ca ON a.fk_accounting_category = ca.rowid"; - $sql .= " WHERE"; - if ($rowid) { - $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) . ')'; - } - if (!empty($limittoachartaccount)) { - $sql .= " AND a.fk_pcg_version = '" . $this->db->escape($limittoachartaccount) . "'"; - } - - dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $obj = $this->db->fetch_object($result); - - if ($obj) { - $this->id = $obj->rowid; - $this->rowid = $obj->rowid; - $this->ref = $obj->account_number; - $this->datec = $obj->datec; - $this->tms = $obj->tms; - $this->fk_pcg_version = $obj->fk_pcg_version; - $this->pcg_type = $obj->pcg_type; - $this->account_number = $obj->account_number; - $this->account_parent = $obj->account_parent; - $this->label = $obj->label; - $this->labelshort = $obj->labelshort; - $this->account_category = $obj->fk_accounting_category; - $this->account_category_label = $obj->category_label; - $this->fk_user_author = $obj->fk_user_author; - $this->fk_user_modif = $obj->fk_user_modif; - $this->active = $obj->active; - $this->status = $obj->active; - $this->reconcilable = $obj->reconcilable; - - return $this->id; - } else { - return 0; - } - } else { - $this->error = "Error " . $this->db->lasterror(); - $this->errors[] = "Error " . $this->db->lasterror(); - } - } - return -1; - } } From 77d64e4fe2d2eea9be6f5a305c28bd4251d4be87 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Sat, 25 Sep 2021 12:13:06 +0200 Subject: [PATCH 16/28] NEW API list of staff units --- htdocs/api/class/api_setup.class.php | 59 ++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index f5f301e9c16..faccf512ed8 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -1278,6 +1278,65 @@ class Setup extends DolibarrApi return $list; } + + /** + * Get the list of staff. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param int $active Staff is active or not {@min 0} {@max 1} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return array List of staff + * + * @url GET dictionary/staff + * + * @throws RestException + */ + public function getListOfStaff($sortfield = "id", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') + { + $list = array(); + + //TODO link with multicurrency module + $sql = "SELECT t.id, t.code, t.libelle, t.active, t.module"; + $sql .= " FROM ".MAIN_DB_PREFIX."c_effectif as t"; + $sql .= " WHERE t.active = ".((int) $active); + // 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 .= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of staff: '.$this->db->lasterror()); + } + + return $list; + } /** * Get the list of social networks. From 6b820ae4c5461044cad4bfc2e04d29c75ccbfd22 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sat, 25 Sep 2021 10:16:29 +0000 Subject: [PATCH 17/28] Fixing style errors. --- htdocs/api/class/api_setup.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index faccf512ed8..b957feda82c 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -1278,7 +1278,7 @@ class Setup extends DolibarrApi return $list; } - + /** * Get the list of staff. * From 1199782d61e16da2370c9ce6a57c0f99bcd50c5a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Sep 2021 13:10:46 +0200 Subject: [PATCH 18/28] Update api_setup.class.php --- htdocs/api/class/api_setup.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index b957feda82c..3ebb0252500 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -1298,7 +1298,6 @@ class Setup extends DolibarrApi { $list = array(); - //TODO link with multicurrency module $sql = "SELECT t.id, t.code, t.libelle, t.active, t.module"; $sql .= " FROM ".MAIN_DB_PREFIX."c_effectif as t"; $sql .= " WHERE t.active = ".((int) $active); From d43cf4938a43208d81509702560f0cefea466a97 Mon Sep 17 00:00:00 2001 From: Norbert Penel Date: Tue, 28 Sep 2021 13:46:03 +0200 Subject: [PATCH 19/28] it was impossible to update a task after some investigation i saw those errors but they are maybe some more around here --- htdocs/projet/class/api_tasks.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index e3d6af2de53..9366422002d 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -454,7 +454,7 @@ class Tasks extends DolibarrApi throw new RestException(404, 'Task not found'); } - if (!DolibarrApi::_checkAccessToResource('tasks', $this->project->id)) { + if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -488,7 +488,7 @@ class Tasks extends DolibarrApi throw new RestException(404, 'Task not found'); } - if (!DolibarrApi::_checkAccessToResource('tasks', $this->project->id)) { + if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } From d565f9d3f1005689749e6a3f8bb064a5440f127c Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 28 Sep 2021 15:09:47 +0200 Subject: [PATCH 20/28] reveiw code --- .../class/accountingaccount.class.php | 29 ++++++++++--------- htdocs/accountancy/customer/index.php | 2 +- htdocs/accountancy/customer/list.php | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 7ec07d1f15b..ed3c69c18bc 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -732,7 +732,8 @@ class AccountingAccount extends CommonObject /** * Return Suggest accounting accounts to bind * - * @param Societe $thirdparty Societe Object seller or Buyers + * @param Societe $buyer Societe Object Buyers + * @param $seller Company Object seller * @param Product $product Product object sell or buy * @param Facture $facture Facture * @param FactureLigne $factureDet Facture Det @@ -740,22 +741,22 @@ class AccountingAccount extends CommonObject * * @return array Accounting accounts suggested */ - public function getAccountingCodeToBind(Societe $thirdparty, Product $product, Facture $facture, FactureLigne $factureDet, $accountingAccount = array()) + public function getAccountingCodeToBind(Societe $buyer, $seller, Product $product, Facture $facture, FactureLigne $factureDet, $accountingAccount = array()) { - global $mysoc, $conf; + global $conf; global $hookmanager; // Instantiate hooks for external modules $hookmanager->initHooks(array('accoutancyBindingCalculation')); // Execute hook accoutancyBindingCalculation - $parameters = array('thirdparty' => $thirdparty, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount); + $parameters = array('buyer' => $buyer, 'seller' => $seller, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount); $reshook = $hookmanager->executeHooks('accoutancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; - $isBuyerInEEC = isInEEC($thirdparty); - $isSellerInEEC = isInEEC($mysoc); + $isBuyerInEEC = isInEEC($buyer); + $isSellerInEEC = isInEEC($seller); $code_sell_l = ''; $code_sell_p = ''; $code_sell_t = ''; @@ -764,14 +765,14 @@ class AccountingAccount extends CommonObject // Level 1: Search suggested default account for product/service $suggestedaccountingaccountbydefaultfor = ''; if ($factureDet->product_type == 1) { - if ($thirdparty->country_code == $mysoc->country_code || empty($thirdparty->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) $code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); $suggestedaccountingaccountbydefaultfor = ''; } else { if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT $code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); $suggestedaccountingaccountbydefaultfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($thirdparty->tva_intra)) { // European intravat sale, without VAT intra community number + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number $code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale @@ -783,14 +784,14 @@ class AccountingAccount extends CommonObject } } } elseif ($factureDet->product_type == 0) { - if ($thirdparty->country_code == $mysoc->country_code || empty($thirdparty->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) $code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); $suggestedaccountingaccountbydefaultfor = ''; } else { if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT $code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); $suggestedaccountingaccountbydefaultfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($thirdparty->tva_intra)) { // European intravat sale, without VAT intra community number + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number $code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale @@ -808,7 +809,7 @@ class AccountingAccount extends CommonObject // Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) $suggestedaccountingaccountfor = ''; - if ((($thirdparty->country_code == $mysoc->country_code) || empty($thirdparty->country_code)) && !empty($product->accountancy_code_sell)) { // If buyer in same country than seller (if not defined, we assume it is same country) + if ((($buyer->country_code == $seller->country_code) || empty($buyer->country_code)) && !empty($product->accountancy_code_sell)) { // If buyer in same country than seller (if not defined, we assume it is same country) $code_sell_p = $product->accountancy_code_sell; $suggestedid = $accountingAccount['dom']; $suggestedaccountingaccountfor = 'prodserv'; @@ -817,7 +818,7 @@ class AccountingAccount extends CommonObject $code_sell_p = $product->accountancy_code_sell; $suggestedid = $accountingAccount['dom']; $suggestedaccountingaccountfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($thirdparty->tva_intra) && !empty($product->accountancy_code_sell)) { // European intravat sale, without VAT intra community number + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra) && !empty($product->accountancy_code_sell)) { // European intravat sale, without VAT intra community number $code_sell_p = $product->accountancy_code_sell; $suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ? $suggestedaccountingaccountfor = 'eecwithoutvatnumber'; @@ -834,8 +835,8 @@ class AccountingAccount extends CommonObject // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { - if (!empty($thirdparty->code_compta)) { - $code_sell_t = $thirdparty->code_compta; + if (!empty($buyer->code_compta)) { + $code_sell_t = $buyer->code_compta; $suggestedid = $accountingAccount['thirdparty']; $suggestedaccountingaccountfor = 'thridparty'; } diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index 4fe6bd8cae9..7c3cc2cf0e2 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -232,7 +232,7 @@ if ($action == 'validatehistory') { $code_sell_p_notset = ''; $code_sell_t_notset = ''; - $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $product_static, $facture_static, $facture_static_det, $accoutinAccountArray); + $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accoutinAccountArray); if (!is_array($return) && $return<0) { setEventMessage($accountingAccount->error, 'errors'); } else { diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 0435f6cfafe..a730a8a9af6 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -573,7 +573,7 @@ if ($result) { $code_sell_p_notset = ''; $code_sell_t_notset = ''; - $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $product_static, $facture_static, $facture_static_det, $accoutinAccountArray); + $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accoutinAccountArray); if (!is_array($return) && $return<0) { setEventMessage($accountingAccount->error, 'errors'); } else { From b6bb27e0f743ac767c27f94d8bf60666d1c61681 Mon Sep 17 00:00:00 2001 From: javieralapps4up Date: Tue, 28 Sep 2021 17:21:22 +0200 Subject: [PATCH 21/28] FIX: #18848 --- htdocs/compta/bank/class/account.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 9fd88f44d4f..fc447980780 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1503,7 +1503,7 @@ class Account extends CommonObject { $country_code = $this->getCountryCode(); - if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) { + if (in_array($country_code, array('AD','FR', 'ES', 'GA', 'IT', 'NC'))) { return 1; // France, Spain, Gabon, ... - Not valid for CH } if (in_array($country_code, array('AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) { From f6c8932cfa3890168c02ae7c2c998729bb4a24c6 Mon Sep 17 00:00:00 2001 From: javieralapps4up Date: Tue, 28 Sep 2021 17:25:31 +0200 Subject: [PATCH 22/28] Update account.class.php --- htdocs/compta/bank/class/account.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index fc447980780..a852e351f22 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1503,7 +1503,7 @@ class Account extends CommonObject { $country_code = $this->getCountryCode(); - if (in_array($country_code, array('AD','FR', 'ES', 'GA', 'IT', 'NC'))) { + if (in_array($country_code, array('AD', 'FR', 'ES', 'GA', 'IT', 'NC'))) { return 1; // France, Spain, Gabon, ... - Not valid for CH } if (in_array($country_code, array('AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) { From 1b714042252e1bde92e8eea1a555e7edc6bc6723 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Tue, 28 Sep 2021 20:27:45 +0200 Subject: [PATCH 23/28] Update api_setup.class.php --- htdocs/api/class/api_setup.class.php | 65 +++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 3ebb0252500..26732863dc7 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2017 Regis Houssin * Copyright (C) 2017 Neil Orley * Copyright (C) 2018-2021 Frédéric France - * Copyright (C) 2018-2020 Thibault FOUCART + * Copyright (C) 2018-2021 Thibault FOUCART * * * This program is free software; you can redistribute it and/or modify @@ -1239,7 +1239,6 @@ class Setup extends DolibarrApi { $list = array(); - //TODO link with multicurrency module $sql = "SELECT t.rowid, t.code, t.label,t.short_label, t.active, t.scale, t.unit_type"; $sql .= " FROM ".MAIN_DB_PREFIX."c_units as t"; $sql .= " WHERE t.active = ".((int) $active); @@ -1280,6 +1279,68 @@ class Setup extends DolibarrApi } /** + * Get the list of legal form of business. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $country To filter on country + * @param int $active Lega form is active or not {@min 0} {@max 1} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return array List of legal form + * + * @url GET dictionary/legal_form + * + * @throws RestException + */ + public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = '', $active = 1, $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT t.rowid, t.code, t.fk_pays, t.libelle, t.isvatexempted, t.active, t.module, t.position"; + $sql .= " FROM ".MAIN_DB_PREFIX."c_forme_juridique as t"; + $sql .= " WHERE t.active = ".((int) $active); + if ($country) { + $sql .= " AND t.fk_pays = '".$this->db->escape($country)."'"; + } + // 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 .= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of legal form: '.$this->db->lasterror()); + } + + return $list; + } + +/** * Get the list of staff. * * @param string $sortfield Sort field From 4d62aff8aa0983a59cd4be0d6f5f1d33795710c2 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 28 Sep 2021 18:29:50 +0000 Subject: [PATCH 24/28] Fixing style errors. --- htdocs/api/class/api_setup.class.php | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 26732863dc7..6892092a8a3 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -1339,22 +1339,22 @@ class Setup extends DolibarrApi return $list; } - -/** - * Get the list of staff. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Number of items per page - * @param int $page Page number (starting from zero) - * @param int $active Staff is active or not {@min 0} {@max 1} - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return array List of staff - * - * @url GET dictionary/staff - * - * @throws RestException - */ + + /** + * Get the list of staff. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param int $active Staff is active or not {@min 0} {@max 1} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return array List of staff + * + * @url GET dictionary/staff + * + * @throws RestException + */ public function getListOfStaff($sortfield = "id", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') { $list = array(); From 2205073f252571615f2e47ced12273eadacd3b2c Mon Sep 17 00:00:00 2001 From: Norbert Penel Date: Thu, 30 Sep 2021 12:09:17 +0200 Subject: [PATCH 25/28] load_stats_reception is not loaded --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index fd5d8ecf1db..2702f7989b3 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5306,7 +5306,7 @@ class Product extends CommonObject } $stock_commande_fournisseur = $this->stats_commande_fournisseur['qty']; } - if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) && empty($conf->reception->enabled)) { + if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) && !empty($conf->reception->enabled)) { $filterStatus = '4'; if (isset($includedraftpoforvirtual)) { $filterStatus = '0,'.$filterStatus; From c5ad75c7c12ebbd17ad1c9ba89cda8c482b3260e Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 30 Sep 2021 12:27:01 +0000 Subject: [PATCH 26/28] Fixing style errors. --- htdocs/core/ajax/row.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php index 1f5d20af874..52cc23faf8f 100644 --- a/htdocs/core/ajax/row.php +++ b/htdocs/core/ajax/row.php @@ -101,7 +101,7 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) $perm = 1; } elseif ($table_element_line == 'product_association' && $fk_element == 'fk_product' && !empty($user->rights->produit->creer)) { $perm = 1; - } elseif ($table_element_line == 'projet_task' && $fk_element == 'fk_projet' && $user->rights->projet->creer) { + } elseif ($table_element_line == 'projet_task' && $fk_element == 'fk_projet' && $user->rights->projet->creer) { $perm = 1; } else { $tmparray = explode('_', $table_element_line); From 63218d5d5c3de75309609015d520f7c6035a144c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Sep 2021 14:30:50 +0200 Subject: [PATCH 27/28] Update product.class.php --- htdocs/product/class/product.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 1054d747387..67521ef149b 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4021,22 +4021,22 @@ class Product extends CommonObject } // Check not already father of id_pere (to avoid father -> child -> father links) - $sql = 'SELECT fk_product_pere from '.MAIN_DB_PREFIX.'product_association'; - $sql .= ' WHERE fk_product_pere = '.((int) $id_fils).' AND fk_product_fils = '.((int) $id_pere); + $sql = "SELECT fk_product_pere from ".MAIN_DB_PREFIX."product_association"; + $sql .= " WHERE fk_product_pere = ".((int) $id_fils)." AND fk_product_fils = ".((int) $id_pere); if (!$this->db->query($sql)) { dol_print_error($this->db); return -1; } else { //Selection of the highest row - $sql = 'SELECT MAX(rang) as max_rank FROM '.MAIN_DB_PREFIX.'product_association'; - $sql .= ' WHERE fk_product_pere = '.$id_pere; + $sql = "SELECT MAX(rang) as max_rank FROM ".MAIN_DB_PREFIX."product_association"; + $sql .= " WHERE fk_product_pere = ".((int) $id_pere); $resql = $this->db->query($sql); if ($resql > 0) { $obj = $this->db->fetch_object($resql); $rank = $obj->max_rank + 1; //Addition of a product with the highest rank +1 - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty,incdec,rang)'; - $sql .= ' VALUES ('.$id_pere.', '.$id_fils.', '.$qty.', '.$incdec.', '.$this->db->escape($rank).')'; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_association(fk_product_pere,fk_product_fils,qty,incdec,rang)"; + $sql .= " VALUES (".((int) $id_pere).", ".((int) $id_fils).", ".((float) $qty).", ".((float) $incdec).", ".$this->db->escape($rank).")"; if (! $this->db->query($sql)) { dol_print_error($this->db); return -1; From 827639f28deb37803d7d46012df8fec261d5ee19 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Sep 2021 14:45:22 +0200 Subject: [PATCH 28/28] Try to solve pb of unique id --- htdocs/product/composition/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index d1e59482d44..5f783d190e9 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -432,7 +432,7 @@ if ($id > 0 || !empty($ref)) { $hide = ' hideobject'; // By default, we do not show this. It makes screen very difficult to understand } - print ''; + print ''; //$productstatic->ref=$value['label']; $productstatic->ref = $value['ref'];
'.$langs->trans('Rank').''.$langs->trans('ComposedProduct').''.$langs->trans('Label').''.$langs->trans('MinSupplierPrice').''.$langs->trans('Qty').''.$langs->trans('ComposedProductIncDecStock').'
'.$object->sousprods[$parent_label][$value['id']][7].''.($value['incdec'] == 1 ? 'x' : '').''; + print '
'; for ($i = 0; $i < $value['level']; $i++) { print '     '; // Add indentation @@ -437,6 +456,7 @@ if ($id > 0 || !empty($ref)) { } print ''.$value['nb'].'