diff --git a/ChangeLog b/ChangeLog index 7823d4cefb1..d75938891f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ Following changes may create regressions for some external modules, but were nec * The methode "cloture" on contact were renamed into "closeAll". * The substitution key for reference of object is now __REF__ whatever is the object (it replaces __ORDERREF__, __PROPALREF__, ...) +* Some REST API to access the dictionary (country, town, ...) were moved into a common API. ***** ChangeLog for 6.0.1 compared to 6.0.* ***** diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index b2bb56b14b5..0ef0a4e3dc3 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2001-2004 Rodolphe Quiedeville * Copyright (C) 2002-2003 Jean-Louis Bergamo * Copyright (C) 2004-2012 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2012 Marcos GarcĂ­a * Copyright (C) 2012-2016 Philippe Grand * Copyright (C) 2015-2016 Alexandre Spangaro @@ -833,6 +833,7 @@ else print '
'; print ''; print ''; + if ($backtopage) print ''; dol_fiche_head(''); @@ -974,11 +975,18 @@ else dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; - print '
'; + print '
'; + print ''; + print '  '; + if (! empty($backtopage)) + { + print ''; + } + else + { + print ''; + } + print '
'; print "
\n"; } @@ -1245,7 +1253,7 @@ else print '
'; print ''; print '     '; - print ''; + print ''; print '
'; print ''; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 81fc6ea5909..5eb757c0c5c 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -419,33 +419,33 @@ class Adherent extends CommonObject $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " civility = ".(!is_null($this->civility_id)?$this->db->escape($this->civility_id):"null"); + $sql.= " civility = ".($this->civility_id>0?$this->db->escape($this->civility_id):"null"); $sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null"); - $sql.= ", lastname=" .($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); - $sql.= ", login=" .($this->login?"'".$this->db->escape($this->login)."'":"null"); - $sql.= ", societe=" .($this->societe?"'".$this->db->escape($this->societe)."'":"null"); - $sql.= ", fk_soc=" .($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); - $sql.= ", address=" .($this->address?"'".$this->db->escape($this->address)."'":"null"); - $sql.= ", zip=" .($this->zip?"'".$this->db->escape($this->zip)."'":"null"); - $sql.= ", town=" .($this->town?"'".$this->db->escape($this->town)."'":"null"); - $sql.= ", country=".($this->country_id>0?$this->db->escape($this->country_id):"null"); - $sql.= ", state_id=".($this->state_id>0?$this->db->escape($this->state_id):"null"); - $sql.= ", email='".$this->db->escape($this->email)."'"; - $sql.= ", skype='".$this->db->escape($this->skype)."'"; - $sql.= ", phone=" .($this->phone?"'".$this->db->escape($this->phone)."'":"null"); - $sql.= ", phone_perso=" .($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null"); - $sql.= ", phone_mobile=" .($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null"); - $sql.= ", note_private=" .($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); - $sql.= ", note_public=" .($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); - $sql.= ", photo=" .($this->photo?"'".$this->db->escape($this->photo)."'":"null"); - $sql.= ", public='".$this->db->escape($this->public)."'"; - $sql.= ", statut=" .$this->statut; - $sql.= ", fk_adherent_type=".$this->typeid; - $sql.= ", morphy='".$this->db->escape($this->morphy)."'"; - $sql.= ", birth=" .($this->birth?"'".$this->db->idate($this->birth)."'":"null"); - if ($this->datefin) $sql.= ", datefin='".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription - if ($this->datevalid) $sql.= ", datevalid='".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member - $sql.= ", fk_user_mod=".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest + $sql.= ", lastname = ".($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); + $sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null"); + $sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null"); + $sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); + $sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null"); + $sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null"); + $sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null"); + $sql.= ", country = ".($this->country_id>0?$this->db->escape($this->country_id):"null"); + $sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null"); + $sql.= ", email = '".$this->db->escape($this->email)."'"; + $sql.= ", skype = '".$this->db->escape($this->skype)."'"; + $sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null"); + $sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null"); + $sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null"); + $sql.= ", note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ", note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); + $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null"); + $sql.= ", public = '".$this->db->escape($this->public)."'"; + $sql.= ", statut = ".$this->statut; + $sql.= ", fk_adherent_type = ".$this->typeid; + $sql.= ", morphy = '".$this->db->escape($this->morphy)."'"; + $sql.= ", birth = ".($this->birth?"'".$this->db->idate($this->birth)."'":"null"); + if ($this->datefin) $sql.= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription + if ($this->datevalid) $sql.= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member + $sql.= ", fk_user_mod = ".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest $sql.= " WHERE rowid = ".$this->id; dol_syslog(get_class($this)."::update update member", LOG_DEBUG); @@ -686,15 +686,15 @@ class Adherent extends CommonObject * Fonction qui supprime l'adherent et les donnees associees * * @param int $rowid Id of member to delete - * @param User $user User object + * @param User $user User object * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, 0=nothing to do, >0 if OK */ - function delete($rowid, $user, $notrigger=0) - { - global $conf, $langs; + function delete($rowid, $user, $notrigger=0) + { + global $conf, $langs; - $result = 0; + $result = 0; $error=0; $errorflag=0; @@ -711,84 +711,83 @@ class Adherent extends CommonObject // End call triggers } - // Remove category - $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-1; + // Remove category + $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-1; + } - } + // Remove subscription + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-2; + } + } - // Remove subscription - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-2; - } - } + // Remove linked user + if (! $error) + { + $ret=$this->setUserId(0); + if ($ret < 0) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-3; + } + } - // Remove linked user - if (! $error) - { - $ret=$this->setUserId(0); - if ($ret < 0) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-3; - } - } + // Removed extrafields + if (! $error) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + $errorflag=-4; + dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); + } + } + } - // Removed extrafields - if (! $error) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->deleteExtraFields(); - if ($result < 0) - { - $error++; - $errorflag=-4; - dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); - } - } - } + // Remove adherent + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-5; + } + } - // Remove adherent - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-5; - } - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return $errorflag; - } - } + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return $errorflag; + } + } /** diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index eec88a59c11..30c85618bfa 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2002 Rodolphe Quiedeville * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2009-2017 Regis Houssin * Copyright (C) 2016 Charlie Benke @@ -22,7 +22,6 @@ * \file htdocs/adherents/class/adherent_type.class.php * \ingroup member * \brief File of class to manage members types - * \author Rodolphe Quiedeville */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; @@ -62,228 +61,331 @@ class AdherentType extends CommonObject public $vote; /** @var bool Email sent during validation */ public $mail_valid; + /** @var array Array of members */ + public $members=array(); - /** + /** * Constructor * * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - $this->statut = 1; - } + */ + function __construct($db) + { + $this->db = $db; + $this->statut = 1; + } - /** - * Fonction qui permet de creer le status de l'adherent - * - * @param User $user User making creation - * @return int >0 if OK, < 0 if KO - */ - function create($user) - { - global $conf; + /** + * Fonction qui permet de creer le status de l'adherent + * + * @param User $user User making creation + * @param int $notrigger 1=do not execute triggers, 0 otherwise + * @return int >0 if OK, < 0 if KO + */ + function create($user,$notrigger=0) + { + global $conf; - $this->statut=(int) $this->statut; - $this->label=(!empty($this->libelle)?trim($this->libelle):trim($this->label)); + $error=0; - $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent_type ("; - $sql.= "libelle"; - $sql.= ", entity"; - $sql.= ") VALUES ("; - $sql.= "'".$this->db->escape($this->label)."'"; - $sql.= ", ".$conf->entity; - $sql.= ")"; + $this->statut=(int) $this->statut; + $this->label=trim($this->label); - dol_syslog("Adherent_type::create", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent_type"); - return $this->update($user); - } - else - { - $this->error=$this->db->error().' sql='.$sql; - return -1; - } - } + $this->db->begin(); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent_type ("; + $sql.= "libelle"; + $sql.= ", entity"; + $sql.= ") VALUES ("; + $sql.= "'".$this->db->escape($this->label)."'"; + $sql.= ", ".$conf->entity; + $sql.= ")"; - /** - * Met a jour en base donnees du type - * - * @param User $user Object user making change - * @return int >0 if OK, < 0 if KO - */ - function update($user) - { - global $hookmanager,$conf; + dol_syslog("Adherent_type::create", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent_type"); - $error=0; + $result = $this->update($user,1); + if ($result < 0) + { + $this->db->rollback(); + return -3; + } - $this->label=(!empty($this->libelle)?trim($this->libelle):trim($this->label)); + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent_type "; - $sql.= "SET "; - $sql.= "statut = ".$this->statut.","; - $sql.= "libelle = '".$this->db->escape($this->label) ."',"; - $sql.= "subscription = '".$this->db->escape($this->subscription)."',"; - $sql.= "note = '".$this->db->escape($this->note)."',"; - $sql.= "vote = '".$this->db->escape($this->vote)."',"; - $sql.= "mail_valid = '".$this->db->escape($this->mail_valid)."'"; - $sql.= " WHERE rowid =".$this->id; + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } - $result = $this->db->query($sql); - if ($result) - { - $action='update'; + /** + * Met a jour en base donnees du type + * + * @param User $user Object user making change + * @param int $notrigger 1=do not execute triggers, 0 otherwise + * @return int >0 if OK, < 0 if KO + */ + function update($user,$notrigger=0) + { + global $conf, $hookmanager; - // Actions on extra fields (by external module or standard code) - $hookmanager->initHooks(array('membertypedao')); - $parameters=array('membertype'=>$this->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; + $error=0; + $this->label=trim($this->label); - return 1; - } - else - { - $this->error=$this->db->error().' sql='.$sql; - return -1; - } - } + $this->db->begin(); - /** - * Fonction qui permet de supprimer le status de l'adherent - * - * @param int $rowid Id of member type to delete - * @return int >0 if OK, 0 if not found, < 0 if KO - */ - function delete($rowid='') - { - if (empty($rowid)) $rowid=$this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent_type "; + $sql.= "SET "; + $sql.= "statut = ".$this->statut.","; + $sql.= "libelle = '".$this->db->escape($this->label) ."',"; + $sql.= "subscription = '".$this->db->escape($this->subscription)."',"; + $sql.= "note = '".$this->db->escape($this->note)."',"; + $sql.= "vote = '".$this->db->escape($this->vote)."',"; + $sql.= "mail_valid = '".$this->db->escape($this->mail_valid)."'"; + $sql.= " WHERE rowid =".$this->id; - $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent_type WHERE rowid = ".$rowid; + $result = $this->db->query($sql); + if ($result) + { + $action='update'; - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->affected_rows($resql)) - { - return 1; - } - else - { - return 0; - } - } - else - { - print "Err : ".$this->db->error(); - return 0; - } - } + // Actions on extra fields (by external module or standard code) + $hookmanager->initHooks(array('membertypedao')); + $parameters=array('membertype'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; - /** - * Fonction qui permet de recuperer le status de l'adherent - * - * @param int $rowid Id of member type to load - * @return int <0 if KO, >0 if OK - */ - function fetch($rowid) - { - $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; - $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; - $sql .= " WHERE d.rowid = ".$rowid; + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers + } - dol_syslog("Adherent_type::fetch", LOG_DEBUG); + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); + return -$error; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); + /** + * Fonction qui permet de supprimer le status de l'adherent + * + * @return int >0 if OK, 0 if not found, < 0 if KO + */ + function delete() + { + global $user; - $this->id = $obj->rowid; - $this->ref = $obj->rowid; - $this->label = $obj->label; - $this->libelle = $obj->label; // For backward compatibility - $this->statut = $obj->statut; - $this->subscription = $obj->subscription; - $this->mail_valid = $obj->mail_valid; - $this->note = $obj->note; - $this->vote = $obj->vote; - } - return 1; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent_type"; + $sql.= " WHERE rowid = ".$this->id; - /** - * Return list of members' type - * - * @return array List of types of members - */ - function liste_array() - { - global $conf,$langs; + $resql=$this->db->query($sql); + if ($resql) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_DELETE',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -2; } + // End call triggers - $adherenttypes = array(); + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } - $sql = "SELECT rowid, libelle"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; - $sql.= " WHERE entity IN (".getEntity('adherent').")"; + /** + * Fonction qui permet de recuperer le status de l'adherent + * + * @param int $rowid Id of member type to load + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid) + { + $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; + $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; + $sql .= " WHERE d.rowid = ".$rowid; - $resql=$this->db->query($sql); - if ($resql) - { - $nump = $this->db->num_rows($resql); + dol_syslog("Adherent_type::fetch", LOG_DEBUG); - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = $this->db->fetch_object($resql); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); - $adherenttypes[$obj->rowid] = $langs->trans($obj->libelle); - $i++; - } - } - } - else - { - print $this->db->error(); - } - return $adherenttypes; - } + $this->id = $obj->rowid; + $this->ref = $obj->rowid; + $this->label = $obj->label; + $this->statut = $obj->statut; + $this->subscription = $obj->subscription; + $this->mail_valid = $obj->mail_valid; + $this->note = $obj->note; + $this->vote = $obj->vote; + } + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Return list of members' type + * + * @return array List of types of members + */ + function liste_array() + { + global $conf,$langs; + + $adherenttypes = array(); + + $sql = "SELECT rowid, libelle as label"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; + $sql.= " WHERE entity IN (".getEntity('adherent').")"; + + $resql=$this->db->query($sql); + if ($resql) + { + $nump = $this->db->num_rows($resql); + + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = $this->db->fetch_object($resql); + + $adherenttypes[$obj->rowid] = $langs->trans($obj->label); + $i++; + } + } + } + else + { + print $this->db->error(); + } + return $adherenttypes; + } + + /** + * Return array of Member objects for member type this->id (or all if this->id not defined) + * + * @param string $excludefilter Filter to exclude + * @param int $mode 0=Return array of member instance, 1=Return array of members id only + * @return mixed Array of members or -1 on error + */ + function listMembersForMemberType($excludefilter='', $mode=0) + { + global $conf, $user; + + $ret=array(); + + $sql = "SELECT a.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; + $sql.= " WHERE a.entity IN (".getEntity('member').")"; + $sql.= " AND a.fk_adherent_type = ".$this->id; + if (! empty($excludefilter)) $sql.=' AND ('.$excludefilter.')'; + + dol_syslog(get_class($this)."::listUsersForGroup", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + if (! array_key_exists($obj->rowid, $ret)) + { + if ($mode != 1) + { + $memberstatic=new Adherent($this->db); + $memberstatic->fetch($obj->rowid); + $ret[$obj->rowid]=$memberstatic; + } + else $ret[$obj->rowid]=$obj->rowid; + } + } + + $this->db->free($resql); + + $this->members=$ret; + + return $ret; + } + 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 $maxlen length max libelle + * @param int $maxlen length max label * @return string String with URL */ function getNomUrl($withpicto=0,$maxlen=0) @@ -291,7 +393,7 @@ class AdherentType extends CommonObject global $langs; $result=''; - $label=$langs->trans("ShowTypeCard",$this->libelle); + $label=$langs->trans("ShowTypeCard",$this->label); $link = ''; $linkend=''; @@ -300,75 +402,159 @@ class AdherentType extends CommonObject if ($withpicto) $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); if ($withpicto && $withpicto != 2) $result.=' '; - $result.=$link.($maxlen?dol_trunc($this->libelle,$maxlen):$this->libelle).$linkend; + $result.=$link.($maxlen?dol_trunc($this->label,$maxlen):$this->label).$linkend; return $result; } - /** * getLibStatut * * @return string Return status of a type of member */ - function getLibStatut() - { - return ''; - } + function getLibStatut() + { + return ''; + } - /** - * getMailOnValid - * - * @return string Return mail model - */ - function getMailOnValid() - { - global $conf; + /** + * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet + * + * @param array $info Info array loaded by _load_ldap_info + * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb) + * 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb) + * 2=Return key only (uid=qqq) + * @return string DN + */ + function _load_ldap_dn($info,$mode=0) + { + global $conf; + $dn=''; + if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS_TYPES."=".$info[$conf->global->LDAP_KEY_MEMBERS_TYPES].",".$conf->global->LDAP_MEMBER_TYPE_DN; + if ($mode==1) $dn=$conf->global->LDAP_MEMBER_TYPE_DN; + if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS_TYPES."=".$info[$conf->global->LDAP_KEY_MEMBERS_TYPES]; + return $dn; + } - if (! empty($this->mail_valid) && trim(dol_htmlentitiesbr_decode($this->mail_valid))) - { - return $this->mail_valid; - } - else - { - return $conf->global->ADHERENT_MAIL_VALID; - } - } - /** - * getMailOnSubscription - * - * @return string Return mail model - */ - function getMailOnSubscription() - { - global $conf; - // mail_subscription not defined so never used - if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription))) // Property not yet defined - { - return $this->mail_subscription; - } - else - { - return $conf->global->ADHERENT_MAIL_COTIS; - } - } + /** + * Initialize the info array (array of LDAP values) that will be used to call LDAP functions + * + * @return array Tableau info des attributs + */ + function _load_ldap_info() + { + global $conf,$langs; + + $info=array(); + + // Object classes + $info["objectclass"]=explode(',',$conf->global->LDAP_MEMBER_TYPE_OBJECT_CLASS); + + // Champs + if ($this->label && ! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME)) $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME] = $this->label; + if ($this->note && ! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION] = $this->note; + if (! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)) + { + $valueofldapfield=array(); + foreach($this->members as $key=>$val) // This is array of users for group into dolibarr database. + { + $member=new Adherent($this->db); + $member->fetch($val->id); + $info2 = $member->_load_ldap_info(); + $valueofldapfield[] = $member->_load_ldap_dn($info2); + } + $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); + } + return $info; + } + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + global $conf, $user, $langs; + + // Initialise parametres + $this->id = 0; + $this->ref = 0; + $this->specimen=1; + + $this->label='MEMBERS TYPE SPECIMEN'; + $this->note='This is a note'; + $this->mail_valid='This is welcome email'; + $this->subscription=1; + $this->vote=0; + + $this->statut=1; + + // Members of this member type is just me + $this->members=array( + $user->id => $user + ); + } + + /** + * getMailOnValid + * + * @return string Return mail model + */ + function getMailOnValid() + { + global $conf; + + if (! empty($this->mail_valid) && trim(dol_htmlentitiesbr_decode($this->mail_valid))) + { + return $this->mail_valid; + } + else + { + return $conf->global->ADHERENT_MAIL_VALID; + } + } + + /** + * getMailOnSubscription + * + * @return string Return mail model + */ + function getMailOnSubscription() + { + global $conf; + + // mail_subscription not defined so never used + if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription))) // Property not yet defined + { + return $this->mail_subscription; + } + else + { + return $conf->global->ADHERENT_MAIL_COTIS; + } + } + + /** + * getMailOnResiliate + * + * @return string Return mail model + */ + function getMailOnResiliate() + { + global $conf; + + // NOTE mail_resiliate not defined so never used + if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate))) // Property not yet defined + { + return $this->mail_resiliate; + } + else + { + return $conf->global->ADHERENT_MAIL_RESIL; + } + } - /** - * getMailOnResiliate - * - * @return string Return mail model - */ - function getMailOnResiliate() - { - global $conf; - // NOTE mail_resiliate not defined so never used - if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate))) // Property not yet defined - { - return $this->mail_resiliate; - } - else - { - return $conf->global->ADHERENT_MAIL_RESIL; - } - } } diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index ff8064d80fb..c6adaf50142 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -272,7 +272,6 @@ class MembersTypes extends DolibarrApi $object = parent::_cleanObjectDatas($object); unset($object->cotisation); - unset($object->libelle); unset($object->array_options); unset($object->linkedObjectsIds); diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php index 2614a27d509..54779432a3b 100644 --- a/htdocs/adherents/index.php +++ b/htdocs/adherents/index.php @@ -59,7 +59,7 @@ $AdherentsResilies=array(); $AdherentType=array(); // Liste les adherents -$sql = "SELECT t.rowid, t.libelle, t.subscription,"; +$sql = "SELECT t.rowid, t.libelle as label, t.subscription,"; $sql.= " d.statut, count(d.rowid) as somme"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."adherent as d"; @@ -81,7 +81,7 @@ if ($result) $adhtype=new AdherentType($db); $adhtype->id=$objp->rowid; $adhtype->subscription=$objp->subscription; - $adhtype->libelle=$objp->libelle; + $adhtype->label=$objp->label; $AdherentType[$objp->rowid]=$adhtype; if ($objp->statut == -1) { $MemberToValidate[$objp->rowid]=$objp->somme; } @@ -273,7 +273,7 @@ $max=5; $sql = "SELECT a.rowid, a.statut, a.lastname, a.firstname, a.societe as company, a.fk_soc,"; $sql.= " a.tms as datem, datefin as date_end_subscription,"; -$sql.= " ta.rowid as typeid, ta.libelle, ta.subscription"; +$sql.= " ta.rowid as typeid, ta.libelle as label, ta.subscription"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a, ".MAIN_DB_PREFIX."adherent_type as ta"; $sql.= " WHERE a.entity IN (".getEntity('adherent').")"; $sql.= " AND a.fk_adherent_type = ta.rowid"; @@ -310,7 +310,7 @@ if ($resql) } $staticmember->ref=$staticmember->getFullName($langs); $statictype->id=$obj->typeid; - $statictype->libelle=$obj->libelle; + $statictype->label=$obj->label; print ''.$staticmember->getNomUrl(1,32).''; print ''.$statictype->getNomUrl(1,32).''; print ''.dol_print_date($db->jdate($obj->datem),'dayhour').''; diff --git a/htdocs/adherents/ldap.php b/htdocs/adherents/ldap.php index 38e90663c0f..65aea951d76 100644 --- a/htdocs/adherents/ldap.php +++ b/htdocs/adherents/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006 Regis Houssin +/* Copyright (C) 2006 Laurent Destailleur + * Copyright (C) 2006-2017 Regis Houssin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -218,13 +218,11 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; - llxFooter(); - $db->close(); diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 3dc5439f47f..783934deb34 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -315,7 +315,7 @@ if ($search_type > 0) { $membertype=new AdherentType($db); $result=$membertype->fetch(GETPOST("type",'int')); - $titre.=" (".$membertype->libelle.")"; + $titre.=" (".$membertype->label.")"; } $param=''; @@ -698,7 +698,7 @@ while ($i < min($num, $limit)) if (! empty($arrayfields['t.libelle']['checked'])) { $membertypestatic->id=$obj->type_id; - $membertypestatic->libelle=$obj->type; + $membertypestatic->label=$obj->type; print ''; print $membertypestatic->getNomUrl(1,32); print ''; diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index a0f36c409de..b59d8b7530d 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2001-2002 Rodolphe Quiedeville * Copyright (C) 2003 Jean-Louis Bergamo * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2017 Regis Houssin @@ -37,6 +37,7 @@ $langs->load("members"); $rowid = GETPOST('rowid','int'); $action = GETPOST('action','alpha'); $cancel = GETPOST('cancel','alpha'); +$backtopage = GETPOST('backtopage','alpha'); $search_lastname = GETPOST('search_lastname','alpha'); $search_login = GETPOST('search_login','alpha'); @@ -64,6 +65,8 @@ $mail_valid=GETPOST("mail_valid"); // Security check $result=restrictedArea($user,'adherent',$rowid,'adherent_type'); +$object = new AdherentType($db); + $extrafields = new ExtraFields($db); // fetch optionals attributes and labels @@ -87,73 +90,113 @@ $hookmanager->initHooks(array('membertypecard','globalcard')); * Actions */ +if ($cancel) { + + $action=''; + + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } +} + if ($action == 'add' && $user->rights->adherent->configurer) { - if (! $cancel) + $object->label = trim($label); + $object->subscription = (int) trim($subscription); + $object->note = trim($comment); + $object->mail_valid = trim($mail_valid); + $object->vote = (boolean) trim($vote); + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + if ($ret < 0) $error++; + + if (empty($object->label)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")), null, 'errors'); + } + else { + $sql = "SELECT libelle FROM ".MAIN_DB_PREFIX."adherent_type WHERE libelle='".$db->escape($object->label)."'"; + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + } + if ($num) { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorLabelAlreadyExists",$login), null, 'errors'); + } + } + + if (! $error) { - $object = new AdherentType($db); - - $object->label = trim($label); - $object->subscription = (int) trim($subscription); - $object->note = trim($comment); - $object->mail_valid = (boolean) trim($mail_valid); - $object->vote = (boolean) trim($vote); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - if ($ret < 0) $error++; - - if ($object->label) + $id=$object->create($user); + if ($id > 0) { - $id=$object->create($user); - if ($id > 0) - { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; - } - else - { - $mesg=$object->error; - $action = 'create'; - } + header("Location: ".$_SERVER["PHP_SELF"]); + exit; } else { - $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")); + setEventMessages($object->error, $object->errors, 'errors'); $action = 'create'; } } + else + { + $action = 'create'; + } } if ($action == 'update' && $user->rights->adherent->configurer) { - if (! $cancel) + $object->fetch($rowid); + + $object->oldcopy = clone $object; + + $object->label = trim($label); + $object->subscription = (int) trim($subscription); + $object->note = trim($comment); + $object->mail_valid = trim($mail_valid); + $object->vote = (boolean) trim($vote); + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + if ($ret < 0) $error++; + + $ret=$object->update($user); + + if ($ret >= 0 && ! count($object->errors)) { - $object = new AdherentType($db); - $object->id = $rowid; - $object->label = trim($label); - $object->subscription = (int) trim($subscription); - $object->note = trim($comment); - $object->mail_valid = (boolean) trim($mail_valid); - $object->vote = (boolean) trim($vote); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - if ($ret < 0) $error++; - - $object->update($user); - - header("Location: ".$_SERVER["PHP_SELF"]."?rowid=".$_POST["rowid"]); - exit; + setEventMessages($langs->trans("MemberTypeModified"), null, 'mesgs'); } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + + header("Location: ".$_SERVER["PHP_SELF"]."?rowid=".$object->id); + exit; } -if ($action == 'delete' && $user->rights->adherent->configurer) +if ($action == 'confirm_delete' && $user->rights->adherent->configurer) { - $object = new AdherentType($db); - $object->delete($rowid); - header("Location: ".$_SERVER["PHP_SELF"]); - exit; + $object->fetch($rowid); + $res=$object->delete(); + + if ($res > 0) + { + setEventMessages($langs->trans("MemberTypeDeleted"), null, 'mesgs'); + header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + setEventMessages($langs->trans("MemberTypeCanNotBeDeleted"), null, 'errors'); + $action=''; + } } @@ -308,7 +351,15 @@ if ($rowid > 0) { $object = new AdherentType($db); $object->fetch($rowid); - $object->fetch_optionals($rowid,$extralabels); + $object->fetch_optionals($object->id,$extralabels); + + /* + * Confirmation suppression + */ + if ($action == 'delete') + { + print $form->formconfirm($_SERVER['PHP_SELF']."?rowid=".$object->id,$langs->trans("DeleteAMemberType"),$langs->trans("ConfirmDeleteMemberType",$object->label),"confirm_delete", '',0,1); + } $head = member_type_prepare_head($object); @@ -337,15 +388,14 @@ if ($rowid > 0) print ''.$langs->trans("WelcomeEMail").''; print nl2br($object->mail_valid).""; - // Other attributes - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; print ''; - print ''; + print ''; dol_fiche_end(); - /* * Buttons */ @@ -359,7 +409,7 @@ if ($rowid > 0) } // Add - print ''; + print ''; // Delete if ($user->rights->adherent->configurer) @@ -459,7 +509,7 @@ if ($rowid > 0) $titre.=" (".$membertype->label.")"; } - $param="&rowid=".$rowid; + $param="&rowid=".$object->id; if (! empty($status)) $param.="&status=".$status; if (! empty($search_lastname)) $param.="&search_lastname=".$search_lastname; if (! empty($search_firstname)) $param.="&search_firstname=".$search_firstname; @@ -473,7 +523,7 @@ if ($rowid > 0) } print '
'; - print ''; + print ''; print '
'; print_barre_liste('',$page,$_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords); @@ -593,12 +643,12 @@ if ($rowid > 0) print ''; if ($user->rights->adherent->creer) { - print ''.img_edit().''; + print ''.img_edit().''; } print ' '; if ($user->rights->adherent->supprimer) { - print ''.img_picto($langs->trans("Resiliate"),'disable.png').''; + print ''.img_picto($langs->trans("Resiliate"),'disable.png').''; } print ""; @@ -631,15 +681,14 @@ if ($rowid > 0) if ($action == 'edit') { $object = new AdherentType($db); - $object->id = $rowid; $object->fetch($rowid); - $object->fetch_optionals($rowid,$extralabels); + $object->fetch_optionals($object->id,$extralabels); $head = member_type_prepare_head($object); - print ''; + print ''; print ''; - print ''; + print ''; print ''; dol_fiche_head($head, 'card', $langs->trans("MemberType"), 0, 'group'); @@ -706,7 +755,7 @@ if ($rowid > 0) print '
'; print ''; print '     '; - print ''; + print ''; print '
'; print "
"; diff --git a/htdocs/adherents/type_ldap.php b/htdocs/adherents/type_ldap.php new file mode 100644 index 00000000000..d4de1a2afdb --- /dev/null +++ b/htdocs/adherents/type_ldap.php @@ -0,0 +1,191 @@ + + * Copyright (C) 2006-2017 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/adherents/type_ldap.php + * \ingroup ldap + * \brief Page fiche LDAP members types + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; + +$langs->load("members"); +$langs->load("admin"); +$langs->load("ldap"); + +$id = GETPOST('rowid', 'int'); +$action = GETPOST('action','alpha'); + +// Security check +$result=restrictedArea($user,'adherent',$id,'adherent_type'); + +$object = new AdherentType($db); +$object->fetch($id); + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('membertypeldapcard','globalcard')); + +/* + * Actions + */ + + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + if ($action == 'dolibarr2ldap') + { + $ldap = new Ldap(); + $result = $ldap->connect_bind(); + + if ($result > 0) + { + $object->listMembersForMemberType(); + + $info = $object->_load_ldap_info(); + $dn = $object->_load_ldap_dn($info); + $olddn = $dn; // We can say that old dn = dn as we force synchro + + $result = $ldap->update($dn, $info, $user, $olddn); + } + + if ($result >= 0) { + setEventMessages($langs->trans("MemberTypeSynchronized"), null, 'mesgs'); + } + else { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } + } +} + +/* + * View + */ + +llxHeader(); + +$form = new Form($db); + +$head = member_type_prepare_head($object); + +dol_fiche_head($head, 'ldap', $langs->trans("MemberType"), -1, 'group'); + +$linkback = ''.$langs->trans("BackToList").''; + +dol_banner_tab($object, 'rowid', $linkback); + +print '
'; +print '
'; + +print ''; + +// LDAP DN +print '\n"; + +// LDAP Cle +print '\n"; + +// LDAP Server +print '\n"; +print '\n"; +print '\n"; +print '\n"; +print '\n"; + +print '
LDAP '.$langs->trans("LDAPMemberTypeDn").''.$conf->global->LDAP_MEMBER_TYPE_DN."
LDAP '.$langs->trans("LDAPNamingAttribute").''.$conf->global->LDAP_KEY_MEMBERS_TYPES."
LDAP '.$langs->trans("Type").''.$conf->global->LDAP_SERVER_TYPE."
LDAP '.$langs->trans("Version").''.$conf->global->LDAP_SERVER_PROTOCOLVERSION."
LDAP '.$langs->trans("LDAPPrimaryServer").''.$conf->global->LDAP_SERVER_HOST."
LDAP '.$langs->trans("LDAPSecondaryServer").''.$conf->global->LDAP_SERVER_HOST_SLAVE."
LDAP '.$langs->trans("LDAPServerPort").''.$conf->global->LDAP_SERVER_PORT."
'; + +print '
'; + +dol_fiche_end(); + +/* + * Barre d'actions + */ + +print '
'; + +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) +{ + print ''.$langs->trans("ForceSynchronize").''; +} + +print "
\n"; + +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) print "
\n"; + + + +// Affichage attributs LDAP +print load_fiche_titre($langs->trans("LDAPInformationsForThisMemberType")); + +print ''; + +print ''; +print ''; +print ''; +print ''; + +// Lecture LDAP +$ldap=new Ldap(); +$result=$ldap->connect_bind(); +if ($result > 0) +{ + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info,1); + $search = "(".$object->_load_ldap_dn($info,2).")"; + $records = $ldap->getAttribute($dn,$search); + + //print_r($records); + + // Affichage arbre + if ((! is_numeric($records) || $records != 0) && (! isset($records['count']) || $records['count'] > 0)) + { + if (! is_array($records)) + { + print ''; + } + else + { + $result=show_ldap_content($records,0,$records['count'],true); + } + } + else + { + print ''; + } + + $ldap->unbind(); + $ldap->close(); +} +else +{ + setEventMessages($ldap->error, $ldap->errors, 'errors'); +} + +print '
'.$langs->trans("LDAPAttributes").''.$langs->trans("Value").'
'.$langs->trans("ErrorFailedToReadLDAP").'
'.$langs->trans("LDAPRecordNotFound").' (dn='.$dn.' - search='.$search.')
'; + +llxFooter(); +$db->close(); diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 0aa9b5a9e78..32f895dc1ec 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -621,7 +621,8 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($value == 'localtax2' && empty($_POST['localtax2_type'])) continue; if ($value == 'color' && empty($_POST['color'])) continue; if ($value == 'formula' && empty($_POST['formula'])) continue; - if ((! isset($_POST[$value]) || $_POST[$value]=='') + if ($value == 'sortorder') continue; // For a column name 'sortorder', we use the field name 'position' + if ((! isset($_POST[$value]) || $_POST[$value]=='') && (! in_array($listfield[$f], array('decalage','module','accountancy_code','accountancy_code_sell','accountancy_code_buy')) // Fields that are not mandatory && (! ($id == 10 && $listfield[$f] == 'code')) // Code is mandatory fir table 10 ) @@ -736,7 +737,11 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) $_POST[$listfieldvalue[$i]] = getEntity($tabname[$id], 2); } if ($i) $sql.=","; - if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' + if ($listfieldvalue[$i] == 'sortorder') // For column name 'sortorder', we use the field name 'position' + { + $sql.="'".(int) $db->escape($_POST['position'])."'"; + } + elseif ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } @@ -785,7 +790,11 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) } if ($i) $sql.=","; $sql.= $field."="; - if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' + if ($listfieldvalue[$i] == 'sortorder') // For column name 'sortorder', we use the field name 'position' + { + $sql.="'".(int) $db->escape($_POST['position'])."'"; + } + elseif ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } @@ -1938,6 +1947,8 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') } else { + if ($fieldlist[$field]=='sortorder') $fieldlist[$field]='position'; + $classtd=''; $class=''; if ($fieldlist[$field]=='code') $classtd='width100'; if ($fieldlist[$field]=='affect') $class='maxwidth50'; diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index d5720835f3c..f9b863e487e 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -68,6 +68,7 @@ if (empty($reshook)) if (! dolibarr_set_const($db, 'LDAP_SYNCHRO_ACTIVE',GETPOST("activesynchro"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_CONTACT_ACTIVE',GETPOST("activecontact"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_ACTIVE',GETPOST("activemembers"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_ACTIVE',GETPOST("activememberstypes"),'chaine',0,'',$conf->entity)) $error++; if (! $error) { @@ -135,7 +136,6 @@ print ''; // Synchro contact active if (! empty($conf->societe->enabled)) { - print ''.$langs->trans("LDAPDnContactActive").''; $arraylist=array(); $arraylist['0']=$langs->trans("No"); @@ -147,7 +147,6 @@ if (! empty($conf->societe->enabled)) // Synchro member active if (! empty($conf->adherent->enabled)) { - print ''.$langs->trans("LDAPDnMemberActive").''; $arraylist=array(); $arraylist['0']=$langs->trans("No"); @@ -157,6 +156,18 @@ if (! empty($conf->adherent->enabled)) print ''.$langs->trans("LDAPDnMemberActiveExample").''; } +// Synchro member type active +if (! empty($conf->adherent->enabled)) +{ + print ''.$langs->trans("LDAPDnMemberTypeActive").''; + $arraylist=array(); + $arraylist['0']=$langs->trans("No"); + $arraylist['1']=$langs->trans("DolibarrToLDAP"); + $arraylist['ldap2dolibarr']=$langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; + print $form->selectarray('activememberstypes',$arraylist,$conf->global->LDAP_MEMBER_TYPE_ACTIVE); + print ''.$langs->trans("LDAPDnMemberTypeActiveExample").''; +} + // Fields from hook $parameters=array(); $reshook=$hookmanager->executeHooks('addAdminLdapOptions',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index fc68d815439..d431a7aaf30 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -220,8 +220,9 @@ if (function_exists("ldap_connect")) $dn=$object->_load_ldap_dn($info); // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } $result1=$ldap->delete($dn); // To be sure to delete existing records $result2=$ldap->add($dn,$info,$user); // Now the test diff --git a/htdocs/admin/ldap_members_types.php b/htdocs/admin/ldap_members_types.php new file mode 100644 index 00000000000..47286dc98da --- /dev/null +++ b/htdocs/admin/ldap_members_types.php @@ -0,0 +1,252 @@ + + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2006-2011 Laurent Destailleur + * Copyright (C) 2011-2013 Juanjo Menent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/ldap_members_types.php + * \ingroup ldap + * \brief Page to setup LDAP synchronization for members types + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; + +$langs->load("admin"); +$langs->load("errors"); + +if (!$user->admin) + accessforbidden(); + +$action = GETPOST('action','aZ09'); + + +/* + * Actions + */ + +if ($action == 'setvalue' && $user->admin) +{ + $error=0; + $db->begin(); + + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_DN',GETPOST("membertype"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_OBJECT_CLASS',GETPOST("objectclass"),'chaine',0,'',$conf->entity)) $error++; + + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_FULLNAME',GETPOST("fieldfullname"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_DESCRIPTION',GETPOST("fielddescription"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS',GETPOST("fieldmembertypemembers"),'chaine',0,'',$conf->entity)) $error++; + + // This one must be after the others + $valkey=''; + $key=GETPOST("key"); + if ($key) $valkey=$conf->global->$key; + if (! dolibarr_set_const($db, 'LDAP_KEY_MEMBERS_TYPES',$valkey,'chaine',0,'',$conf->entity)) $error++; + + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + dol_print_error($db); + } +} + + + +/* + * View + */ + +llxHeader('',$langs->trans("LDAPSetup"),'EN:Module_LDAP_En|FR:Module_LDAP|ES:Módulo_LDAP'); +$linkback=''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans("LDAPSetup"),$linkback,'title_setup'); + +$head = ldap_prepare_head(); + +// Test si fonction LDAP actives +if (! function_exists("ldap_connect")) +{ + setEventMessages($langs->trans("LDAPFunctionsNotAvailableOnPHP"), null, 'errors'); +} + +dol_fiche_head($head, 'memberstypes', $langs->trans("LDAPSetup"), -1); + + +print $langs->trans("LDAPDescMembersTypes").'
'; +print '
'; + + +print '
'; +print ''; + +$form=new Form($db); + +print ''; +$var=true; + +print ''; +print ''; +print "\n"; + +// DN pour les types de membres + +print ''; +print ''; +print ''; + +// List of object class used to define attributes in structure + +print ''; +print ''; +print ''; + +print '
'.$langs->trans("LDAPSynchronizeMembersTypes").'
'.$langs->trans("LDAPMemberTypeDn").''; +print ''; +print ''.$langs->trans("LDAPMemberTypepDnExample").' 
'.$langs->trans("LDAPMemberTypeObjectClassList").''; +print ''; +print ''.$langs->trans("LDAPMemberTypeObjectClassListExample").' 
'; +print '
'; +print ''; +$var=true; + +print ''; +print ''; +print ''; +print ''; +print "\n"; + +// Filtre + +// Common name + +print ''; +print '"; +print ''; + +// Description + +print ''; +print '"; +print ''; + +// User group + +print ''; +print '"; +print ''; + +print '
'.$langs->trans("LDAPDolibarrMapping").''.$langs->trans("LDAPLdapMapping").''.$langs->trans("LDAPNamingAttribute").'
'.$langs->trans("LDAPFieldName").''; +print ''; +print ''.$langs->trans("LDAPFieldCommonNameExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBERS_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME)?' checked':'').">
'.$langs->trans("LDAPFieldDescription").''; +print ''; +print ''.$langs->trans("LDAPFieldDescriptionExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBER_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)?' checked':'').">
'.$langs->trans("LDAPFieldGroupMembers").''; +print ''; +print ''.$langs->trans("LDAPFieldGroupMembersExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBERS_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)?' checked':'').">
'; + +print info_admin($langs->trans("LDAPDescValues")); + +dol_fiche_end(); + +print '
'; + +print '
'; + + +/* + * Test de la connexion + */ +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') +{ + $butlabel=$langs->trans("LDAPTestSynchroMemberType"); + $testlabel='testmembertype'; + $key=$conf->global->LDAP_KEY_MEMBERS_TYPES; + $dn=$conf->global->LDAP_MEMBER_TYPE_DN; + $objectclass=$conf->global->LDAP_MEMBER_TYPE_OBJECT_CLASS; + + show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass); +} + +if (function_exists("ldap_connect")) +{ + if ($_GET["action"] == 'testmembertype') + { + // Creation objet + $object=new AdherentType($db); + $object->initAsSpecimen(); + + // Test synchro + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPES'); + } + + $result1=$ldap->delete($dn); // To be sure to delete existing records + $result2=$ldap->add($dn,$info,$user); // Now the test + $result3=$ldap->delete($dn); // Clean what we did + + if ($result2 > 0) + { + print img_picto('','info').' '; + print ''.$langs->trans("LDAPSynchroOK").'
'; + } + else + { + print img_picto('','error').' '; + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ': '.$ldap->error; + print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; + } + + print "
\n"; + print "LDAP input file used for test:

\n"; + print nl2br($ldap->dump_content($dn,$info)); + print "\n
"; + } + else + { + print img_picto('','error').' '; + print ''.$langs->trans("LDAPSynchroKO"); + print ': '.$ldap->error; + print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; + } + } +} + +llxFooter(); +$db->close(); diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index 88a91feb083..52ac09074f3 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -78,23 +78,35 @@ if (preg_match('/del_(.*)/',$action,$reg)) if ($action == 'add_currency') { + $error=0; + $langs->loadCacheCurrencies(''); $code = GETPOST('code', 'alpha'); - $rate = GETPOST('rate', 'alpha'); + $rate = price2num(GETPOST('rate', 'alpha')); $currency = new MultiCurrency($db); $currency->code = $code; $currency->name = !empty($langs->cache_currencies[$code]['label']) ? $langs->cache_currencies[$code]['label'].' ('.$langs->getCurrencySymbol($code).')' : $code; - if ($currency->create($user) > 0) + if (empty($rate)) { - if ($currency->addRate($rate)) setEventMessages($langs->trans('RecordSaved'), array()); - else setEventMessages($langs->trans('ErrorAddRateFail'), array(), 'errors'); + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Rate")), null, 'errors'); + $error++; + } + if (! $error) + { + if ($currency->create($user) > 0) + { + if ($currency->addRate($rate)) setEventMessages($langs->trans('RecordSaved'), array()); + else setEventMessages($langs->trans('ErrorAddRateFail'), array(), 'errors'); + } + else setEventMessages($langs->trans('ErrorAddCurrencyFail'), $currency->errors, 'errors'); } - else setEventMessages($langs->trans('ErrorAddCurrencyFail'), $currency->errors, 'errors'); } elseif ($action == 'update_currency') { + $error = 0; + $submit = GETPOST('submit', 'alpha'); if ($submit == $langs->trans('Modify')) @@ -103,9 +115,17 @@ elseif ($action == 'update_currency') $rate = price2num(GETPOST('rate', 'alpha')); $currency = new MultiCurrency($db); - if ($currency->fetch($fk_multicurrency) > 0) + if (empty($rate)) { - $currency->updateRate($rate); + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Rate")), null, 'errors'); + $error++; + } + if (! $error) + { + if ($currency->fetch($fk_multicurrency) > 0) + { + $currency->updateRate($rate); + } } } elseif ($submit == $langs->trans('Delete')) @@ -279,7 +299,6 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print ''; print ''; - print ''; print ''.$langs->transnoentitiesnoconv("multicurrency_alternateCurrencySource").''; print ' '; @@ -325,8 +344,7 @@ print ''; foreach ($TCurrency as &$currency) { - if($currency->code == $conf->currency) continue; - + if ($currency->code == $conf->currency) continue; print ''; print ''.$currency->code.' - '.$currency->name.''; diff --git a/htdocs/api/class/api_dictionary.class.php b/htdocs/api/class/api_dictionary.class.php new file mode 100644 index 00000000000..93f16d44377 --- /dev/null +++ b/htdocs/api/class/api_dictionary.class.php @@ -0,0 +1,452 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +use Luracast\Restler\RestException; + +require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; + +/** + * API class for payment type (content of the paiement dictionary) + * + * @access protected + * @class DolibarrApiAccess {@requires user,external} + */ +class Dictionary extends DolibarrApi +{ + private $translations = null; + + /** + * Constructor + */ + function __construct() + { + global $db; + $this->db = $db; + } + + /** + * Get the list of payments types. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number {@min 0} + * @param int $active Payment type is active or not {@min 0} {@max 1} + * @param string $sqlfilters SQL criteria to filter. Syntax example "(t.code:=:'CHQ')" + * + * @url GET payments + * + * @return List of payment types + * + * @throws RestException + */ + function getPaymentTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT id, code, type, libelle as label, module"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement as t"; + $sql.= " WHERE t.active = ".$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 payment types : '.$this->db->lasterror()); + } + + return $list; + } + + /** + * Get the list of countries. + * + * The names of the countries will be translated to the given language if + * the $lang parameter is provided. The value of $lang must be a language + * code supported by Dolibarr, for example 'en_US' or 'fr_FR'. + * The returned list is sorted by country ID. + * + * @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 $filter To filter the countries by name + * @param string $lang Code of the language the label of the countries must be translated to + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of countries + * + * @url GET countries + * + * @throws RestException + */ + function getListOfCountries($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '') + { + $list = array(); + + // Note: The filter is not applied in the SQL request because it must + // be applied to the translated names, not to the names in database. + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t"; + $sql.=" WHERE 1 = 1"; + // 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++) { + $obj = $this->db->fetch_object($result); + $country = new Ccountry($this->db); + if ($country->fetch($obj->rowid) > 0) { + // Translate the name of the country if needed + // and then apply the filter if there is one. + $this->translateLabel($country, $lang); + + if (empty($filter) || stripos($country->label, $filter) !== FALSE) { + $list[] = $this->_cleanObjectDatas($country); + } + } + } + } else { + throw new RestException(503, 'Error when retrieving list of countries : '.$country->error); + } + + return $list; + } + + /** + * Get country by ID. + * + * @param int $id ID of country + * @param string $lang Code of the language the name of the + * country must be translated to + * + * @url GET countries/{id} + * + * @throws RestException + */ + function getCountryByID($id, $lang = '') + { + $country = new Ccountry($this->db); + + if ($country->fetch($id) < 0) { + throw new RestException(503, 'Error when retrieving country : '.$country->error); + } + else if ($country->fetch($id) == 0) { + throw new RestException(404, 'country not found'); + } + + $this->translateLabel($country, $lang); + + return $this->_cleanObjectDatas($country); + } + + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) + { + $object = parent::_cleanObjectDatas($object); + + unset($object->error); + unset($object->errors); + + return $object; + } + + /** + * Translate the name of the country to the given language. + * + * @param Ccountry $country Country + * @param string $lang Code of the language the name of the + * country must be translated to + */ + private function translateLabel($country, $lang) + { + if (!empty($lang)) { + // Load the translations if this is a new language. + if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) { + global $conf; + $this->translations = new Translate('', $conf); + $this->translations->setDefaultLang($lang); + $this->translations->load('dict'); + } + if ($country->code) { + $key = 'Country'.$country->code; + $translation = $this->translations->trans($key); + if ($translation != $key) { + $country->label = html_entity_decode($translation); + } + } + } + } + + /** + * Get the list of events types. + * + * @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 $type To filter on type of event + * @param string $module To filter on module events + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of events types + * + * @url GET events + * + * @throws RestException + */ + function getListOfEvents($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT id, code, type, libelle as label, module"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t"; + $sql.= " WHERE t.active = 1"; + if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'"; + if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'"; + // 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 events types : '.$this->db->lasterror()); + } + + return $list; + } + + + /** + * Get the list of extra fields. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param string $type Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...) + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%')" + * @return List of events types + * + * @url GET extrafields + * + * @throws RestException + */ + function getListOfExtrafields($sortfield = "t.pos", $sortorder = 'ASC', $type = '', $sqlfilters = '') + { + $list = array(); + + if ($type == 'thirdparty') $type='societe'; + if ($type == 'contact') $type='socpeople'; + + $sql = "SELECT t.rowid, t.name, t.label, t.type, t.size, t.elementtype, t.fieldunique, t.fieldrequired, t.param, t.pos, t.alwayseditable, t.perms, t.list, t.ishidden, t.fielddefault, t.fieldcomputed"; + $sql.= " FROM ".MAIN_DB_PREFIX."extrafields as t"; + $sql.= " WHERE t.entity IN (".getEntity('extrafields').")"; + if (! empty($type)) $sql.= " AND t.elementtype = '".$this->db->escape($type)."'"; + // 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); + + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + while ($tab = $this->db->fetch_object($resql)) + { + // New usage + $list[$tab->elementtype][$tab->name]['type']=$tab->type; + $list[$tab->elementtype][$tab->name]['label']=$tab->label; + $list[$tab->elementtype][$tab->name]['size']=$tab->size; + $list[$tab->elementtype][$tab->name]['elementtype']=$tab->elementtype; + $list[$tab->elementtype][$tab->name]['default']=$tab->fielddefault; + $list[$tab->elementtype][$tab->name]['computed']=$tab->fieldcomputed; + $list[$tab->elementtype][$tab->name]['unique']=$tab->fieldunique; + $list[$tab->elementtype][$tab->name]['required']=$tab->fieldrequired; + $list[$tab->elementtype][$tab->name]['param']=($tab->param ? unserialize($tab->param) : ''); + $list[$tab->elementtype][$tab->name]['pos']=$tab->pos; + $list[$tab->elementtype][$tab->name]['alwayseditable']=$tab->alwayseditable; + $list[$tab->elementtype][$tab->name]['perms']=$tab->perms; + $list[$tab->elementtype][$tab->name]['list']=$tab->list; + $list[$tab->elementtype][$tab->name]['ishidden']=$tab->ishidden; + } + } + } + else + { + throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror()); + } + + if (! count($list)) + { + throw new RestException(404, 'No extrafield found'); + } + + return $list; + } + + + /** + * Get the list of towns. + * + * @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 $zipcode To filter on zipcode + * @param string $town To filter on city name + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of towns + * + * @url GET towns + * + * @throws RestException + */ + function getListOfTowns($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown as t"; + $sql.= " WHERE t.active = 1"; + if ($zipcode) $sql.=" AND t.zip LIKE '%" . $this->db->escape($zipcode) . "%'"; + if ($town) $sql.=" AND t.town LIKE '%" . $this->db->escape($town) . "%'"; + // 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 towns : '.$this->db->lasterror()); + } + + return $list; + } + +} diff --git a/htdocs/api/class/api_dictionarycountries.class.php b/htdocs/api/class/api_dictionarycountries.class.php deleted file mode 100644 index 070be509a8a..00000000000 --- a/htdocs/api/class/api_dictionarycountries.class.php +++ /dev/null @@ -1,184 +0,0 @@ - - * Copyright (C) 2016 Laurent Destailleur - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; - -/** - * API class for countries - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryCountries extends DolibarrApi -{ - private $translations = null; - - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of countries. - * - * The names of the countries will be translated to the given language if - * the $lang parameter is provided. The value of $lang must be a language - * code supported by Dolibarr, for example 'en_US' or 'fr_FR'. - * The returned list is sorted by country ID. - * - * @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 $filter To filter the countries by name - * @param string $lang Code of the language the label of the countries must be translated to - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of countries - * - * @throws RestException - */ - function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '') - { - $list = array(); - - // Note: The filter is not applied in the SQL request because it must - // be applied to the translated names, not to the names in database. - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t"; - $sql.=" WHERE 1 = 1"; - // 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++) { - $obj = $this->db->fetch_object($result); - $country = new Ccountry($this->db); - if ($country->fetch($obj->rowid) > 0) { - // Translate the name of the country if needed - // and then apply the filter if there is one. - $this->translateLabel($country, $lang); - - if (empty($filter) || stripos($country->label, $filter) !== FALSE) { - $list[] = $this->_cleanObjectDatas($country); - } - } - } - } else { - throw new RestException(503, 'Error when retrieving list of countries : '.$country->error); - } - - return $list; - } - - /** - * Get country by ID. - * - * @param int $id ID of country - * @param string $lang Code of the language the name of the - * country must be translated to - * - * @throws RestException - */ - function get($id, $lang = '') - { - $country = new Ccountry($this->db); - - if ($country->fetch($id) < 0) { - throw new RestException(503, 'Error when retrieving country : '.$country->error); - } - else if ($country->fetch($id) == 0) { - throw new RestException(404, 'country not found'); - } - - $this->translateLabel($country, $lang); - - return $this->_cleanObjectDatas($country); - } - - /** - * Clean sensible object datas - * - * @param object $object Object to clean - * @return array Array of cleaned object properties - */ - function _cleanObjectDatas($object) - { - $object = parent::_cleanObjectDatas($object); - - unset($object->error); - unset($object->errors); - - return $object; - } - - /** - * Translate the name of the country to the given language. - * - * @param Ccountry $country Country - * @param string $lang Code of the language the name of the - * country must be translated to - */ - private function translateLabel($country, $lang) - { - if (!empty($lang)) { - // Load the translations if this is a new language. - if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) { - global $conf; - $this->translations = new Translate('', $conf); - $this->translations->setDefaultLang($lang); - $this->translations->load('dict'); - } - if ($country->code) { - $key = 'Country'.$country->code; - $translation = $this->translations->trans($key); - if ($translation != $key) { - $country->label = html_entity_decode($translation); - } - } - } - } -} diff --git a/htdocs/api/class/api_dictionaryevents.class.php b/htdocs/api/class/api_dictionaryevents.class.php deleted file mode 100644 index 23d7e8e5dba..00000000000 --- a/htdocs/api/class/api_dictionaryevents.class.php +++ /dev/null @@ -1,100 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; - -/** - * API class for events type (content of the actioncomm dictionary) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryEvents extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of events types. - * - * @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 $type To filter on type of event - * @param string $module To filter on module events - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of events types - * - * @throws RestException - */ - function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '') - { - $list = array(); - - $sql = "SELECT id, code, type, libelle as label, module"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t"; - $sql.= " WHERE t.active = 1"; - if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'"; - if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'"; - // 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 events types : '.$this->db->lasterror()); - } - - return $list; - } - -} diff --git a/htdocs/api/class/api_dictionaryextrafields.class.php b/htdocs/api/class/api_dictionaryextrafields.class.php deleted file mode 100644 index 69f574797c7..00000000000 --- a/htdocs/api/class/api_dictionaryextrafields.class.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use Luracast\Restler\RestException; - -//require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; - -/** - * API class for extra fields (content of the extrafields) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryExtraFields extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of extra fields. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param string $type Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...) - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%')" - * @return List of events types - * - * @throws RestException - */ - function index($sortfield = "t.pos", $sortorder = 'ASC', $type = '', $sqlfilters = '') - { - $list = array(); - - if ($type == 'thirdparty') $type='societe'; - if ($type == 'contact') $type='socpeople'; - - $sql = "SELECT t.rowid, t.name, t.label, t.type, t.size, t.elementtype, t.fieldunique, t.fieldrequired, t.param, t.pos, t.alwayseditable, t.perms, t.list, t.ishidden, t.fielddefault, t.fieldcomputed"; - $sql.= " FROM ".MAIN_DB_PREFIX."extrafields as t"; - $sql.= " WHERE t.entity IN (".getEntity('extrafields').")"; - if (! empty($type)) $sql.= " AND t.elementtype = '".$this->db->escape($type)."'"; - // 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); - - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - while ($tab = $this->db->fetch_object($resql)) - { - // New usage - $list[$tab->elementtype][$tab->name]['type']=$tab->type; - $list[$tab->elementtype][$tab->name]['label']=$tab->label; - $list[$tab->elementtype][$tab->name]['size']=$tab->size; - $list[$tab->elementtype][$tab->name]['elementtype']=$tab->elementtype; - $list[$tab->elementtype][$tab->name]['default']=$tab->fielddefault; - $list[$tab->elementtype][$tab->name]['computed']=$tab->fieldcomputed; - $list[$tab->elementtype][$tab->name]['unique']=$tab->fieldunique; - $list[$tab->elementtype][$tab->name]['required']=$tab->fieldrequired; - $list[$tab->elementtype][$tab->name]['param']=($tab->param ? unserialize($tab->param) : ''); - $list[$tab->elementtype][$tab->name]['pos']=$tab->pos; - $list[$tab->elementtype][$tab->name]['alwayseditable']=$tab->alwayseditable; - $list[$tab->elementtype][$tab->name]['perms']=$tab->perms; - $list[$tab->elementtype][$tab->name]['list']=$tab->list; - $list[$tab->elementtype][$tab->name]['ishidden']=$tab->ishidden; - } - } - } - else - { - throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror()); - } - - if (! count($list)) - { - throw new RestException(404, 'No extrafield found'); - } - - return $list; - } - -} diff --git a/htdocs/api/class/api_dictionarytowns.class.php b/htdocs/api/class/api_dictionarytowns.class.php deleted file mode 100644 index 0ebcfbe0b17..00000000000 --- a/htdocs/api/class/api_dictionarytowns.class.php +++ /dev/null @@ -1,102 +0,0 @@ - - * Copyright (C) 2016 Laurent Destailleur - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; - -/** - * API class for towns (content of the ziptown dictionary) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryTowns extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of towns. - * - * @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 $zipcode To filter on zipcode - * @param string $town To filter on city name - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of towns - * - * @throws RestException - */ - function index($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $sqlfilters = '') - { - $list = array(); - - $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown as t"; - $sql.= " WHERE t.active = 1"; - if ($zipcode) $sql.=" AND t.zip LIKE '%" . $this->db->escape($zipcode) . "%'"; - if ($town) $sql.=" AND t.town LIKE '%" . $this->db->escape($town) . "%'"; - // 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 towns : '.$this->db->lasterror()); - } - - return $list; - } - -} diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 02a16af3c17..78e580a4318 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -771,9 +771,9 @@ if ($action == 'create') $events[]=array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1',1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled')); //For external user force the company to user company if (!empty($user->societe_id)) { - print $form->select_thirdparty_list($user->societe_id, 'socid', '', 1, 1, 0, $events); + print $form->select_company($user->societe_id, 'socid', '', 1, 1, 0, $events); } else { - print $form->select_thirdparty_list('', 'socid', '', 'SelectThirdParty', 1, 0, $events); + print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, $events); } } @@ -781,7 +781,7 @@ if ($action == 'create') // Related contact print ''.$langs->trans("ActionOnContact").''; - $form->select_contacts(GETPOST('socid','int'), GETPOST('contactid'), 'contactid', 1, '', '', 0, 'minwidth200'); + $form->selectcontacts(GETPOST('socid','int'), GETPOST('contactid'), 'contactid', 1, '', '', 0, 'minwidth200'); print ''; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index cd51b0f9fa6..316227cbe42 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1404,7 +1404,7 @@ class Propal extends CommonObject { $this->lines=array(); - $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; + $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; $sql.= ' d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,'; $sql.= ' d.fk_unit,'; $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,'; @@ -1443,6 +1443,8 @@ class Propal extends CommonObject $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; $line->subprice = $objp->subprice; $line->fk_remise_except = $objp->fk_remise_except; $line->remise_percent = $objp->remise_percent; @@ -3366,8 +3368,8 @@ class Propal extends CommonObject $this->lines = array(); $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,'; - $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.remise_percent, pt.subprice, pt.info_bits,'; - $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,'; + $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.localtax1_type, pt.localtax2_type, pt.remise_percent, pt.subprice, pt.info_bits,'; + $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.total_localtax1, pt.total_localtax2, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code,'; $sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,'; $sql.= ' pt.fk_unit,'; $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,'; @@ -3411,11 +3413,17 @@ class Propal extends CommonObject $this->lines[$i]->vat_src_code = $obj->vat_src_code; $this->lines[$i]->tva_tx = $obj->tva_tx; + $this->lines[$i]->localtax1_tx = $obj->localtax1_tx; + $this->lines[$i]->localtax2_tx = $obj->localtax2_tx; + $this->lines[$i]->localtax1_type = $obj->localtax1_type; + $this->lines[$i]->localtax2_type = $obj->localtax2_type; $this->lines[$i]->info_bits = $obj->info_bits; $this->lines[$i]->total_ht = $obj->total_ht; $this->lines[$i]->total_tva = $obj->total_tva; $this->lines[$i]->total_ttc = $obj->total_ttc; - $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; + $this->lines[$i]->total_localtax1 = $obj->total_localtax1; + $this->lines[$i]->total_localtax2 = $obj->total_localtax2; + $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht); $this->lines[$i]->pa_ht = $marginInfos[0]; $this->lines[$i]->marge_tx = $marginInfos[1]; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 53082499a9a..5da8423c0a2 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2492,7 +2492,7 @@ if ($action == 'create' && $user->rights->commande->creer) if (! empty($conf->expedition->enabled)) { $numshipping = $object->nb_expedition(); - if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfProductsLines() > 0) { + if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES))) { if (($conf->expedition_bon->enabled && $user->rights->expedition->creer) || ($conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer)) { if ($user->rights->expedition->creer) { print ''; diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index 986fdc9db03..acd8ab93aef 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -104,9 +104,9 @@ if (! $sortfield) $sortfield='b.datev, b.dateo, b.rowid'; $mode_balance_ok=false; //if (($sortfield == 'b.datev' || $sortfield == 'b.datev, b.dateo, b.rowid')) // TODO Manage balance when account not selected -if (($sortfield == 'b.datev' || $sortfield == 'b.datev, b.dateo, b.rowid')) +if (($sortfield == 'b.datev' || $sortfield == 'b.datev,b.dateo,b.rowid')) { - $sortfield = 'b.datev, b.dateo, b.rowid'; + $sortfield = 'b.datev,b.dateo,b.rowid'; if ($id > 0 || ! empty($ref) || $account > 0) $mode_balance_ok = true; } if (strtolower($sortorder) == 'desc') $mode_balance_ok = false; @@ -887,7 +887,7 @@ if ($resql) if (! empty($arrayfields['b.rowid']['checked'])) print_liste_field_titre($arrayfields['b.rowid']['label'],$_SERVER['PHP_SELF'],'b.rowid','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['description']['checked'])) print_liste_field_titre($arrayfields['description']['label'],$_SERVER['PHP_SELF'],'','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.dateo']['checked'])) print_liste_field_titre($arrayfields['b.dateo']['label'],$_SERVER['PHP_SELF'],'b.dateo','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev, b.dateo, b.rowid','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev,b.dateo,b.rowid','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['type']['checked'])) print_liste_field_titre($arrayfields['type']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['b.num_chq']['checked'])) print_liste_field_titre($arrayfields['b.num_chq']['label'],$_SERVER['PHP_SELF'],'b.num_chq','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['bu.label']['checked'])) print_liste_field_titre($arrayfields['bu.label']['label'],$_SERVER['PHP_SELF'],'bu.label','',$param,'',$sortfield,$sortorder); @@ -1065,7 +1065,7 @@ if ($resql) $bankstatic->id=$banklinestatic->fk_account; $bankstatic->label=$banklinestatic->bank_account_ref; print ' ('.$langs->trans("TransferFrom").' '; - print $bankstatic->getNomUrl(1,'transactions'); + print $bankstatic->getNomUrl(1); print ' '.$langs->trans("toward").' '; $bankstatic->id=$objp->bankid; $bankstatic->label=$objp->bankref; @@ -1082,7 +1082,7 @@ if ($resql) $banklinestatic->fetch($links[$key]['url_id']); $bankstatic->id=$banklinestatic->fk_account; $bankstatic->label=$banklinestatic->bank_account_ref; - print $bankstatic->getNomUrl(1,'transactions'); + print $bankstatic->getNomUrl(1); print ')'; } //var_dump($links); diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 9be1aab246b..881616ebc45 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -926,7 +926,8 @@ class Account extends CommonObject } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; + $this->errors[]=$this->error; return -1; } } diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 5a0ab062b29..4485680a4e9 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -92,7 +92,8 @@ $arrayfields=array( 'b.account_number'=>array('label'=>$langs->trans("AccountAccounting"), 'checked'=>$conf->accountancy->enabled), 'b.fk_accountancy_journal'=>array('label'=>$langs->trans("AccountancyJournal"), 'checked'=>$conf->accountancy->enabled), 'toreconcile'=>array('label'=>$langs->trans("TransactionsToConciliate"), 'checked'=>1), - 'b.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 'b.currency_code'=>array('label'=>$langs->trans("Currency"), 'checked'=>0), + 'b.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'b.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), 'b.clos'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), 'balance'=>array('label'=>$langs->trans("Balance"), 'checked'=>1, 'position'=>1010), @@ -121,7 +122,7 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; // Purge search criteria -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { $search_ref=''; $search_label=''; @@ -142,7 +143,7 @@ $title=$langs->trans('BankAccounts'); // Load array of financial accounts (opened by default) $accounts = array(); -$sql = "SELECT rowid, label, courant, rappro, account_number, fk_accountancy_journal, datec as date_creation, tms as date_update"; +$sql = "SELECT rowid, label, courant, rappro, account_number, fk_accountancy_journal, currency_code, datec as date_creation, tms as date_update"; // Add fields from extrafields foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); // Add fields from hooks @@ -337,6 +338,12 @@ if (! empty($arrayfields['toreconcile']['checked'])) print ''; print ''; } +// Currency +if (! empty($arrayfields['b.currency_code']['checked'])) +{ + print ''; + print ''; +} // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { @@ -407,6 +414,7 @@ if (! empty($arrayfields['accountype']['checked'])) print_liste_field_titr if (! empty($arrayfields['b.number']['checked'])) print_liste_field_titre($arrayfields['b.number']['label'],$_SERVER["PHP_SELF"],'b.number','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.account_number']['checked'])) print_liste_field_titre($arrayfields['b.account_number']['label'],$_SERVER["PHP_SELF"],'b.account_number','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.fk_accountancy_journal']['checked'])) print_liste_field_titre($arrayfields['b.fk_accountancy_journal']['label'],$_SERVER["PHP_SELF"],'b.fk_accountancy_journal','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.currency_code']['checked'])) print_liste_field_titre($arrayfields['b.currency_code']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['toreconcile']['checked'])) print_liste_field_titre($arrayfields['toreconcile']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -442,19 +450,19 @@ foreach ($accounts as $key=>$type) $found++; - $acc = new Account($db); - $acc->fetch($key); + $obj = new Account($db); + $obj->fetch($key); $var = !$var; - $solde = $acc->solde(1); + $solde = $obj->solde(1); - if (! empty($lastcurrencycode) && $lastcurrencycode != $acc->currency_code) + if (! empty($lastcurrencycode) && $lastcurrencycode != $obj->currency_code) { $lastcurrencycode='various'; // We found several different currencies } if ($lastcurrencycode != 'various') { - $lastcurrencycode=$acc->currency_code; + $lastcurrencycode=$obj->currency_code; } print ''; @@ -462,14 +470,14 @@ foreach ($accounts as $key=>$type) // Ref if (! empty($arrayfields['b.ref']['checked'])) { - print ''.$acc->getNomUrl(1).''; + print ''.$obj->getNomUrl(1).''; if (! $i) $totalarray['nbfield']++; } // Label if (! empty($arrayfields['b.label']['checked'])) { - print ''.$acc->label.''; + print ''.$obj->label.''; if (! $i) $totalarray['nbfield']++; } @@ -477,7 +485,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['accountype']['checked'])) { print ''; - print $acc->type_lib[$acc->type]; + print $obj->type_lib[$obj->type]; print ''; if (! $i) $totalarray['nbfield']++; } @@ -485,7 +493,7 @@ foreach ($accounts as $key=>$type) // Number if (! empty($arrayfields['b.number']['checked'])) { - print ''.$acc->number.''; + print ''.$obj->number.''; if (! $i) $totalarray['nbfield']++; } @@ -496,12 +504,12 @@ foreach ($accounts as $key=>$type) if (! empty($conf->accounting->enabled)) { $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('',$acc->account_number); + $accountingaccount->fetch('',$obj->account_number); print $accountingaccount->getNomUrl(0,1,1,'',1); } else { - print $acc->account_number; + print $obj->account_number; } print ''; if (! $i) $totalarray['nbfield']++; @@ -514,7 +522,7 @@ foreach ($accounts as $key=>$type) if (! empty($conf->accounting->enabled)) { $accountingjournal = new AccountingJournal($db); - $accountingjournal->fetch($acc->fk_accountancy_journal); + $accountingjournal->fetch($obj->fk_accountancy_journal); print $accountingjournal->getNomUrl(0,1,1,'',1); } else @@ -525,15 +533,24 @@ foreach ($accounts as $key=>$type) if (! $i) $totalarray['nbfield']++; } + // Currency + if (! empty($arrayfields['b.currency_code']['checked'])) + { + print ''; + print $obj->currency_code; + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Transactions to reconcile if (! empty($arrayfields['toreconcile']['checked'])) { print ''; - if ($acc->rappro) + if ($obj->rappro) { - $result=$acc->load_board($user,$acc->id); + $result=$obj->load_board($user,$obj->id); if ($result<0) { - setEventMessages($acc->error, $acc->errors, 'errors'); + setEventMessages($obj->error, $obj->errors, 'errors'); } else { print $result->nbtodo; if ($result->nbtodolate) print '   ('.$result->nbtodolate.img_warning($langs->trans("Late")).')'; @@ -570,7 +587,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['b.datec']['checked'])) { print ''; - print dol_print_date($acc->date_creation, 'dayhour'); + print dol_print_date($obj->date_creation, 'dayhour'); print ''; if (! $i) $totalarray['nbfield']++; } @@ -578,7 +595,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['b.tms']['checked'])) { print ''; - print dol_print_date($acc->date_update, 'dayhour'); + print dol_print_date($obj->date_update, 'dayhour'); print ''; if (! $i) $totalarray['nbfield']++; } @@ -586,7 +603,7 @@ foreach ($accounts as $key=>$type) // Status if (! empty($arrayfields['b.clos']['checked'])) { - print ''.$acc->getLibStatut(5).''; + print ''.$obj->getLibStatut(5).''; if (! $i) $totalarray['nbfield']++; } @@ -594,7 +611,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['balance']['checked'])) { print ''; - print ''.price($solde, 0, $langs, 0, 0, -1, $acc->currency_code).''; + print ''.price($solde, 0, $langs, 0, 0, -1, $obj->currency_code).''; print ''; if (! $i) $totalarray['nbfield']++; if (! $i) $totalarray['totalbalancefield']=$totalarray['nbfield']; @@ -614,7 +631,7 @@ foreach ($accounts as $key=>$type) print ''; - $total[$acc->currency_code] += $solde; + $total[$obj->currency_code] += $solde; $i++; } diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php index 1f3ca1cde8e..7696427b059 100644 --- a/htdocs/compta/bank/transfer.php +++ b/htdocs/compta/bank/transfer.php @@ -30,8 +30,7 @@ require('../../main.inc.php'); require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; -$langs->load("banks"); -$langs->load("categories"); +$langs->loadLangs(array("banks", "categories", "multicurrency")); if (! $user->rights->banque->transfer) accessforbidden(); @@ -44,14 +43,14 @@ $error = 0; * Actions */ -if ($action == 'add_confirm') +if ($action == 'add') { $langs->load("errors"); $dateo = dol_mktime(12,0,0,GETPOST('remonth','int'),GETPOST('reday','int'),GETPOST('reyear','int')); $label = GETPOST('label','alpha'); $amount= GETPOST('amount'); - $amount_to= GETPOST('amount_to'); + $amountto= GETPOST('amountto'); if (! $label) { @@ -83,7 +82,17 @@ if ($action == 'add_confirm') $accountto=new Account($db); $accountto->fetch(GETPOST('account_to','int')); - if ($accountto->id != $accountfrom->id) + if ($accountto->currency_code == $accountfrom->currency_code) { + $amountto=$amount; + } else { + if (! $amountto) + { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AmountTo")), null, 'errors'); + } + } + + if (($accountto->id != $accountfrom->id) && empty($error)) { $db->begin(); @@ -103,8 +112,7 @@ if ($action == 'add_confirm') if (! $error) $bank_line_id_from = $accountfrom->addline($dateo, $typefrom, $label, -1*price2num($amount), '', '', $user); if (! ($bank_line_id_from > 0)) $error++; - if ((! $error) && ($accountto->currency_code == $accountfrom->currency_code)) $bank_line_id_to = $accountto->addline($dateo, $typeto, $label, price2num($amount), '', '', $user); - if ((! $error) && ($accountto->currency_code != $accountfrom->currency_code)) $bank_line_id_to = $accountto->addline($dateo, $typeto, $label, price2num($amount_to), '', '', $user); + if (! $error) $bank_line_id_to = $accountto->addline($dateo, $typeto, $label, price2num($amountto), '', '', $user); if (! ($bank_line_id_to > 0)) $error++; if (! $error) $result=$accountfrom->add_url_line($bank_line_id_from, $bank_line_id_to, DOL_URL_ROOT.'/compta/bank/ligne.php?rowid=', '(banktransfert)', 'banktransfert'); @@ -114,7 +122,7 @@ if ($action == 'add_confirm') if (! $error) { - $mesgs = $langs->trans("TransferFromToDone","id."\">".$accountfrom->label."","id."\">".$accountto->label."",$amount,$langs->transnoentities("Currency".$conf->currency)); + $mesgs = $langs->trans("TransferFromToDone",''.$accountfrom->label."",''.$accountto->label."",$amount,$langs->transnoentities("Currency".$conf->currency)); setEventMessages($mesgs, null, 'mesgs'); $db->commit(); } @@ -139,6 +147,58 @@ if ($action == 'add_confirm') */ llxHeader(); +print ' '; $form=new Form($db); @@ -146,9 +206,8 @@ $account_from=''; $account_to=''; $label=''; $amount=''; -$amount_to=''; -if ($error) +if($error) { $account_from = GETPOST('account_from','int'); $account_to = GETPOST('account_to','int'); @@ -164,21 +223,21 @@ print "

"; print '
'; print ''; -print ''; +print ''; print ''; print ''; -print ''; -print ''; +print ''; +print ''; print ''; $var=false; print '"; print "\n"; print "\n"; print ''; print ''; +print ''; + print "
'.$langs->trans("TransferFrom").''.$langs->trans("TransferTo").''.$langs->trans("Date").''.$langs->trans("Description").''.$langs->trans("Amount").''.$langs->trans("TransferFrom").''.$langs->trans("TransferTo").''.$langs->trans("Date").''.$langs->trans("Description").''.$langs->trans("Amount").'
'; -$form->select_comptes($account_from,'account_from',0,'',1); +$form->select_comptes($account_from, 'account_from', 0, '', 1, '', empty($conf->multicurrency->enabled)?0:1); print "\n"; -$form->select_comptes($account_to,'account_to',0,'',1); +$form->select_comptes($account_to, 'account_to', 0, '', 1, '', empty($conf->multicurrency->enabled)?0:1); print ""; @@ -186,6 +245,8 @@ $form->select_date((! empty($dateo)?$dateo:''),'','','','','add'); print "
"; print '
'; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 76f49a22c04..7fb0b86a39a 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -604,27 +604,30 @@ if (empty($reshook)) $ventilExportCompta = $object->getVentilExportCompta(); // On verifie si aucun paiement n'a ete effectue - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + if ($ventilExportCompta == 0) { - $result=$object->set_draft($user, $idwarehouse); - if ($result<0) setEventMessages($object->error, $object->errors, 'errors'); - - - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_EDITED) || ($resteapayer == $object->total_ttc && empty($object->paye))) { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records + $result=$object->set_draft($user, $idwarehouse); + if ($result<0) setEventMessages($object->error, $object->errors, 'errors'); - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } } } } @@ -1440,7 +1443,7 @@ if (empty($reshook)) $object->situation_counter = $object->situation_counter + 1; $id = $object->createFromCurrent($user); - if ($id <= 0) + if ($id <= 0) { $mesg = $object->error; } @@ -4120,28 +4123,35 @@ else if ($id > 0 || ! empty($ref)) $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { // Editer une facture deja validee, sans paiement effectue et pas exporte en compta - if ($object->statut == 1) + if ($object->statut == Facture::STATUS_VALIDATED) { // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees $ventilExportCompta = $object->getVentilExportCompta(); - if ($resteapayer == $object->total_ttc && empty($object->paye) && $ventilExportCompta == 0) + if ($ventilExportCompta == 0) { - if (! $objectidnext && $object->is_last_in_cycle()) + if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_EDITED) || ($resteapayer == $object->total_ttc && empty($object->paye))) { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate))) + if (! $objectidnext && $object->is_last_in_cycle()) { - print ''; + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate))) + { + print ''; + } else { + print '
' . $langs->trans('Modify') . '
'; + } + } else if (!$object->is_last_in_cycle()) { + print '
' . $langs->trans('Modify') . '
'; } else { - print '
' . $langs->trans('Modify') . '
'; + print '
' . $langs->trans('Modify') . '
'; } - } else if (!$object->is_last_in_cycle()) { - print '
' . $langs->trans('Modify') . '
'; - } else { - print '
' . $langs->trans('Modify') . '
'; } } + else + { + print '
' . $langs->trans('Modify') . '
'; + } } $discount = new DiscountAbsolute($db); @@ -4163,7 +4173,7 @@ else if ($id > 0 || ! empty($ref)) } // Validate - if ($object->statut == 0 && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { + if ($object->statut == Facture::STATUS_DRAFT && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->validate))) { diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 35f84f8e823..d4a68b29ef6 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1059,13 +1059,20 @@ class Facture extends CommonInvoice */ function getDirectExternalLink($withpicto=0) { + global $dolibarr_main_url_root; + // Define $urlwithroot $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - $url='eee'; - return ''.$this->ref.''; + // TODO Read into ecmfile table to get entry and hash exists (PS: If not found, add it) + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($this->db); + //$result = $ecmfile->get(); + + $hashp='todo'; + return ''.$this->ref.''; } /** diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 5a59b61e8a3..d6ffc854844 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -95,8 +95,10 @@ $month_lim = GETPOST('month_lim','int'); $year_lim = GETPOST('year_lim','int'); $option = GETPOST('option'); -if ($option == 'late') $filter = 'paye:0'; -$filtre = GETPOST('filtre'); +if ($option == 'late') { + $search_status = '1'; +} +$filtre = GETPOST('filtre','alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); @@ -387,7 +389,7 @@ if ($search_user > 0) $sql.= ' WHERE f.fk_soc = s.rowid'; $sql.= ' AND f.entity IN ('.getEntity('facture').')'; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; -if ($search_product_category > 0) $sql.=" AND cp.fk_categorie = ".$search_product_category; +if ($search_product_category > 0) $sql.=" AND cp.fk_categorie = ".$db->escape($search_product_category); if ($socid > 0) $sql.= ' AND s.rowid = '.$socid; if ($userid) { @@ -400,7 +402,7 @@ if ($filtre) foreach ($aFilter as $filter) { $filt = explode(':', $filter); - $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); + $sql .= ' AND ' . $db->escape(trim($filt[0])) . ' = ' . $db->escape(trim($filt[1])); } } if ($search_ref) $sql .= natural_search('f.facnumber', $search_ref); @@ -434,7 +436,7 @@ if ($search_status != '' && $search_status >= 0) if ($search_status == '2') $sql.=" AND f.fk_statut = 2"; // payed Not that some corrupted data may contains f.fk_statut = 1 AND f.paye = 1 (it means payed too but should not happend. If yes, reopen and reclassify billed) if ($search_status == '3') $sql.=" AND f.fk_statut = 3"; // abandonned } -if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$search_paymentmode; +if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$db->escape($search_paymentmode); if ($month > 0) { if ($year > 0 && empty($day)) @@ -462,7 +464,6 @@ else if ($year_lim > 0) $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($year_lim,1,false))."' AND '".$db->idate(dol_get_last_day($year_lim,12,false))."'"; } if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->client->warning_delay)."'"; -if ($filter == 'paye:0') $sql.= " AND f.fk_statut = 1"; if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; if ($search_user > 0) { diff --git a/htdocs/contact/ldap.php b/htdocs/contact/ldap.php index 16c00bf92cb..759831f7d57 100644 --- a/htdocs/contact/ldap.php +++ b/htdocs/contact/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2012 Regis Houssin + * Copyright (C) 2006-2017 Regis Houssin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,7 +91,7 @@ $head = contact_prepare_head($object); dol_fiche_head($head, 'ldap', $title, -1, 'contact'); dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', ''); - + print '
'; print '
'; @@ -196,15 +196,11 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; - - - llxFooter(); - $db->close(); diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 69bda6f2b1c..61cd62bd338 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -790,7 +790,7 @@ class Contrat extends CommonObject } // Selectionne les lignes contrat liees a aucun produit - $sql = "SELECT d.rowid, d.fk_contrat, d.statut, d.qty, d.description, d.price_ht, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.rowid, d.remise_percent, d.subprice,"; + $sql = "SELECT d.rowid, d.fk_contrat, d.statut, d.qty, d.description, d.price_ht, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.rowid, d.remise_percent, d.subprice,"; $sql.= " d.total_ht,"; $sql.= " d.total_tva,"; $sql.= " d.total_localtax1,"; @@ -828,6 +828,8 @@ class Contrat extends CommonObject $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; $line->subprice = $objp->subprice; $line->remise_percent = $objp->remise_percent; $line->price_ht = $objp->price_ht; @@ -934,7 +936,7 @@ class Contrat extends CommonObject $sql.= " fk_commercial_signature, fk_commercial_suivi, fk_projet,"; $sql.= " ref, entity, note_private, note_public, ref_customer, ref_supplier, ref_ext)"; $sql.= " VALUES ('".$this->db->idate($now)."',".$this->socid.",".$user->id; - $sql.= ", '".$this->db->idate($this->date_contrat)."'"; + $sql.= ", ".(dol_strlen($this->date_contrat)!=0 ? "'".$this->db->idate($this->date_contrat)."'" : "NULL"); $sql.= ",".($this->commercial_signature_id>0?$this->commercial_signature_id:"NULL"); $sql.= ",".($this->commercial_suivi_id>0?$this->commercial_suivi_id:"NULL"); $sql.= ",".($this->fk_project>0?$this->fk_project:"NULL"); @@ -2711,6 +2713,8 @@ class ContratLigne extends CommonObjectLine $sql.= " t.vat_src_code,"; $sql.= " t.localtax1_tx,"; $sql.= " t.localtax2_tx,"; + $sql.= " t.localtax1_type,"; + $sql.= " t.localtax2_type,"; $sql.= " t.qty,"; $sql.= " t.remise_percent,"; $sql.= " t.remise,"; @@ -2764,6 +2768,8 @@ class ContratLigne extends CommonObjectLine $this->vat_src_code = $obj->vat_src_code; $this->localtax1_tx = $obj->localtax1_tx; $this->localtax2_tx = $obj->localtax2_tx; + $this->localtax1_type = $obj->localtax1_type; + $this->localtax2_type = $obj->localtax2_type; $this->qty = $obj->qty; $this->remise_percent = $obj->remise_percent; $this->remise = $obj->remise; diff --git a/htdocs/contrat/services.php b/htdocs/contrat/services.php index 9d1db86ded6..ddb19e3e88c 100644 --- a/htdocs/contrat/services.php +++ b/htdocs/contrat/services.php @@ -115,6 +115,11 @@ $companystatic=new Societe($db); $arrayfields=array( 'c.ref'=>array('label'=>$langs->trans("Contract"), 'checked'=>1, 'position'=>80), 'p.description'=>array('label'=>$langs->trans("Service"), 'checked'=>1, 'position'=>80), + 'cd.qty'=>array('label'=>$langs->trans("Qty"), 'checked'=>0, 'position'=>100), + 'cd.total_ht'=>array('label'=>$langs->trans("TotalHT"), 'checked'=>0, 'position'=>100), + 'cd.total_tva'=>array('label'=>$langs->trans("TotalVAT"), 'checked'=>0, 'position'=>100), + 'cd.tva_tx'=>array('label'=>$langs->trans("VAT"), 'checked'=>0, 'position'=>100), + 'cd.subprice'=>array('label'=>$langs->trans("PriceUHT"), 'checked'=>0, 'position'=>100), 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1, 'position'=>100), 'cd.date_ouverture_prevue'=>array('label'=>$langs->trans("DateStartPlannedShort"), 'checked'=>(($mode == "" || $mode == -1) || $mode == "0")), 'cd.date_ouverture'=>array('label'=>$langs->trans("DateStartRealShort"), 'checked'=>(($mode == "" || $mode == -1) || $mode > 0)), @@ -199,7 +204,11 @@ if (!$user->rights->societe->client->voir && !$socid) $sql .= " sc.fk_soc, sc.fk $sql.= " cd.date_ouverture_prevue,"; $sql.= " cd.date_ouverture,"; $sql.= " cd.date_fin_validite,"; -$sql.= " cd.date_cloture,"; +$sql.= " cd.qty,"; +$sql.= " cd.total_ht,"; +$sql.= " cd.total_tva,"; +$sql.= " cd.tva_tx,"; +$sql.= " cd.subprice,"; //$sql.= " cd.date_c as date_creation,"; $sql.= " cd.tms as date_update"; // Add fields from extrafields @@ -377,6 +386,11 @@ print ''; if (! empty($arrayfields['c.ref']['checked'])) print_liste_field_titre($arrayfields['c.ref']['label'],$_SERVER["PHP_SELF"],"c.ref","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['p.description']['checked'])) print_liste_field_titre($arrayfields['p.description']['label'],$_SERVER["PHP_SELF"],"p.description","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['cd.qty']['checked'])) print_liste_field_titre($arrayfields['cd.qty']['label'],$_SERVER["PHP_SELF"],"cd.qty","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.total_ht']['checked'])) print_liste_field_titre($arrayfields['cd.total_ht']['label'],$_SERVER["PHP_SELF"],"cd.total_ht","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.total_tva']['checked'])) print_liste_field_titre($arrayfields['cd.total_tva']['label'],$_SERVER["PHP_SELF"],"cd.total_tva","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.tva_tx']['checked'])) print_liste_field_titre($arrayfields['cd.tva_tx']['label'],$_SERVER["PHP_SELF"],"cd.tva_tx","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.subprice']['checked'])) print_liste_field_titre($arrayfields['cd.subprice']['label'],$_SERVER["PHP_SELF"],"cd.subprice","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['cd.date_ouverture_prevue']['checked'])) print_liste_field_titre($arrayfields['cd.date_ouverture_prevue']['label'],$_SERVER["PHP_SELF"],"cd.date_ouverture_prevue","",$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['cd.date_ouverture']['checked'])) print_liste_field_titre($arrayfields['cd.date_ouverture']['label'],$_SERVER["PHP_SELF"],"cd.date_ouverture","",$param,'align="center"',$sortfield,$sortorder); @@ -422,6 +436,32 @@ if (! empty($arrayfields['p.description']['checked'])) print ''; print ''; } +// detail lines +if (! empty($arrayfields['cd.qty']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.total_ht']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.total_tva']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.tva_tx']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.subprice']['checked'])) +{ + print ''; +} // Third party if (! empty($arrayfields['s.nom']['checked'])) { @@ -429,6 +469,8 @@ if (! empty($arrayfields['s.nom']['checked'])) print ''; print ''; } + + if (! empty($arrayfields['cd.date_ouverture_prevue']['checked'])) { print ''; } + if (! empty($arrayfields['cd.qty']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.total_ht']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.total_tva']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.tva_tx']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.subprice']['checked'])) + { + print ''; + } + + // Third party if (! empty($arrayfields['s.nom']['checked'])) { diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index e0acad65ab8..67fde5dbd48 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -540,7 +540,7 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se $filename=preg_replace('/\s/','_',$filename); // Save merged file - if ($filter=='paye:0') + if (in_array($object->element, array('facture', 'facture_fournisseur')) && $search_status == Facture::STATUS_VALIDATED) { if ($option=='late') $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))).'_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Late"))); else $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))); @@ -612,7 +612,7 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se $filename=preg_replace('/\s/','_',$filename); // Save merged file - if ($filter=='paye:0') + if (in_array($object->element, array('facture', 'facture_fournisseur')) && $search_status == Facture::STATUS_VALIDATED) { if ($option=='late') $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))).'_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Late"))); else $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))); diff --git a/htdocs/core/ajax/getaccountcurrency.php b/htdocs/core/ajax/getaccountcurrency.php new file mode 100644 index 00000000000..40e52672c0e --- /dev/null +++ b/htdocs/core/ajax/getaccountcurrency.php @@ -0,0 +1,60 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/ajax/vatrates.php + * \brief File to load vat rates combobox + */ + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Disables token renewal +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); + +require '../../main.inc.php'; + +$id = GETPOST('id','int'); + +/* + * View + */ + +top_httphead(); + +//print ''."\n"; + +// Load original field value +if (! empty($id)) +{ + require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + $account=new Account($db); + $result = $account->fetch($id); + if ($result<0) { + $return['value'] = ''; + $return['num'] = $result; + $return['error'] = $account->errors[0]; + } else { + $return['value'] = $account->currency_code; + $return['num'] = $result; + $return['error'] = ''; + } + + echo json_encode($return); +} + diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index 1795f7c6f2f..0cc4e68682b 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -2,6 +2,7 @@ /* Copyright (C) 2003 Rodolphe Quiedeville * Copyright (C) 2005-2017 Laurent Destailleur * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2017 Nicolas Zabouri * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,7 +92,7 @@ class box_services_contracts extends ModeleBoxes $sql.= " INNER JOIN ".MAIN_DB_PREFIX."contrat as c ON s.rowid = c.fk_soc"; $sql.= " INNER JOIN ".MAIN_DB_PREFIX."contratdet as cd ON c.rowid = cd.fk_contrat"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= "INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; $sql.= ")"; $sql.= " WHERE c.entity = ".$conf->entity; if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 54a907a3c0f..bd6f658185d 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1563,22 +1563,22 @@ abstract class CommonObject switch ($this->element) { case 'propal': - $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'commande': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'facture': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice); break; case 'supplier_proposal': - $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->multicurrency_subprice); + $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->multicurrency_subprice); break; case 'order_supplier': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'invoice_supplier': - $this->updateline($line->id, $line->desc, $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; default: dol_syslog(get_class($this).'::setMulticurrencyRate no updateline defined', LOG_DEBUG); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index ad224fec97d..aa1651d6fc6 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -254,6 +254,7 @@ class Conf if (! isset($this->global->LDAP_KEY_GROUPS)) $this->global->LDAP_KEY_GROUPS=$this->global->LDAP_FIELD_FULLNAME; if (! isset($this->global->LDAP_KEY_CONTACTS)) $this->global->LDAP_KEY_CONTACTS=$this->global->LDAP_FIELD_FULLNAME; if (! isset($this->global->LDAP_KEY_MEMBERS)) $this->global->LDAP_KEY_MEMBERS=$this->global->LDAP_FIELD_FULLNAME; + if (! isset($this->global->LDAP_KEY_MEMBERS_TYPES)) $this->global->LDAP_KEY_MEMBERS_TYPES=$this->global->LDAP_FIELD_FULLNAME; // Load translation object with current language if (empty($this->global->MAIN_LANG_DEFAULT)) $this->global->MAIN_LANG_DEFAULT="en_US"; @@ -287,15 +288,18 @@ class Conf { foreach($this->modules_parts['dir'] as $module => $dirs) { - foreach($dirs as $type => $name) + if (! empty($this->$module->enabled)) { - $subdir=($type=='temp'?'/temp':''); - // For multicompany sharings - $varname = 'multidir_'.$type; - $this->$module->$varname = array($this->entity => $rootfordata."/".$name.$subdir); - // For backward compatibility - $varname = 'dir_'.$type; - $this->$module->$varname = $rootfordata."/".$name.$subdir; + foreach($dirs as $type => $name) + { + $subdir=($type=='temp'?'/temp':''); + // For multicompany sharings + $varname = 'multidir_'.$type; + $this->$module->$varname = array($this->entity => $rootfordata."/".$name.$subdir); + // For backward compatibility + $varname = 'dir_'.$type; + $this->$module->$varname = $rootfordata."/".$name.$subdir; + } } } } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 53327f67a15..f79198a7096 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -8,6 +8,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Charles-Fr BENKE * Copyright (C) 2016 Raphaël Doursenaud + * Copyright (C) 2017 Nicolas ZABOURI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -898,7 +899,7 @@ class ExtraFields { $tmp=explode(',',$size); $newsize=$tmp[0]; - $out=''; + $out=''; } elseif ($type == 'varchar') { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 4690fab3892..12f88eef153 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1256,6 +1256,7 @@ class Form * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param bool $options_only Return options only (for ajax treatment) * @return int <0 if KO, Nb of contact in list if OK + * @deprected You can use selectcontacts directly (warning order of param was changed) */ function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false) { @@ -1264,7 +1265,8 @@ class Form } /** - * Return list of all contacts (for a third party or all) + * Return HTML code of the SELECT of list of all contacts (for a third party or all). + * This also set the number of contacts found into $this->num * * @param int $socid Id ot third party or 0 for all * @param string $selected Id contact pre-selectionne @@ -3306,21 +3308,22 @@ class Form /** * Return a HTML select list of bank accounts * - * @param string $selected Id account pre-selected - * @param string $htmlname Name of select zone - * @param int $statut Status of searched accounts (0=open, 1=closed, 2=both) - * @param string $filtre To filter list - * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. - * @param string $moreattrib To add more attribute on select + * @param string $selected Id account pre-selected + * @param string $htmlname Name of select zone + * @param int $statut Status of searched accounts (0=open, 1=closed, 2=both) + * @param string $filtre To filter list + * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. + * @param string $moreattrib To add more attribute on select + * @param int $showcurrency Show currency in label * @return void */ - function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='') + function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='',$showcurrency=0) { global $langs, $conf; $langs->load("admin"); - $sql = "SELECT rowid, label, bank, clos as status"; + $sql = "SELECT rowid, label, bank, clos as status, currency_code"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE entity IN (".getEntity('bank_account').")"; if ($statut != 2) $sql.= " AND clos = '".$statut."'"; @@ -3353,6 +3356,7 @@ class Form print ''; $i++; diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 3e09c1a83e8..e1df1156239 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -329,6 +329,7 @@ class FormMail extends Form $out.= ''."\n"; } + $modelmail_array=array(); if ($this->param['models'] != 'none') { $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs); @@ -336,7 +337,6 @@ class FormMail extends Form { setEventMessages($this->error, $this->errors, 'errors'); } - $modelmail_array=array(); foreach($this->lines_model as $line) { $langs->trans("members"); @@ -907,8 +907,8 @@ class FormMail extends Form /** - * Return templates of email with type = $type_template or type = 'all' - * This search into table c_email_templates. + * Return templates of email with type = $type_template or type = 'all'. + * This search into table c_email_templates. Used by the get_form function. * * @param DoliDB $db Database handler * @param string $type_template Get message for type=$type_template, type='all' also included. @@ -918,7 +918,7 @@ class FormMail extends Form * @param int $active 1=Only active template, 0=Only disabled, -1=All * @return array array('topic'=>,'content'=>,..) */ - private function getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1) + public function getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1) { $ret=array(); @@ -1076,11 +1076,11 @@ class FormMail extends Form * @return void * @see getCommonSubstitutionArray */ - function setSubstitFromObject($object, $outputlangs=null) + function setSubstitFromObject($object, $outputlangs) { global $conf, $user; - $parameters=array('mode'=>$mode); + $parameters=array(); $tmparray=getCommonSubstitutionArray($outputlangs, 0, null, $object); complete_substitutions_array($tmparray, $outputlangs, null, $parameters); @@ -1135,6 +1135,7 @@ class FormMail extends Form { global $conf, $langs; + $tmparray=array(); if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines') { $parameters=array('mode'=>$mode); diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 7c6fc0c5a77..64e6f9fd5ef 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2006-2015 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify @@ -123,7 +123,7 @@ class Ldap $this->filter = $conf->global->LDAP_FILTER_CONNECTION; // Filter on user $this->filtermember = $conf->global->LDAP_MEMBER_FILTER; // Filter on member - + // Users $this->attr_login = $conf->global->LDAP_FIELD_LOGIN; //unix $this->attr_sambalogin = $conf->global->LDAP_FIELD_LOGIN_SAMBA; //samba, activedirectory @@ -176,34 +176,40 @@ class Ldap { if ($connected) break; if (empty($host)) continue; - + if (preg_match('/^ldap/',$host)) { - $this->connection = ldap_connect($host); + if ($this->serverPing($host) === true) { + $this->connection = ldap_connect($host); + } + else continue; } else { - $this->connection = ldap_connect($host,$this->serverPort); + if ($this->serverPing($host, $this->serverPort) === true) { + $this->connection = ldap_connect($host,$this->serverPort); + } + else continue; } - + if (is_resource($this->connection)) { // Begin TLS if requested by the configuration - if (! empty($conf->global->LDAP_SERVER_USE_TLS)) - { - if (! ldap_start_tls($this->connection)) - { - dol_syslog(get_class($this)."::connect_bind failed to start tls", LOG_WARNING); - $connected = 0; - $this->close(); - } - } - + if (! empty($conf->global->LDAP_SERVER_USE_TLS)) + { + if (! ldap_start_tls($this->connection)) + { + dol_syslog(get_class($this)."::connect_bind failed to start tls", LOG_WARNING); + $connected = 0; + $this->close(); + } + } + // Execute the ldap_set_option here (after connect and before bind) $this->setVersion(); ldap_set_option($this->connection, LDAP_OPT_SIZELIMIT, 0); // no limit here. should return true. - - + + if ($this->serverType == "activedirectory") { $result=$this->setReferrals(); @@ -256,7 +262,7 @@ class Ldap } } } - + if (! $connected) $this->close(); } } @@ -662,6 +668,24 @@ class Ldap } } + /** + * Ping a server before ldap_connect for avoid waiting + * + * @param string $host Server host or address + * @param int $port Server port (default 389) + * @param int $timeout Timeout in second (default 1s) + * @return boolean true or false + */ + function serverPing($host, $port=389, $timeout=1) + { + $op = @fsockopen($host, $port, $errno, $errstr, $timeout); + if (!$op) return false; //DC is N/A + else { + fclose($op); //explicitly close open socket connection + return true; //DC is up & running, we can safely connect with ldap_connect + } + } + // Attribute methods ----------------------------------------------------- @@ -1387,13 +1411,16 @@ class Ldap /** * Return available value of group GID * - * @return int gid number + * @param string $keygroup Key of group + * @return int gid number */ - function getNextGroupGid() + function getNextGroupGid($keygroup='LDAP_KEY_GROUPS') { global $conf; - $search='('.$conf->global->LDAP_KEY_GROUPS.'=*)'; + if (empty($keygroup)) $keygroup='LDAP_KEY_GROUPS'; + + $search='('.$conf->global->$keygroup.'=*)'; $result = $this->search($this->groups,$search); if($result) { @@ -1411,5 +1438,3 @@ class Ldap return 0; } } - - diff --git a/htdocs/core/js/lib_batch.js b/htdocs/core/js/lib_batch.js deleted file mode 100644 index 54ddb8fa77d..00000000000 --- a/htdocs/core/js/lib_batch.js +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2014 Cedric GROSS -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// or see http://www.gnu.org/ - -// -// \file htdocs/core/js/lib_batch.js -// \brief File that include javascript functions used when dispatching batch-enabled product -// - -/** - * addLineBatch - * @deprecated replaced by addDispatchLine and moved to module folder and file fourn/js/lib_dispatch.js - * - * @param index int number of produt. 0 = first product line - */ -function addLineBatch(index) -{ - var nme = 'dluo_0_'+index; - $row=$("tr[name='"+nme+"']").clone(true); - $row.find("input[name^='qty']").val(''); - var trs = $("tr[name^='dluo_'][name$='_"+index+"']"); /* trs.length = position of line for batch */ - var newrow=$row.html().replace(/_0_/g,"_"+(trs.length)+"_"); - $row.html(newrow); - //clear value - $row.find("input[name^='qty']").val(''); - //change name of row - $row.attr('name','dluo_'+trs.length+'_'+index); - $("tr[name^='dluo_'][name$='_"+index+"']:last").after($row); - - /* Suffix of lines are: _ trs.length _ index */ - jQuery("#lot_number_"+trs.length+"_"+index).focus(); - nb = jQuery("#qty_"+(trs.length - 1)+"_"+index).val(); - if (nb > 0) - { - jQuery("#qty_"+(trs.length - 1)+"_"+index).val(1); - jQuery("#qty_"+trs.length+"_"+index).val(nb - 1); - } -} diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1817cc5ba9c..566416016aa 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3794,7 +3794,7 @@ function vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0) if (! preg_match('/\//', $rate)) $ret=price($rate,0,'',0,0).($addpercent?'%':''); else { - // TODO Split on / and output with a price2num to have clean numbers with ton of 000. + // TODO Split on / and output with a price2num to have clean numbers without ton of 000. $ret=$rate.($addpercent?'%':''); } if ($info_bits & 1) $ret.=' *'; @@ -5283,10 +5283,12 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob // TODO USe this ? $msgishtml = 0; + $birthday = dol_print_date($object->birth,'day'); + if (method_exists($object, 'getCivilityLabel')) $substitutionarray['__MEMBER_CIVILITY__'] = $object->getCivilityLabel(); $substitutionarray['__MEMBER_FIRSTNAME__']=$msgishtml?dol_htmlentitiesbr($object->firstname):$object->firstname; $substitutionarray['__MEMBER_LASTNAME__']=$msgishtml?dol_htmlentitiesbr($object->lastname):$object->lastname; - if (method_exists($object, 'getFullName')) $substitutionarray['__MEMBER_FULLNAME__']=$msgishtml?dol_htmlentitiesbr($object->getFullName($langs)):$object->getFullName($langs); + if (method_exists($object, 'getFullName')) $substitutionarray['__MEMBER_FULLNAME__']=$msgishtml?dol_htmlentitiesbr($object->getFullName($outputlangs)):$object->getFullName($outputlangs); $substitutionarray['__MEMBER_COMPANY__']=$msgishtml?dol_htmlentitiesbr($object->societe):$object->societe; $substitutionarray['__MEMBER_ADDRESS__']=$msgishtml?dol_htmlentitiesbr($object->address):$object->address; $substitutionarray['__MEMBER_ZIP__']=$msgishtml?dol_htmlentitiesbr($object->zip):$object->zip; diff --git a/htdocs/core/lib/ldap.lib.php b/htdocs/core/lib/ldap.lib.php index f684af594e5..3db36723b32 100644 --- a/htdocs/core/lib/ldap.lib.php +++ b/htdocs/core/lib/ldap.lib.php @@ -75,6 +75,14 @@ function ldap_prepare_head() $h++; } + if (! empty($conf->adherent->enabled) && ! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE)) + { + $head[$h][0] = DOL_URL_ROOT."/admin/ldap_members_types.php"; + $head[$h][1] = $langs->trans("LDAPMembersTypesSynchro"); + $head[$h][2] = 'memberstypes'; + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/lib/member.lib.php b/htdocs/core/lib/member.lib.php index 472c040e450..7e5e5e0c604 100644 --- a/htdocs/core/lib/member.lib.php +++ b/htdocs/core/lib/member.lib.php @@ -124,6 +124,16 @@ function member_type_prepare_head(AdherentType $object) $head[$h][2] = 'card'; $h++; + if (! empty($conf->ldap->enabled) && ! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE)) + { + $langs->load("ldap"); + + $head[$h][0] = DOL_URL_ROOT.'/adherents/type_ldap.php?rowid='.$object->id; + $head[$h][1] = $langs->trans("LDAPCard"); + $head[$h][2] = 'ldap'; + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/modules/modApi.class.php b/htdocs/core/modules/modApi.class.php index fc1821fde53..34c8e62a03f 100644 --- a/htdocs/core/modules/modApi.class.php +++ b/htdocs/core/modules/modApi.class.php @@ -20,7 +20,7 @@ /** * \defgroup api Module Api * \brief Descriptor file for Api modulee - * \file htdocs/api/core/modules/modApi.class.php + * \file htdocs/core/modules/modApi.class.php * \ingroup api * \brief Description and activation file for module Api */ @@ -67,7 +67,7 @@ class modApi extends DolibarrModules // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' $this->picto='technic'; - + $this->module_parts = array(); // Data directories to create when module is enabled. diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index f51e69039e9..79541c10105 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -260,10 +260,12 @@ class modProduct extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('p'=>MAIN_DB_PREFIX.'product','extra'=>MAIN_DB_PREFIX.'product_extrafields'); $this->import_tables_creator_array[$r]=array('p'=>'fk_user_author'); // Fields to store import user id - $this->import_fields_array[$r]=array('p.ref'=>"Ref*",'p.label'=>"Label*",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.weight'=>"Weight",'p.duration'=>"Duration",'p.customcode'=>'CustomCode','p.price'=>"SellingPriceHT",'p.price_ttc'=>"SellingPriceTTC",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation'); + $this->import_fields_array[$r]=array('p.ref'=>"Ref*",'p.label'=>"Label*",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.weight'=>"Weight",'p.duration'=>"Duration",'p.customcode'=>'CustomCode','p.price'=>"SellingPriceHT",'p.price_ttc'=>"SellingPriceTTC", 'p.tva_tx'=>'VATRate', 'p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation'); if (! empty($conf->stock->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.cost_price'=>'CostPrice')); if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax1_tx'=>'LT1', 'p.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.barcode'=>'BarCode')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->import_fields_array[$r]['p.fk_unit'] = 'Unit'; // Add extra fields @@ -300,9 +302,12 @@ class modProduct extends DolibarrModules $this->import_fields_array[$r]=array('sp.fk_product'=>"ProductOrService*", 'sp.fk_soc'=>"Supplier*", 'sp.ref_fourn'=>'SupplierRef', 'sp.quantity'=>"QtyMin*", 'sp.tva_tx'=>'VATRate', 'sp.price'=>"PriceQtyMinHT*", - 'sp.unitprice'=>'UnitPriceHT*', // TODO Make this file not required and calculate it from price and qty + 'sp.unitprice'=>'UnitPriceHT*', // TODO Make this field not required and calculate it from price and qty 'sp.remise_percent'=>'DiscountQtyMin' ); + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.localtax1_tx'=>'LT1', 'sp.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.localtax2_tx'=>'LT2', 'sp.localtax2_type'=>'LT2Type')); $this->import_convertvalue_array[$r]=array( 'sp.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty'), diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index cdf64b59f10..6d473c77086 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -42,6 +42,7 @@ class pdf_paiement global $langs,$conf; $langs->load("bills"); $langs->load("compta"); + $langs->load("main"); $this->db = $db; $this->description = $langs->transnoentities("ListOfCustomerPayments"); @@ -77,6 +78,8 @@ class pdf_paiement $this->posxinvoiceamount-=10; $this->posxpaymentamount-=20; } + // which type of document will be generated: clients (client) or providers (fourn) invoices + $this->doc_type = "client"; } @@ -105,7 +108,6 @@ class pdf_paiement $this->month=$month; $this->year=$year; - $dir=$_dir.'/'.$year; if (! is_dir($dir)) @@ -120,7 +122,15 @@ class pdf_paiement $month = sprintf("%02d",$month); $year = sprintf("%04d",$year); - $file = $dir . "/payments-".$year."-".$month.".pdf"; + switch ($this->doc_type) { + case "client": + $file = $dir . "/payments-".$year."-".$month.".pdf"; + break; + case "fourn": + $file = $dir . "/supplier_payments-".$year."-".$month.".pdf"; + break; + } + // Add pdfgeneration hook if (! is_object($hookmanager)) @@ -148,7 +158,14 @@ class pdf_paiement // count number of lines of payment $sql = "SELECT p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p"; + switch ($this->doc_type) { + case "client": + $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p"; + break; + case "fourn": + $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p"; + break; + } $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; $sql.= " AND p.entity = " . $conf->entity; $result = $this->db->query($sql); @@ -158,36 +175,72 @@ class pdf_paiement } // number of bill - $sql = "SELECT p.datep as dp, f.facnumber"; - //$sql .= ", c.libelle as paiement_type, p.num_paiement"; - $sql.= ", c.code as paiement_code, p.num_paiement"; - $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; - $sql.= ", pf.amount as pf_amount"; - if (! empty($conf->banque->enabled)) - $sql.= ", ba.ref as bankaccount"; - $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."facture as f,"; - $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiement_facture as pf,"; - if (! empty($conf->banque->enabled)) - $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + switch ($this->doc_type) { + case "client": + $sql = "SELECT p.datep as dp, f.facnumber"; + //$sql .= ", c.libelle as paiement_type, p.num_paiement"; + $sql.= ", c.code as paiement_code, p.num_paiement"; + $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; + $sql.= ", pf.amount as pf_amount"; + if (! empty($conf->banque->enabled)) + $sql.= ", ba.ref as bankaccount"; + $sql.= ", p.rowid as prowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."facture as f,"; + $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiement_facture as pf,"; + if (! empty($conf->banque->enabled)) + $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; + $sql.= " ".MAIN_DB_PREFIX."societe as s"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + } + $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facture = f.rowid AND pf.fk_paiement = p.rowid"; + if (! empty($conf->banque->enabled)) + $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND p.fk_paiement = c.id "; + $sql.= " AND c.entity = " . getEntity('c_paiement'); + $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + } + if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; + $sql.= " ORDER BY p.datep ASC, pf.fk_paiement ASC"; + break; + case "fourn": + $sql = "SELECT p.datep as dp, f.ref as facnumber"; + //$sql .= ", c.libelle as paiement_type, p.num_paiement"; + $sql.= ", c.code as paiement_code, p.num_paiement"; + $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; + $sql.= ", pf.amount as pf_amount"; + if (! empty($conf->banque->enabled)) + $sql.= ", ba.ref as bankaccount"; + $sql.= ", p.rowid as prowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p, ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; + if (! empty($conf->banque->enabled)) + $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; + $sql.= " ".MAIN_DB_PREFIX."societe as s"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + } + $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facturefourn = f.rowid AND pf.fk_paiementfourn = p.rowid"; + if (! empty($conf->banque->enabled)) + $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND p.fk_paiement = c.id "; + $sql.= " AND c.entity = " . getEntity('c_paiement'); + $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + } + if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; + $sql.= " ORDER BY p.datep ASC, pf.fk_paiementfourn ASC"; + break; } - $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facture = f.rowid AND pf.fk_paiement = p.rowid"; - if (! empty($conf->banque->enabled)) - $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND p.fk_paiement = c.id "; - $sql.= " AND c.entity = " . getEntity('c_paiement', 2); - $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - } - if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; - $sql.= " ORDER BY p.datep ASC, pf.fk_paiement ASC"; dol_syslog(get_class($this)."::write_file", LOG_DEBUG); $result = $this->db->query($sql); @@ -211,6 +264,7 @@ class pdf_paiement $lines[$i][6] = price($objp->pf_amount); $lines[$i][7] = $objp->prowid; $lines[$i][8] = $objp->bankaccount; + $lines[$i][9] = $objp->paiement_amount; $i++; } } @@ -276,9 +330,9 @@ class pdf_paiement if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); - + $this->result = array('fullpath'=>$file); - + return 1; } @@ -301,7 +355,14 @@ class pdf_paiement $default_font_size = pdf_getPDFFontSize($outputlangs); $title=$conf->global->MAIN_INFO_SOCIETE_NOM; - $title.=' - '.$outputlangs->transnoentities("ListOfCustomerPayments"); + switch($this->doc_type) { + case "client": + $title.=' - '.$outputlangs->transnoentities("ListOfCustomerPayments"); + break; + case "fourn": + $title.=' - '.$outputlangs->transnoentities("ListOfSupplierPayments"); + break; + } $title.=' - '.dol_print_date(dol_mktime(0,0,0,$this->month,1,$this->year),"%B %Y",false,$outputlangs,true); $pdf->SetFont('','B',$default_font_size + 1); $pdf->SetXY($this->marge_gauche,10); @@ -358,10 +419,13 @@ class pdf_paiement */ function Body(&$pdf, $page, $lines, $outputlangs) { + global $langs; $default_font_size = pdf_getPDFFontSize($outputlangs); $pdf->SetFont('','', $default_font_size - 1); $oldprowid = 0; + $total_page = 0; + $total = 0; $pdf->SetFillColor(220,220,220); $yp = 0; $numlines=count($lines); @@ -378,13 +442,17 @@ class pdf_paiement } if ($oldprowid <> $lines[$j][7]) { - if ($yp > $this->tab_height -10) + if ($yp > $this->tab_height -15) { + $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $langs->transnoentities('SubTotal')." : ".price($total_page), 0, 'R', 0); $page++; $pdf->AddPage(); $this->_pagehead($pdf, $page, 0, $outputlangs); $pdf->SetFont('','', $default_font_size - 1); $yp = 0; + $total += $total_page; + $total_page = 0; } $pdf->SetXY($this->posxdate - 1, $this->tab_top + 10 + $yp); @@ -399,11 +467,12 @@ class pdf_paiement $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][4], 0, 'R', 1); $yp = $yp + 5; + $total_page += $lines[$j][9]; } // Invoice number $pdf->SetXY($this->posxinvoice, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); + $pdf->MultiCell($this->posxinvoice - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); // BankAccount $pdf->SetXY($this->posxbankaccount, $this->tab_top + 10 + $yp); @@ -423,6 +492,9 @@ class pdf_paiement $oldprowid = $lines[$j][7]; } } + $total += $total_page; + $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $langs->transnoentities('Total')." : ".price($total), 0, 'R', 0); } } diff --git a/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php b/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php index 14eb5db43b4..0b823e0419e 100644 --- a/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php @@ -23,12 +23,12 @@ */ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - +require_once DOL_DOCUMENT_ROOT.'/core/modules/rapport/pdf_paiement.class.php'; /** * Classe permettant de generer les rapports de paiement */ -class pdf_paiement_fourn +class pdf_paiement_fourn extends pdf_paiement { /** * Constructor @@ -37,390 +37,7 @@ class pdf_paiement_fourn */ function __construct($db) { - global $langs,$conf; - $langs->load("bills"); - $langs->load("compta"); - - $this->db = $db; - $this->description = $langs->transnoentities("ListOfCustomerPayments"); - - // Dimension page pour format A4 - $this->type = 'pdf'; - $formatarray=pdf_getFormat(); - $this->page_largeur = $formatarray['width']; - $this->page_hauteur = $formatarray['height']; - $this->format = array($this->page_largeur,$this->page_hauteur); - $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; - $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; - $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; - $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; - - $this->tab_top = 30; - - $this->line_height = 5; - $this->line_per_page = 40; - $this->tab_height = $this->page_hauteur - $this->marge_haute - $this->marge_basse - $this->tab_top - 5; // must be > $this->line_height * $this->line_per_page and < $this->page_hauteur - $this->marge_haute - $this->marge_basse - $this->tab_top - 5; - - $this->posxdate=$this->marge_gauche+2; - $this->posxpaymenttype=42; - $this->posxinvoice=82; - $this->posxbankaccount=110; - $this->posxinvoiceamount=132; - $this->posxpaymentamount=162; - if ($this->page_largeur < 210) // To work with US executive format - { - $this->line_per_page = 35; - $this->posxpaymenttype-=10; - $this->posxinvoice-=0; - $this->posxinvoiceamount-=10; - $this->posxpaymentamount-=20; - } - - } - - - /** - * Fonction generant la rapport sur le disque - * - * @param string $_dir repertoire - * @param int $month mois du rapport - * @param int $year annee du rapport - * @param string $outputlangs Lang output object - * @return int <0 if KO, >0 if OK - */ - function write_file($_dir, $month, $year, $outputlangs) - { - include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - - global $conf, $hookmanager, $langs, $user; - - $socid=0; - if ($user->societe_id) $socid=$user->societe_id; - - if (! is_object($outputlangs)) $outputlangs=$langs; - // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO - if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; - - $this->month=$month; - $this->year=$year; - - $dir=$_dir.'/'.$year; - - if (! is_dir($dir)) - { - $result=dol_mkdir($dir); - if ($result < 0) - { - $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); - return -1; - } - } - - $month = sprintf("%02d",$month); - $year = sprintf("%04d",$year); - $file = $dir . "/supplier_payments-".$year."-".$month.".pdf"; - - // Add pdfgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('pdfgeneration')); - $parameters=array('file'=>$file,'outputlangs'=>$outputlangs); - global $action; - $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - - $pdf=pdf_getInstance($this->format); - $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance - - if (class_exists('TCPDF')) - { - $pdf->setPrintHeader(false); - $pdf->setPrintFooter(false); - } - $pdf->SetFont(pdf_getPDFFont($outputlangs)); - - $num=0; - $lines=array(); - - // count number of lines of payment - $sql = "SELECT p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p"; - $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - $sql.= " AND p.entity = " . $conf->entity; - $result = $this->db->query($sql); - if ($result) - { - $numpaiement = $this->db->num_rows($result); - } - - // number of bill - $sql = "SELECT p.datep as dp, f.ref"; - //$sql .= ", c.libelle as paiement_type, p.num_paiement"; - $sql.= ", c.code as paiement_code, p.num_paiement"; - $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; - $sql.= ", pf.amount as pf_amount"; - if (! empty($conf->banque->enabled)) - $sql.= ", ba.ref as bankaccount"; - $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p, ".MAIN_DB_PREFIX."facture_fourn as f,"; - $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; - if (! empty($conf->banque->enabled)) - $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facturefourn = f.rowid AND pf.fk_paiementfourn = p.rowid"; - if (! empty($conf->banque->enabled)) - $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND p.fk_paiement = c.id "; - $sql.= " AND c.entity = " . getEntity('c_paiement', 2); - $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - } - if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; - $sql.= " ORDER BY p.datep ASC, pf.fk_paiementfourn ASC"; - - dol_syslog(get_class($this)."::write_file", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - $var=True; - - while ($i < $num) - { - $objp = $this->db->fetch_object($result); - - - $lines[$i][0] = $objp->ref; - $lines[$i][1] = dol_print_date($this->db->jdate($objp->dp),"day",false,$outputlangs,true); - $lines[$i][2] = $langs->transnoentities("PaymentTypeShort".$objp->paiement_code); - $lines[$i][3] = $objp->num_paiement; - $lines[$i][4] = price($objp->paiement_amount); - $lines[$i][5] = price($objp->facture_amount); - $lines[$i][6] = price($objp->pf_amount); - $lines[$i][7] = $objp->prowid; - $lines[$i][8] = $objp->bankaccount; - $i++; - } - } - else - { - dol_print_error($this->db); - } - - $pages = intval(($num + $numpaiement) / $this->line_per_page); - - if ((($num + $numpaiement) % $this->line_per_page)>0) - { - $pages++; - } - - if ($pages == 0) - { - // force to build at least one page if report has no line - $pages = 1; - } - - $pdf->Open(); - $pagenb=0; - $pdf->SetDrawColor(128,128,128); - - $pdf->SetTitle($outputlangs->transnoentities("Payments")); - $pdf->SetSubject($outputlangs->transnoentities("Payments")); - $pdf->SetCreator("Dolibarr ".DOL_VERSION); - $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); - //$pdf->SetKeyWords(); - if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); - - $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right - $pdf->SetAutoPageBreak(1,0); - - // New page - $pdf->AddPage(); - $pagenb++; - $this->_pagehead($pdf, $pagenb, 1, $outputlangs); - $pdf->SetFont('','', 9); - $pdf->MultiCell(0, 3, ''); // Set interline to 3 - $pdf->SetTextColor(0,0,0); - - - $this->Body($pdf, 1, $lines, $outputlangs); - - if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); - - $pdf->Close(); - - $pdf->Output($file,'F'); - - // Add pdfgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('pdfgeneration')); - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); - global $action; - $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - - if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); - - $this->result = array('fullpath'=>$file); - - return 1; - } - - /** - * Show top header of page. - * - * @param PDF $pdf Object PDF - * @param int $page Object to show - * @param int $showaddress 0=no, 1=yes - * @param Translate $outputlangs Object lang for output - * @return void - */ - function _pagehead(&$pdf, $page, $showaddress, $outputlangs) - { - global $langs; - - // Do not add the BACKGROUND as this is a report - //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); - - $default_font_size = pdf_getPDFFontSize($outputlangs); - - $title=$conf->global->MAIN_INFO_SOCIETE_NOM; - $title.=' - '.$outputlangs->transnoentities("ListOfSupplierPayments"); - $title.=' - '.dol_print_date(dol_mktime(0,0,0,$this->month,1,$this->year),"%B %Y",false,$outputlangs,true); - $pdf->SetFont('','B',$default_font_size + 1); - $pdf->SetXY($this->marge_gauche,10); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->marge_gauche, 2, $title, 0, 'C'); - - $pdf->SetFont('','',$default_font_size); - - $pdf->SetXY($this->posxdate, 16); - $pdf->MultiCell(80, 2, $outputlangs->transnoentities("DateBuild")." : ".dol_print_date(time(),"day",false,$outputlangs,true), 0, 'L'); - - $pdf->SetXY($this->posxdate+100, 16); - $pdf->MultiCell(80, 2, $outputlangs->transnoentities("Page")." : ".$page, 0, 'R'); - - - // Title line - $pdf->SetXY($this->posxdate, $this->tab_top+2); - $pdf->MultiCell($this->posxpaymenttype - $this->posxdate, 2, 'Date'); - - $pdf->line($this->posxpaymenttype - 1, $this->tab_top, $this->posxpaymenttype - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxpaymenttype, $this->tab_top+2); - $pdf->MultiCell($this->posxinvoice - $this->posxpaymenttype, 2, $outputlangs->transnoentities("PaymentMode"), 0, 'L'); - - $pdf->line($this->posxinvoice - 1, $this->tab_top, $this->posxinvoice - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxinvoice, $this->tab_top+2); - $pdf->MultiCell($this->posxbankaccount - $this->posxinvoice, 2, $outputlangs->transnoentities("Invoice"), 0, 'L'); - - $pdf->line($this->posxbankaccount - 1, $this->tab_top, $this->posxbankaccount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxbankaccount, $this->tab_top+2); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, 2, $outputlangs->transnoentities("Account"), 0, 'L'); - - - $pdf->line($this->posxinvoiceamount - 1, $this->tab_top, $this->posxinvoiceamount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top+2); - $pdf->MultiCell($this->posxpaymentamount - $this->posxinvoiceamount - 1, 2, $outputlangs->transnoentities("AmountInvoice"), 0, 'R'); - - $pdf->line($this->posxpaymentamount - 1, $this->tab_top, $this->posxpaymentamount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxpaymentamount, $this->tab_top+2); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount - 1, 2, $outputlangs->transnoentities("AmountPayment"), 0, 'R'); - - $pdf->line($this->marge_gauche, $this->tab_top + 10, $this->page_largeur - $this->marge_droite, $this->tab_top + 10); - - $pdf->Rect($this->marge_gauche, $this->tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $this->tab_height + 10); - } - - - /** - * Output body - * - * @param PDF $pdf PDF object - * @param string $page Page - * @param array $lines Array of lines - * @param Translate $outputlangs Object langs - * @return void - */ - function Body(&$pdf, $page, $lines, $outputlangs) - { - $default_font_size = pdf_getPDFFontSize($outputlangs); - - $pdf->SetFont('','', $default_font_size - 1); - $oldprowid = 0; - $pdf->SetFillColor(220,220,220); - $yp = 0; - $numlines=count($lines); - for ($j = 0 ; $j < $numlines ; $j++) - { - $i = $j; - if ($yp > $this->tab_height -5) - { - $page++; - $pdf->AddPage(); - $this->_pagehead($pdf, $page, 0, $outputlangs); - $pdf->SetFont('','', $default_font_size - 1); - $yp = 0; - } - if ($oldprowid <> $lines[$j][7]) - { - if ($yp > $this->tab_height -10) - { - $page++; - $pdf->AddPage(); - $this->_pagehead($pdf, $page, 0, $outputlangs); - $pdf->SetFont('','', $default_font_size - 1); - $yp = 0; - } - - $pdf->SetXY($this->posxdate - 1, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymenttype - $this->posxdate + 1, $this->line_height, $lines[$j][1], 0, 'L', 1); - - $pdf->SetXY($this->posxpaymenttype, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxpaymenttype, $this->line_height, $lines[$j][2].' '.$lines[$j][3], 0, 'L', 1); - - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymentamount- $this->posxinvoiceamount, $this->line_height, '', 0, 'R', 1); - - $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][4], 0, 'R', 1); - $yp = $yp + 5; - } - - // Invoice number - $pdf->SetXY($this->posxinvoice, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); - - // BankAccount - $pdf->SetXY($this->posxbankaccount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxbankaccount - $this->posxdate, $this->line_height, $lines[$j][8], 0, 'L', 0); - - // Invoice amount - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymentamount- $this->posxinvoiceamount - 1, $this->line_height, $lines[$j][5], 0, 'R', 0); - - // Payment amount - $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][6], 0, 'R', 0); - $yp = $yp + 5; - - if ($oldprowid <> $lines[$j][7]) - { - $oldprowid = $lines[$j][7]; - } - } + parent::__construct($db); + $this->doc_type = "fourn"; } } - diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index f968fdcbfc7..94c05fd9ffe 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -145,7 +145,7 @@ if (empty($outputalsopricetotalwithtax)) $outputalsopricetotalwithtax=0; '; $linktoprod = '' . img_object($langs->trans("ShowProduct"), 'product') . ' ' . $objp->ref . ''; @@ -607,9 +610,6 @@ if ($id > 0 || ! empty($ref)) { print ''; } - // hidden fields for js function - print ''; - print ''; print ''; print ''; } // Qty to dispatch print ''; + print ''; print ''."\n"; print ''."\n"; - + print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; - + print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; /* - + print ''."\n"; print ''."\n"; print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; @@ -577,6 +619,38 @@ while ($i < min($num,$limit)) print ''; + print $obj->qty; + print ''; + print price($obj->total_ht); + print ''; + print price($obj->total_tva); + print ''; + print price2num($obj->tva_tx).'%'; + print ''; + print price($obj->subprice); + print 'tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); + if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); if (price2num($line->total_localtax1)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); if (price2num($line->total_localtax2)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); if (empty($positiverates)) $positiverates='0'; diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index fa93db2503c..bfa0efad8e6 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -55,7 +55,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers // Proposals to order if ($action == 'PROPAL_CLOSE_SIGNED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_PROPAL_AUTOCREATE_ORDER)) { include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; @@ -74,7 +74,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers // Order to invoice if ($action == 'ORDER_CLOSE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_ORDER_AUTOCREATE_INVOICE)) { include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; @@ -90,12 +90,10 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - - // Order classify billed proposal if ($action == 'ORDER_CLASSIFY_BILLED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL)) { $object->fetchObjectLinked('','propal',$object->id,$object->element); @@ -106,8 +104,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['propal'] as $element) { @@ -119,11 +117,35 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - // classify billed order + // classify billed order & billed propososal if ($action == 'BILL_VALIDATE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); - + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); + + // First classify billed the order to allow the proposal classify process + if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER)) + { + $object->fetchObjectLinked('','commande',$object->id,$object->element); + if (! empty($object->linkedObjects)) + { + $totalonlinkedelements=0; + foreach($object->linkedObjects['commande'] as $element) + { + if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; + } + dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) + { + foreach($object->linkedObjects['commande'] as $element) + { + $ret=$element->classifyBilled($user); + } + } + } + return $ret; + } + + // Second classify billed the proposal. if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL)) { $object->fetchObjectLinked('','propal',$object->id,$object->element); @@ -134,8 +156,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['propal'] as $element) { @@ -145,34 +167,13 @@ class InterfaceWorkflowManager extends DolibarrTriggers } return $ret; } - - if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER)) - { - $object->fetchObjectLinked('','commande',$object->id,$object->element); - if (! empty($object->linkedObjects)) - { - $totalonlinkedelements=0; - foreach($object->linkedObjects['commande'] as $element) - { - if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; - } - dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) - { - foreach($object->linkedObjects['commande'] as $element) - { - $ret=$element->classifyBilled($user); - } - } - } - return $ret; - } + } // Invoice classify billed order if ($action == 'BILL_PAYED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER)) { @@ -184,8 +185,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['commande'] as $element) { @@ -199,8 +200,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers if ($action=='SHIPPING_VALIDATE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); - + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->commande->enabled) && ! empty($conf->expedition->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING)) { @@ -234,6 +234,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } } + //Build array of quantity ordered by product if (is_array($order->lines) && count($order->lines)>0) { foreach($order->lines as $orderline) { diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php index 561ba330694..a906ec821ed 100644 --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php @@ -1,6 +1,7 @@ - * Copyright (C) 2014 Marcos GarcĂ­a +/* Copyright (C) 2005-2012 Laurent Destailleur + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2014 Marcos GarcĂ­a * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -49,553 +50,748 @@ class InterfaceLdapsynchro extends DolibarrTriggers * @return int <0 if KO, 0 if no triggered ran, >0 if OK */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) - { - if (empty($conf->ldap->enabled)) return 0; // Module not active, we do nothing + { + if (empty($conf->ldap->enabled)) return 0; // Module not active, we do nothing - if (! function_exists('ldap_connect')) - { - dol_syslog("Warning, module LDAP is enabled but LDAP functions not available in this PHP", LOG_WARNING); - return 0; - } + if (! function_exists('ldap_connect')) + { + dol_syslog("Warning, module LDAP is enabled but LDAP functions not available in this PHP", LOG_WARNING); + return 0; + } - // Users - if ($action == 'USER_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + $result=0; - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); + // Users + if ($action == 'USER_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); } - return $result; - } - } - elseif ($action == 'USER_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'USER_NEW_PASSWORD') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_NEW_PASSWORD') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'USER_ENABLEDISABLE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - } - elseif ($action == 'USER_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'USER_SETINGROUP') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - // Must edit $object->newgroupid - $usergroup=new UserGroup($this->db); - if ($object->newgroupid > 0) - { - $usergroup->fetch($object->newgroupid); + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_ENABLEDISABLE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + } + elseif ($action == 'USER_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$usergroup->_load_ldap_info(); - $olddn=$usergroup->_load_ldap_dn($oldinfo); + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); - // Verify if entry exist - $container=$usergroup->_load_ldap_dn($oldinfo,1); - $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } + $result=$ldap->delete($dn); + } - $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) - $dn=$usergroup->_load_ldap_dn($info); + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_SETINGROUP') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - } - return $result; - } - } - elseif ($action == 'USER_REMOVEFROMGROUP') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + if ($result > 0) + { + // Must edit $object->newgroupid + $usergroup=new UserGroup($this->db); + if ($object->newgroupid > 0) + { + $usergroup->fetch($object->newgroupid); - // Must edit $object->newgroupid - $usergroup=new UserGroup($this->db); - if ($object->oldgroupid > 0) - { - $usergroup->fetch($object->oldgroupid); + $oldinfo=$usergroup->_load_ldap_info(); + $olddn=$usergroup->_load_ldap_dn($oldinfo); - $oldinfo=$usergroup->_load_ldap_info(); - $olddn=$usergroup->_load_ldap_dn($oldinfo); + // Verify if entry exist + $container=$usergroup->_load_ldap_dn($oldinfo,1); + $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } - // Verify if entry exist - $container=$usergroup->_load_ldap_dn($oldinfo,1); - $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } + $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$usergroup->_load_ldap_dn($info); - $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) - $dn=$usergroup->_load_ldap_dn($info); + $result=$ldap->update($dn,$info,$user,$olddn); + } + } - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - } - return $result; - } - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_REMOVEFROMGROUP') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + // Must edit $object->newgroupid + $usergroup=new UserGroup($this->db); + if ($object->oldgroupid > 0) + { + $usergroup->fetch($object->oldgroupid); + + $oldinfo=$usergroup->_load_ldap_info(); + $olddn=$usergroup->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$usergroup->_load_ldap_dn($oldinfo,1); + $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$usergroup->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } // Groupes - elseif ($action == 'GROUP_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + elseif ($action == 'GROUP_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } + + $result=$ldap->add($dn,$info,$user); } - return $result; - } - } - elseif ($action == 'GROUP_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'GROUP_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - - // Contacts - elseif ($action == 'CONTACT_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'CONTACT_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'CONTACT_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } - } + } + elseif ($action == 'GROUP_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - // Members - elseif ($action == 'MEMBER_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'MEMBER_VALIDATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'GROUP_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + // Contacts + elseif ($action == 'CONTACT_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'CONTACT_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'CONTACT_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + // Members + elseif ($action == 'MEMBER_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $membertype=new AdherentType($this->db); + if ($object->typeid > 0) + { + $membertype->fetch($object->typeid); + $membertype->listMembersForMemberType(); + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$membertype->_load_ldap_dn($oldinfo,1); + $search = "(".$membertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_VALIDATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If status field is setup to be synchronized if (! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only status - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only status + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_SUBSCRIPTION') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + } + elseif ($action == 'MEMBER_SUBSCRIPTION') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If subscriptions fields are setup to be synchronized if ($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE - || $conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT - || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE - || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT - || $conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION) + || $conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT + || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE + || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT + || $conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only subscriptions - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only subscriptions + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + } + elseif ($action == 'MEMBER_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + /* + * Change member info + */ + $newmembertype=new AdherentType($this->db); + $newmembertype->fetch($object->typeid); + $newmembertype->listMembersForMemberType(); + + $oldinfo=$newmembertype->_load_ldap_info(); + $olddn=$newmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$newmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$newmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$newmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$newmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + + if ($object->oldcopy->typeid != $object->typeid) + { + /* + * Remove member in old member type + */ + $oldmembertype=new AdherentType($this->db); + $oldmembertype->fetch($object->oldcopy->typeid); + $oldmembertype->listMembersForMemberType(); + + $oldinfo=$oldmembertype->_load_ldap_info(); + $olddn=$oldmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$oldmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$oldmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$oldmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$oldmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } } - return $result; - } - } - elseif ($action == 'MEMBER_NEW_PASSWORD') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_NEW_PASSWORD') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If password field is setup to be synchronized if ($conf->global->LDAP_FIELD_PASSWORD || $conf->global->LDAP_FIELD_PASSWORD_CRYPTED) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only password - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only password + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } } - elseif ($action == 'MEMBER_RESILIATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + elseif ($action == 'MEMBER_RESILIATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If status field is setup to be synchronized if (! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only status - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only status + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + } + elseif ($action == 'MEMBER_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); - // If not found -/* - else - { - dol_syslog("Trigger '".$this->name."' for action '$action' was ran by ".__FILE__." but no handler found for this action."); - return -1; - } -*/ - return 0; - } + $result=$ldap->delete($dn); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + if ($object->typeid > 0) + { + /* + * Remove member in member type + */ + $membertype=new AdherentType($this->db); + $membertype->fetch($object->typeid); + $membertype->listMembersForMemberType('a.rowid != ' . $object->id); // remove deleted member from the list + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$membertype->_load_ldap_dn($oldinfo,1); + $search = "(".$membertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + // Members types + elseif ($action == 'MEMBER_TYPE_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPE'); + } + + $result=$ldap->add($dn,$info,$user); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_TYPE_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $object->oldcopy->listMembersForMemberType(); + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $object->listMembersForMemberType(); + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_TYPE_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + return $result; + } } diff --git a/htdocs/document.php b/htdocs/document.php index 11017f52cc2..0b2db2323cd 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -25,7 +25,7 @@ * \file htdocs/document.php * \brief Wrapper to download data files * \remarks Call of this wrapper is made with URL: - * document.php?modulepart=repfichierconcerne&file=pathrelatifdufichier + * document.php?modulepart=repfichierconcerne&file=relativepathoffile * document.php?modulepart=logs&file=dolibarr.log */ diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 17777e6e228..ef4bf2a9a70 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2221,7 +2221,7 @@ else if ($id || $ref) $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit['__SHIPPINGREF__']=$object->ref; $formmail->substit['__SHIPPINGTRACKNUM__']=$object->tracking_number; $formmail->substit['__SHIPPINGTRACKNUMURL__']=$object->tracking_url; diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 680ab2b6a7e..84bcebf8ea1 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1683,18 +1683,11 @@ else if ($id > 0 || ! empty($ref)) * Built documents */ $filename=dol_sanitizeFileName($object->ref); - $filedir=$conf->ficheinter->dir_output . "/".$object->ref; + $filedir=$conf->ficheinter->dir_output . "/".$filename; $urlsource=$_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed=$user->rights->ficheinter->creer; $delallowed=$user->rights->ficheinter->supprimer; - $genallowed=1; - $delallowed=1; - - $var=true; - - //print "
\n"; - print $somethingshown=$formfile->showdocuments('ficheinter',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); - + print $formfile->showdocuments('ficheinter',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('fichinter')); diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 95f573530bf..9335e4dcbb4 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -279,11 +279,12 @@ class CommandeFournisseur extends CommonOrder $this->fetchObjectLinked(); + //$result=$this->fetch_lines(); $this->lines=array(); $sql = "SELECT l.rowid, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description, l.qty,"; $sql.= " l.vat_src_code, l.tva_tx, l.remise_percent, l.subprice,"; - $sql.= " l.localtax1_tx, l. localtax2_tx, l.total_localtax1, l.total_localtax2,"; + $sql.= " l.localtax1_tx, l. localtax2_tx, l.localtax1_type, l. localtax2_type, l.total_localtax1, l.total_localtax2,"; $sql.= " l.total_ht, l.total_tva, l.total_ttc, l.special_code, l.fk_parent_line, l.rang,"; $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc,"; $sql.= " l.fk_unit,"; @@ -315,6 +316,8 @@ class CommandeFournisseur extends CommonOrder $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; $line->subprice = $objp->subprice; $line->pu_ht = $objp->subprice; $line->remise_percent = $objp->remise_percent; @@ -2977,7 +2980,7 @@ class CommandeFournisseurLigne extends CommonOrderLine public function fetch($rowid) { $sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_product, cd.product_type, cd.description, cd.qty, cd.tva_tx,'; - $sql.= ' cd.localtax1_tx, cd.localtax2_tx, cd.ref,'; + $sql.= ' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref,'; $sql.= ' cd.remise, cd.remise_percent, cd.subprice,'; $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_ttc,'; $sql.= ' cd.total_localtax1, cd.total_localtax2,'; @@ -3003,6 +3006,8 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->tva_tx = $objp->tva_tx; $this->localtax1_tx = $objp->localtax1_tx; $this->localtax2_tx = $objp->localtax2_tx; + $this->localtax1_type = $objp->localtax1_type; + $this->localtax2_type = $objp->localtax2_type; $this->remise = $objp->remise; $this->remise_percent = $objp->remise_percent; $this->fk_product = $objp->fk_product; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 78c08478321..5410d7aba65 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -640,7 +640,7 @@ class FactureFournisseur extends CommonInvoice function fetch_lines() { $sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.vat_src_code, f.tva_tx'; - $sql.= ', f.localtax1_tx, f.localtax2_tx, f.total_localtax1, f.total_localtax2, f.fk_facture_fourn '; + $sql.= ', f.localtax1_tx, f.localtax2_tx, f.localtax1_type, f.localtax2_type, f.total_localtax1, f.total_localtax2, f.fk_facture_fourn '; $sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit'; $sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as label, p.description as product_desc'; $sql.= ', f.fk_multicurrency, f.multicurrency_code, f.multicurrency_subprice, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc'; @@ -681,6 +681,8 @@ class FactureFournisseur extends CommonInvoice $line->tva_tx = $obj->tva_tx; $line->localtax1_tx = $obj->localtax1_tx; $line->localtax2_tx = $obj->localtax2_tx; + $line->localtax1_type = $obj->localtax1_type; + $line->localtax2_type = $obj->localtax2_type; $line->qty = $obj->qty; $line->remise_percent = $obj->remise_percent; $line->tva = $obj->total_tva; @@ -1806,7 +1808,7 @@ class FactureFournisseur extends CommonInvoice $response->warning_delay=$conf->facture->fournisseur->warning_delay/60/60/24; $response->label=$langs->trans("SupplierBillsToPay"); - $response->url=DOL_URL_ROOT.'/fourn/facture/list.php?filtre=fac.fk_statut:1,paye:0&mainmenu=accountancy&leftmenu=suppliers_bills'; + $response->url=DOL_URL_ROOT.'/fourn/facture/list.php?search_status=1&mainmenu=accountancy&leftmenu=suppliers_bills'; $response->img=img_object($langs->trans("Bills"),"bill"); $facturestatic = new FactureFournisseur($this->db); diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 5a63cb3f1ff..504147adff3 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -180,16 +180,18 @@ class ProductFournisseur extends Product * @param Societe $fourn Supplier * @param int $availability Product availability * @param string $ref_fourn Supplier ref - * @param float $tva_tx VAT rate + * @param float $tva_tx New VAT Rate (For example 8.5. Should not be a string) * @param string $charges costs affering to product * @param float $remise_percent Discount regarding qty (percent) * @param float $remise Discount regarding qty (amount) * @param int $newnpr Set NPR or not * @param int $delivery_time_days Delay in days for delivery (max). May be '' if not defined. * @param string $supplier_reputation Reputation with this product to the defined supplier (empty, FAVORITE, DONOTORDER) + * @param array $localtaxes_array Array with localtaxes info array('0'=>type1,'1'=>rate1,'2'=>type2,'3'=>rate2) (loaded by getLocalTaxesFromRate(vatrate, 0, ...) function). + * @param string $newdefaultvatcode Default vat code * @return int <0 if KO, >=0 if OK */ - function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0, $delivery_time_days=0, $supplier_reputation='') + function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0, $delivery_time_days=0, $supplier_reputation='', $localtaxes_array=array(), $newdefaultvatcode='') { global $conf, $langs; //global $mysoc; @@ -217,6 +219,25 @@ class ProductFournisseur extends Product $now=dol_now(); + $newvat = $tva_tx; + + if (count($localtaxes_array) > 0) + { + $localtaxtype1=$localtaxes_array['0']; + $localtax1=$localtaxes_array['1']; + $localtaxtype2=$localtaxes_array['2']; + $localtax2=$localtaxes_array['3']; + } + else // old method. deprecated because ot can't retreive type + { + $localtaxtype1='0'; + $localtax1=get_localtax($newvat,1); + $localtaxtype2='0'; + $localtax2=get_localtax($newvat,2); + } + if (empty($localtax1)) $localtax1=0; // If = '' then = 0 + if (empty($localtax2)) $localtax2=0; // If = '' then = 0 + $this->db->begin(); if ($this->product_fourn_price_id > 0) @@ -230,9 +251,15 @@ class ProductFournisseur extends Product $sql.= " remise = ".$remise.","; $sql.= " unitprice = ".$unitBuyPrice.","; $sql.= " unitcharges = ".$unitCharges.","; // deprecated - $sql.= " tva_tx = ".$tva_tx.","; $sql.= " fk_availability = ".$availability.","; $sql.= " entity = ".$conf->entity.","; + $sql.= " tva_tx = ".price2num($tva_tx).","; + // TODO Add localtax1 and localtax2 + //$sql.= " localtax1_tx=".($localtax1>=0?$localtax1:'NULL').","; + //$sql.= " localtax2_tx=".($localtax2>=0?$localtax2:'NULL').","; + //$sql.= " localtax1_type=".($localtaxtype1!=''?"'".$localtaxtype1."'":"'0'").","; + //$sql.= " localtax2_type=".($localtaxtype2!=''?"'".$localtaxtype2."'":"'0'").","; + $sql.= " default_vat_code=".($newdefaultvatcode?"'".$this->db->escape($newdefaultvatcode)."'":"null").","; $sql.= " info_bits = ".$newnpr.","; $sql.= " charges = ".$charges.","; // deprecated $sql.= " delivery_time_days = ".($delivery_time_days != '' ? $delivery_time_days : 'null').","; @@ -279,7 +306,7 @@ class ProductFournisseur extends Product if ($resql) { // Add price for this quantity to supplier $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price("; - $sql .= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, unitcharges, fk_availability, info_bits, entity, delivery_time_days,supplier_reputation)"; + $sql .= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, unitcharges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation)"; $sql .= " values('" . $this->db->idate($now) . "',"; $sql .= " " . $this->id . ","; $sql .= " " . $fourn->id . ","; @@ -294,6 +321,7 @@ class ProductFournisseur extends Product $sql .= " " . $charges . ","; $sql .= " " . $unitCharges . ","; $sql .= " " . $availability . ","; + $sql .= " ".($newdefaultvatcode?"'".$this->db->escape($newdefaultvatcode)."'":"null").","; $sql .= " " . $newnpr . ","; $sql .= $conf->entity . ","; $sql .= $delivery_time_days . ","; @@ -364,9 +392,9 @@ class ProductFournisseur extends Product function fetch_product_fournisseur_price($rowid, $ignore_expression = 0) { global $conf; - $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability,"; + $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.default_vat_code, pfp.fk_availability,"; $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges, pfp.fk_supplier_price_expression, pfp.delivery_time_days,"; // , pfp.recuperableonly as fourn_tva_npr"; FIXME this field not exist in llx_product_fournisseur_price - $sql.=" pfp.supplier_reputation"; + $sql.= " pfp.supplier_reputation"; $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE pfp.rowid = ".$rowid; @@ -392,11 +420,14 @@ class ProductFournisseur extends Product $this->fourn_unitprice = $obj->unitprice; $this->fourn_unitcharges = $obj->unitcharges; // deprecated $this->fourn_tva_tx = $obj->tva_tx; - //$this->fourn_tva_npr = $obj->fourn_tva_npr; // TODO this field not exist in llx_product_fournisseur_price. We should add it ? + // TODO + // $this->fourn_tva_npr = $obj->fourn_tva_npr; // TODO this field not exist in llx_product_fournisseur_price. We should add it ? + // Add also localtaxes $this->fk_availability = $obj->fk_availability; $this->delivery_time_days = $obj->delivery_time_days; $this->fk_supplier_price_expression = $obj->fk_supplier_price_expression; - $this->supplier_reputation = $obj->supplier_reputation; + $this->supplier_reputation = $obj->supplier_reputation; + $this->default_vat_code = $obj->default_vat_code; if (empty($ignore_expression) && !empty($this->fk_supplier_price_expression)) { diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 210e93adf14..a7568f446ca 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -552,117 +552,137 @@ if (empty($reshook)) */ if ($action == 'updateline' && $user->rights->fournisseur->commande->creer && ! GETPOST('cancel','alpha')) { - $tva_tx = GETPOST('tva_tx'); - - if (GETPOST('price_ht') != '') - { - $price_base_type = 'HT'; - $ht = price2num(GETPOST('price_ht')); - } - else - { - $ttc = price2num(GETPOST('price_ttc')); - $ht = $ttc / (1 + ($tva_tx / 100)); - $price_base_type = 'HT'; - } + $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); if ($lineid) - { - $line = new CommandeFournisseurLigne($db); - $res = $line->fetch($lineid); - if (!$res) dol_print_error($db); - } - - $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - - $localtax1_tx=get_localtax($tva_tx,1,$mysoc,$object->thirdparty); - $localtax2_tx=get_localtax($tva_tx,2,$mysoc,$object->thirdparty); - - $pu_ht_devise = GETPOST('multicurrency_subprice'); - - // Extrafields Lines - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); - // Unset extrafield POST Data - if (is_array($extralabelsline)) { - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); - } + { + $line = new CommandeFournisseurLigne($db); + $res = $line->fetch($lineid); + if (!$res) dol_print_error($db); + } + + if ($productsupplier->get_buyprice(0, price2num($_POST['qty']), $line->fk_product, 'none', GETPOST('socid','int')) < 0 ) + { + setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings'); } - $result = $object->updateline( - $lineid, - $_POST['product_desc'], - $ht, - $_POST['qty'], - $_POST['remise_percent'], - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $price_base_type, - 0, - isset($_POST["type"])?$_POST["type"]:$line->product_type, - false, - $date_start, - $date_end, - $array_options, - $_POST['units'], - $pu_ht_devise - ); - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['idprodfournprice']); - unset($_POST['remmise_percent']); - unset($_POST['dp_desc']); - unset($_POST['np_desc']); - unset($_POST['pu']); - unset($_POST['tva_tx']); - unset($_POST['date_start']); - unset($_POST['date_end']); - unset($_POST['units']); - unset($localtax1_tx); - unset($localtax2_tx); + $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); + // Define info_bits + $info_bits = 0; + if (preg_match('/\*/', $vat_rate)) + $info_bits |= 0x01; - if ($result >= 0) - { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records + // Define vat_rate + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $mysoc, $object->thirdparty); + $localtax2_rate = get_localtax($vat_rate, 2, $mysoc, $object->thirdparty); - $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result < 0) dol_print_error($db,$result); - } - } - else - { - dol_print_error($db,$object->error); - exit; - } + if (GETPOST('price_ht') != '') + { + $price_base_type = 'HT'; + $ht = price2num(GETPOST('price_ht')); + } + else + { + $vatratecleaned = $vat_rate; + if (preg_match('/^(.*)\s*\((.*)\)$/', $vat_rate, $reg)) // If vat is "xx (yy)" + { + $vatratecleaned = trim($reg[1]); + $vatratecode = $reg[2]; + } + + $ttc = price2num(GETPOST('price_ttc')); + $ht = $ttc / (1 + ($vatratecleaned / 100)); + $price_base_type = 'HT'; + } + + $pu_ht_devise = GETPOST('multicurrency_subprice'); + + // Extrafields Lines + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield POST Data + if (is_array($extralabelsline)) { + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + $result = $object->updateline( + $lineid, + $_POST['product_desc'], + $ht, + $_POST['qty'], + $_POST['remise_percent'], + $vat_rate, + $localtax1_rate, + $localtax2_rate, + $price_base_type, + 0, + isset($_POST["type"])?$_POST["type"]:$line->product_type, + false, + $date_start, + $date_end, + $array_options, + $_POST['units'], + $pu_ht_devise + ); + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['idprodfournprice']); + unset($_POST['remmise_percent']); + unset($_POST['dp_desc']); + unset($_POST['np_desc']); + unset($_POST['pu']); + unset($_POST['tva_tx']); + unset($_POST['date_start']); + unset($_POST['date_end']); + unset($_POST['units']); + unset($localtax1_tx); + unset($localtax2_tx); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); + + if ($result >= 0) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) dol_print_error($db,$result); + } + } + else + { + dol_print_error($db,$object->error); + exit; + } + } // Remove a product line diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index f4f05f96b78..67b22c6767c 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -547,6 +547,9 @@ if ($id > 0 || ! empty($ref)) { print "\n"; print '' . "\n"; + // hidden fields for js function + print ''; + print ''; print '
'; @@ -649,16 +649,13 @@ if ($id > 0 || ! empty($ref)) { print ''; } - // hidden fields for js function - print ''; - print ''; print ''; print ''; - print ''; if (! empty($conf->productbatch->enabled) && $objp->tobatch == 1) { diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index ba2d321dcbe..bd883091059 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -328,7 +328,7 @@ if (empty($reshook)) // Multicurrency rate else if ($action == 'setmulticurrencyrate' && $user->rights->facture->creer) { - $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx'))); + $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx', 'alpha'))); } // bank account diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index c11b914c45d..349726bab5b 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -54,6 +54,7 @@ $massaction=GETPOST('massaction','alpha'); $show_files=GETPOST('show_files','int'); $confirm=GETPOST('confirm','alpha'); $toselect = GETPOST('toselect', 'array'); +$optioncss = GETPOST('optioncss','alpha'); $socid = GETPOST('socid','int'); @@ -67,6 +68,11 @@ if ($user->societe_id > 0) $mode=GETPOST("mode"); +$search_all = GETPOST('sall', 'alphanohtml'); +$search_label = GETPOST("search_label","alpha"); +$search_company = GETPOST("search_company","alpha"); +$search_amount_no_tax = GETPOST("search_amount_no_tax","alpha"); +$search_amount_all_tax = GETPOST("search_amount_all_tax","alpha"); $search_product_category=GETPOST('search_product_category','int'); $search_ref=GETPOST('sf_ref')?GETPOST('sf_ref','alpha'):GETPOST('search_ref','alpha'); $search_refsupplier=GETPOST('search_refsupplier','alpha'); @@ -93,20 +99,12 @@ $day_lim = GETPOST('day_lim','int'); $month_lim = GETPOST('month_lim','int'); $year_lim = GETPOST('year_lim','int'); $toselect = GETPOST('toselect', 'array'); -$filter = GETPOST('filtre','alpha'); $option = GETPOST('option'); if ($option == 'late') { - $filter = 'paye:0'; + $search_status = '1'; } - -$search_all = GETPOST('sall', 'alphanohtml'); -$search_label = GETPOST("search_label","alpha"); -$search_company = GETPOST("search_company","alpha"); -$search_amount_no_tax = GETPOST("search_amount_no_tax","alpha"); -$search_amount_all_tax = GETPOST("search_amount_all_tax","alpha"); -$search_status=GETPOST('search_status','alpha'); -$optioncss = GETPOST('optioncss','alpha'); +$filter = GETPOST('filtre','alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); @@ -349,7 +347,6 @@ else if ($year_lim > 0) $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($year_lim,1,false))."' AND '".$db->idate(dol_get_last_day($year_lim,12,false))."'"; } if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->fournisseur->warning_delay)."'"; -if ($filter == 'paye:0') $sql.= " AND f.fk_statut = 1"; if ($search_label) $sql .= natural_search('f.libelle', $search_label); if ($search_status != '' && $search_status >= 0) { @@ -361,10 +358,10 @@ if ($filter && $filter != -1) foreach ($aFilter as $fil) { $filt = explode(':', $fil); - $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); + $sql .= ' AND ' . $db->escape(trim($filt[0])) . ' = ' . $db->escape(trim($filt[1])); } } -if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; +if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$db->escape($search_sale); if ($search_user > 0) { $sql.= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='invoice_supplier' AND tc.source='internal' AND ec.element_id = f.rowid AND ec.fk_socpeople = ".$search_user; diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 7194aae65ac..5a6c39840ac 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -41,6 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/holiday/common.inc.php'; $myparam = GETPOST("myparam"); $action=GETPOST('action', 'alpha'); $id=GETPOST('id', 'int'); +$fuserid = (GETPOST('fuserid','int')?GETPOST('fuserid','int'):$user->id); // Protection if external user if ($user->societe_id > 0) accessforbidden(); diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql index cce279d79da..b805b9f8014 100644 --- a/htdocs/install/mysql/data/llx_c_tva.sql +++ b/htdocs/install/mysql/data/llx_c_tva.sql @@ -88,6 +88,8 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 9 -- CYPRUS (id country=78) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (781, 78, '19','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (782, 78, '9','0','VAT Rate 9',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (783, 78, '5','0','VAT Rate 5',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (784, 78, '0','0','VAT Rate 0',1); -- DANMERK (id country=80) @@ -133,13 +135,16 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 3 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 34, 3, '0','0','VAT Rate 0',1); -- INDIA (id country=117) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '12.5','0','VAT standard rate', 0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1172, 117, '4','0','VAT reduced rate', 0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1173, 117, '1','0','VAT super-reduced rate',0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1174, 117, '0','0','VAT Rate 0', 0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '0','0','VAT Rate 0', 0); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'CGST+SGST', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'IGST' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1178, 117, 'C+S-5', 0, 2.5, '1', 2.5, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1179, 117, 'I-5' , 5, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1180, 117, 'C+S-12', 0, 6, '1', 6, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1181, 117, 'I-12' , 12, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'C+S-18', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'I-18' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1182, 117, 'C+S-28', 0, 14, '1', 14, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1183, 117, 'I-28' , 28, 0, '0', 0, '0', 0, 'IGST', 1); -- IRELAND (id country=8) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (81, 8, '0','0','VAT Rate 0',1); diff --git a/htdocs/install/mysql/migration/3.0.0-3.1.0.sql b/htdocs/install/mysql/migration/3.0.0-3.1.0.sql index fa94a5deeed..a4ab666299d 100644 --- a/htdocs/install/mysql/migration/3.0.0-3.1.0.sql +++ b/htdocs/install/mysql/migration/3.0.0-3.1.0.sql @@ -63,7 +63,7 @@ ALTER TABLE llx_facturedet ADD UNIQUE INDEX uk_fk_remise_except (fk_remise_excep ALTER TABLE llx_societe ADD COLUMN fk_currency integer DEFAULT 0 AFTER fk_forme_juridique; ALTER TABLE llx_societe ADD COLUMN status tinyint DEFAULT 1; -ALTER TABLE llx_societe ADD COLUMN logo varchar(255); +ALTER TABLE llx_societe ADD COLUMN logo varchar(255) DEFAULT NULL; ALTER TABLE llx_societe_remise MODIFY remise_client double(6,3) DEFAULT 0 NOT NULL; diff --git a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql index 25a92f1e265..175e03ec179 100644 --- a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql +++ b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql @@ -4,6 +4,7 @@ -- when current version is 5.0.0 or higher. -- -- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- -- VPGSQL8.2 ALTER SEQUENCE IF EXISTS llx_table_rowid_seq RENAME TO llx_table_new_rowid_seq; -- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; -- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); -- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; @@ -121,6 +122,8 @@ create table llx_expensereport_extrafields ALTER TABLE llx_expensereport_extrafields ADD INDEX idx_expensereport_extrafields (fk_object); ALTER TABLE llx_cotisation RENAME TO llx_subscription; +-- VPGSQL8.2 ALTER SEQUENCE IF EXISTS llx_cotisation_rowid_seq RENAME TO llx_subscription_rowid_seq; + ALTER TABLE llx_subscription ADD UNIQUE INDEX uk_subscription (fk_adherent,dateadh); ALTER TABLE llx_subscription CHANGE COLUMN cotisation subscription real; ALTER TABLE llx_adherent_type CHANGE COLUMN cotisation subscription varchar(3) NOT NULL DEFAULT '1'; diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index c51925fa7dc..4e3272a88c9 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -338,6 +338,7 @@ UPDATE llx_const SET value = __ENCRYPT('moono-lisa')__ WHERE value = __ENCRYPT DELETE FROM llx_document_model where nom = 'fsfe.fr.php' and type='donation'; ALTER TABLE llx_product_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; +ALTER TABLE llx_product_customer_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; ALTER TABLE llx_product_fournisseur_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; ALTER TABLE llx_user ADD COLUMN model_pdf varchar(255); @@ -617,5 +618,11 @@ CREATE TABLE llx_facturedet_rec_extrafields ALTER TABLE llx_facturedet_rec_extrafields ADD INDEX idx_facturedet_rec_extrafields (fk_object); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'CGST+SGST', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'IGST' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1178, 117, 'C+S-5', 0, 2.5, '1', 2.5, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1179, 117, 'I-5' , 5, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1180, 117, 'C+S-12', 0, 6, '1', 6, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1181, 117, 'I-12' , 12, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'C+S-18', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'I-18' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1182, 117, 'C+S-28', 0, 14, '1', 14, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1183, 117, 'I-28' , 28, 0, '0', 0, '0', 0, 'IGST', 1); diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index 33b6816d96f..f3e77278719 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -41,6 +41,11 @@ ALTER TABLE llx_website_page ADD COLUMN fk_user_modif integer; -- For 7.0 +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax1_tx double(6,3) DEFAULT 0; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax1_type varchar(10) NOT NULL DEFAULT '0'; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax2_tx double(6,3) DEFAULT 0; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax2_type varchar(10) NOT NULL DEFAULT '0'; + insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SENTBYMAIL','Mails sent from member card','Executed when you send email from member card','member',23); diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index f341b103edb..1c86bfe04f8 100755 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -38,6 +38,10 @@ create table llx_product_fournisseur_price unitcharges double(24,8) DEFAULT 0, -- deprecated default_vat_code varchar(10), tva_tx double(6,3) NOT NULL, + localtax1_tx double(6,3) DEFAULT 0, + localtax1_type varchar(10) NOT NULL DEFAULT '0', + localtax2_tx double(6,3) DEFAULT 0, + localtax2_type varchar(10) NOT NULL DEFAULT '0', info_bits integer NOT NULL DEFAULT 0, fk_user integer, fk_supplier_price_expression integer, -- Link to the rule for dynamic price calculation diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index 20440b692d7..0f0cb437750 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -95,13 +95,13 @@ create table llx_societe barcode varchar(255), -- barcode fk_barcode_type integer NULL DEFAULT 0, -- barcode type price_level integer NULL, -- level of price for multiprices - outstanding_limit double(24,8) DEFAULT NULL, -- allowed outstanding limit + outstanding_limit double(24,8) DEFAULT NULL, -- allowed outstanding limit default_lang varchar(6), -- default language - logo varchar(255), - canvas varchar(32), -- type of canvas if used (null by default) + logo varchar(255) DEFAULT NULL, + canvas varchar(32) DEFAULT NULL, -- type of canvas if used (null by default) import_key varchar(14), -- import key - webservices_url varchar(255), -- supplier webservice url - webservices_key varchar(128), -- supplier webservice key + webservices_url varchar(255), -- supplier webservice url + webservices_key varchar(128), -- supplier webservice key fk_multicurrency integer, multicurrency_code varchar(255) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 7aefde7340c..3c10edc86ca 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1253,6 +1253,7 @@ LDAPUsersSynchro=Users LDAPGroupsSynchro=Groups LDAPContactsSynchro=Contacts LDAPMembersSynchro=Members +LDAPMembersTypesSynchro=Members types LDAPSynchronization=LDAP synchronisation LDAPFunctionsNotAvailableOnPHP=LDAP functions are not available on your PHP LDAPToDolibarr=LDAP -> Dolibarr @@ -1261,7 +1262,8 @@ LDAPNamingAttribute=Key in LDAP LDAPSynchronizeUsers=Organization of users in LDAP LDAPSynchronizeGroups=Organization of groups in LDAP LDAPSynchronizeContacts=Organization of contacts in LDAP -LDAPSynchronizeMembers=Organization of foundation's members in LDAP +LDAPSynchronizeMembers=Organization of foundation's members in LDAP +LDAPSynchronizeMembersTypes=Organization of foundation's members types in LDAP LDAPPrimaryServer=Primary server LDAPSecondaryServer=Secondary server LDAPServerPort=Server port @@ -1285,12 +1287,18 @@ LDAPDnContactActive=Contacts' synchronization LDAPDnContactActiveExample=Activated/Unactivated synchronization LDAPDnMemberActive=Members' synchronization LDAPDnMemberActiveExample=Activated/Unactivated synchronization +LDAPDnMemberTypeActive=Members types' synchronization +LDAPDnMemberTypeActiveExample=Activated/Unactivated synchronization LDAPContactDn=Dolibarr contacts' DN LDAPContactDnExample=Complete DN (ex: ou=contacts,dc=example,dc=com) LDAPMemberDn=Dolibarr members DN LDAPMemberDnExample=Complete DN (ex: ou=members,dc=example,dc=com) LDAPMemberObjectClassList=List of objectClass LDAPMemberObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) +LDAPMemberTypeDn=Dolibarr members types DN +LDAPMemberTypepDnExample=Complete DN (ex: ou=memberstypes,dc=example,dc=com) +LDAPMemberTypeObjectClassList=List of objectClass +LDAPMemberTypeObjectClassListExample=List of objectClass defining record attributes (ex: top,groupOfUniqueNames) LDAPUserObjectClassList=List of objectClass LDAPUserObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) LDAPGroupObjectClassList=List of objectClass @@ -1302,6 +1310,7 @@ LDAPTestSynchroContact=Test contacts synchronization LDAPTestSynchroUser=Test user synchronization LDAPTestSynchroGroup=Test group synchronization LDAPTestSynchroMember=Test member synchronization +LDAPTestSynchroMemberType=Test member type synchronization LDAPTestSearch= Test a LDAP search LDAPSynchroOK=Synchronization test successful LDAPSynchroKO=Failed synchronization test @@ -1367,6 +1376,7 @@ LDAPDescContact=This page allows you to define LDAP attributes name in LDAP tree LDAPDescUsers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr users. LDAPDescGroups=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr groups. LDAPDescMembers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members module. +LDAPDescMembersTypes=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members types. LDAPDescValues=Example values are designed for OpenLDAP with following loaded schemas: core.schema, cosine.schema, inetorgperson.schema). If you use thoose values and OpenLDAP, modify your LDAP config file slapd.conf to have all thoose schemas loaded. ForANonAnonymousAccess=For an authenticated access (for a write access for example) PerfDolibarr=Performance setup/optimizing report @@ -1390,7 +1400,7 @@ CompressionOfResources=Compression of HTTP responses CompressionOfResourcesDesc=For exemple using the Apache directive "AddOutputFilterByType DEFLATE" TestNotPossibleWithCurrentBrowsers=Such an automatic detection is not possible with current browsers DefaultValuesDesc=You can define/force here the default value you want to get when your create a new record, and/or defaut filters or sort order when your list record. -DefaultCreateForm=Default values for new objects +DefaultCreateForm=Default values for creation form DefaultSearchFilters=Default search filters DefaultSortOrder=Default sort orders DefaultFocus=Default focus fields diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 124aca73d1b..b61d81c6d48 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -104,6 +104,7 @@ ErrorForbidden2=Permission for this login can be defined by your Dolibarr admini ErrorForbidden3=It seems that Dolibarr is not used through an authenticated session. Take a look at Dolibarr setup documentation to know how to manage authentications (htaccess, mod_auth or other...). ErrorNoImagickReadimage=Class Imagick is not found in this PHP. No preview can be available. Administrators can disable this tab from menu Setup - Display. ErrorRecordAlreadyExists=Record already exists +ErrorLabelAlreadyExists=This label already exists ErrorCantReadFile=Failed to read file '%s' ErrorCantReadDir=Failed to read directory '%s' ErrorBadLoginPassword=Bad value for login or password diff --git a/htdocs/langs/en_US/ldap.lang b/htdocs/langs/en_US/ldap.lang index 42e699de311..d6360f3e540 100644 --- a/htdocs/langs/en_US/ldap.lang +++ b/htdocs/langs/en_US/ldap.lang @@ -6,6 +6,7 @@ LDAPInformationsForThisContact=Information in LDAP database for this contact LDAPInformationsForThisUser=Information in LDAP database for this user LDAPInformationsForThisGroup=Information in LDAP database for this group LDAPInformationsForThisMember=Information in LDAP database for this member +LDAPInformationsForThisMemberType=Information in LDAP database for this member type LDAPAttributes=LDAP attributes LDAPCard=LDAP card LDAPRecordNotFound=Record not found in LDAP database @@ -20,6 +21,7 @@ LDAPFieldSkypeExample=Example : skypeName UserSynchronized=User synchronized GroupSynchronized=Group synchronized MemberSynchronized=Member synchronized +MemberTypeSynchronized=Member type synchronized ContactSynchronized=Contact synchronized ForceSynchronize=Force synchronizing Dolibarr -> LDAP ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility. diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 7475d1194eb..93616b6151c 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -376,12 +376,15 @@ VATIN=IGST VATs=Sales taxes VATINs=IGST taxes LT1=Sales tax 2 +LT1Type=Sales tax 2 type LT2=Sales tax 3 +LT2Type=Sales tax 3 type LT1ES=RE LT2ES=IRPF LT1IN=CGST LT2IN=SGST VATRate=Tax Rate +DefaultTaxRate=Default tax rate Average=Average Sum=Sum Delta=Delta diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 5e7ad30ec3f..dc25d792517 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -57,6 +57,11 @@ NewCotisation=New contribution PaymentSubscription=New contribution payment SubscriptionEndDate=Subscription's end date MembersTypeSetup=Members type setup +MemberTypeModified=Member type modified +DeleteAMemberType=Delete a member type +ConfirmDeleteMemberType=Are you sure you want to delete this member type? +MemberTypeDeleted=Member type deleted +MemberTypeCanNotBeDeleted=Member type can not be deleted NewSubscription=New subscription NewSubscriptionDesc=This form allows you to record your subscription as a new member of the foundation. If you want to renew your subscription (if already a member), please contact foundation board instead by email %s. Subscription=Subscription diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang index fcf84791a1f..bd19ab1b0e9 100644 --- a/htdocs/langs/en_US/multicurrency.lang +++ b/htdocs/langs/en_US/multicurrency.lang @@ -17,3 +17,4 @@ rate=rate MulticurrencyReceived=Received, original currency MulticurrencyRemainderToTake=Remaining amout, original currency MulticurrencyPaymentAmount=Payment amount, original currency +AmountToOthercurrency=Amount To (in currency of receiving account) \ No newline at end of file diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 6bc5d842a8e..b324154e9d0 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -152,7 +152,7 @@ BuyingPrices=Buying prices CustomerPrices=Customer prices SuppliersPrices=Supplier prices SuppliersPricesOfProductsOrServices=Supplier prices (of products or services) -CustomCode=Customs code +CustomCode=Customs/Commodity/HS code CountryOrigin=Origin country Nature=Nature ShortLabel=Short label diff --git a/htdocs/langs/en_US/supplier_proposal.lang b/htdocs/langs/en_US/supplier_proposal.lang index dc3eae23672..d5b51978920 100644 --- a/htdocs/langs/en_US/supplier_proposal.lang +++ b/htdocs/langs/en_US/supplier_proposal.lang @@ -1,7 +1,7 @@ # Dolibarr language file - Source file is en_US - supplier_proposal SupplierProposal=Supplier commercial proposals supplier_proposalDESC=Manage price requests to suppliers -SupplierProposalNew=New request +SupplierProposalNew=New price request CommRequest=Price request CommRequests=Price requests SearchRequest=Find a request diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 259db698024..4a5f349215b 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -324,6 +324,17 @@ class MyObject extends CommonObject return $result; } + /** + * Return link to download file from a direct external access + * + * @param int $withpicto Add download picto into link + * @return string HTML link to file + */ + function getDirectExternalLink($withpicto=0) + { + return 'todo'; + } + /** * Retourne le libelle du status d'un user (actif, inactif) * diff --git a/htdocs/product/admin/product_tools.php b/htdocs/product/admin/product_tools.php index 85351a0fb2a..f19f672a25e 100644 --- a/htdocs/product/admin/product_tools.php +++ b/htdocs/product/admin/product_tools.php @@ -38,8 +38,8 @@ $langs->load("products"); if (! $user->admin) accessforbidden(); $action = GETPOST('action','alpha'); -$oldvatrate=GETPOST('oldvatrate'); -$newvatrate=GETPOST('newvatrate'); +$oldvatrate=GETPOST('oldvatrate', 'alpha'); +$newvatrate=GETPOST('newvatrate', 'alpha'); //$price_base_type=GETPOST('price_base_type'); @@ -67,13 +67,31 @@ if ($action == 'convert') $db->begin(); + // Clean vat code old + $vat_src_code_old=''; + if (preg_match('/\((.*)\)/', $oldvatrate, $reg)) + { + $vat_src_code_old = $reg[1]; + $oldvatrateclean = preg_replace('/\s*\(.*\)/', '', $oldvatrate); // Remove code into vatrate. + } + + // Clean vat code new + $vat_src_code_new=''; + if (preg_match('/\((.*)\)/', $newvatrate, $reg)) + { + $vat_src_code_new = $reg[1]; + $newvatrateclean = preg_replace('/\s*\(.*\)/', '', $newvatrate); // Remove code into vatrate. + } + // If country to edit is my country, so we change customer prices if ($country_id == $mysoc->country_id) { $sql = 'SELECT rowid'; $sql.= ' FROM '.MAIN_DB_PREFIX.'product'; $sql.= ' WHERE entity IN ('.getEntity('product').')'; - $sql.= " AND tva_tx = '".$db->escape($oldvatrate)."'"; + $sql.= " AND tva_tx = '".$db->escape($oldvatrateclean)."'"; + if ($vat_src_code_old) $sql.= " AND default_vat_code = '".$vat_src_code_old."'"; + else " AND default_vat_code = IS NULL"; $resql=$db->query($sql); if ($resql) @@ -109,12 +127,15 @@ if ($action == 'convert') $newminprice=$objectstatic->multiprices_min[$level]; } if ($newminprice > $newprice) $newminprice=$newprice; + $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); $newnpr=$objectstatic->multiprices_recuperableonly[$level]; + $newdefaultvatcode=$vat_src_code_new; $newlevel=$level; //print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
\n"; - $retm=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvat, $newminprice, $newlevel, $newnpr); + $retm=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatratclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode); if ($retm < 0) { $error++; @@ -138,19 +159,21 @@ if ($action == 'convert') } if ($newminprice > $newprice) $newminprice=$newprice; $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); $newnpr=$objectstatic->recuperableonly; + $newdefaultvatcode=$vat_src_code_new; $newlevel=0; if (! empty($price_base_type) && ! $updatelevel1) { //print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
\n"; - $ret=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvat, $newminprice, $newlevel, $newnpr); + $ret=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatrateclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode); } if ($ret < 0 || $retm < 0) $error++; else $nbrecordsmodified++; } unset($objectstatic); - + $i++; } } @@ -164,6 +187,8 @@ if ($action == 'convert') $sql.= ' FROM '.MAIN_DB_PREFIX.'product_fournisseur_price as pfp, '.MAIN_DB_PREFIX.'societe as s'; $sql.= ' WHERE pfp.fk_soc = s.rowid AND pfp.entity IN ('.getEntity('product').')'; $sql.= " AND tva_tx = '".$db->escape($oldvatrate)."'"; + if ($vat_src_code_old) $sql.= " AND default_vat_code = '".$vat_src_code_old."'"; + else " AND default_vat_code = IS NULL"; $sql.= " AND s.fk_pays = '".$country_id."'"; //print $sql; $resql=$db->query($sql); @@ -196,26 +221,33 @@ if ($action == 'convert') //} //if ($newminprice > $newprice) $newminprice=$newprice; $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); //$newnpr=$objectstatic2->recuperableonly; + $newnpr=0; + $newdefaultvatcode=$vat_src_code_new; + + $newpercent = $objectstatic2->fourn_remise_percent; + $newdeliverydelay = $objectstatic2->delivery_time_days; + $newsupplierreputation = $objectstatic2->supplier_reputation; + $newlevel=0; if (! empty($price_base_type) && ! $updatelevel1) { //print "$objectstatic2->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
\n"; $fourn->id=$obj->fk_soc; - $ret=$objectstatic2->update_buyprice($obj->qty, $newprice, $user, $price_base_type, $fourn, $obj->fk_availability, $obj->ref_fourn, $newvat); + $ret=$objectstatic2->update_buyprice($obj->qty, $newprice, $user, $price_base_type, $fourn, $obj->fk_availability, $obj->ref_fourn, $newvat, '', $newpercent, 0, $newnpr, $newdeliverydelay, $newsupplierreputation, $localtaxes_type, $newdefaultvatcode); } if ($ret < 0 || $retm < 0) $error++; else $nbrecordsmodified++; } unset($objectstatic2); - + $i++; } } else dol_print_error($db); - if (! $error) { $db->commit(); @@ -274,24 +306,24 @@ else print '
'.$langs->trans("Value").'
'.$langs->trans("OldVATRates").''."\n"; - print $form->load_tva('oldvatrate', $oldvatrate, $mysoc); + print $form->load_tva('oldvatrate', $oldvatrate, $mysoc, null, 0, 0, '', false, 1); print '
'.$langs->trans("NewVATRates").''."\n"; - print $form->load_tva('newvatrate', $newvatrate, $mysoc); + print $form->load_tva('newvatrate', $newvatrate, $mysoc, null, 0, 0, '', false, 1); print '
'.$langs->trans("PriceBaseTypeToChange").''."\n"; @@ -303,7 +335,7 @@ else print '
'; print '
'; - + // Boutons actions print '
'; print ''; diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php index 3b83ae6b858..5b41cb0f02b 100644 --- a/htdocs/product/class/productcustomerprice.class.php +++ b/htdocs/product/class/productcustomerprice.class.php @@ -329,6 +329,8 @@ class Productcustomerprice extends CommonObject $sql .= " t.recuperableonly,"; $sql .= " t.localtax1_tx,"; $sql .= " t.localtax2_tx,"; + $sql .= " t.localtax1_type,"; + $sql .= " t.localtax2_type,"; $sql .= " t.fk_user,"; $sql .= " t.import_key,"; $sql .= " soc.nom as socname,"; @@ -386,6 +388,8 @@ class Productcustomerprice extends CommonObject $line->recuperableonly = $obj->recuperableonly; $line->localtax1_tx = $obj->localtax1_tx; $line->localtax2_tx = $obj->localtax2_tx; + $line->localtax1_type = $obj->localtax1_type; + $line->localtax2_type = $obj->localtax2_type; $line->fk_user = $obj->fk_user; $line->import_key = $obj->import_key; $line->socname = $obj->socname; diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index dada74a2c59..a4012b7d3c4 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -208,7 +208,7 @@ if ($id > 0 || ! empty($ref)) $shownav = 1; if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0; - dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', '', '', '', 0, '', '', 1); + dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', '', '', '', 0, '', '', 0); if ($object->type!=Product::TYPE_SERVICE || empty($conf->global->PRODUIT_MULTIPRICES)) { diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index ed53163615d..cb295012795 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -472,7 +472,9 @@ if ($id > 0 || $ref) $default_vat=$object->tva_tx; } } - print ''; + $vattosuggest=(GETPOST("tva_tx")?vatrate(GETPOST("tva_tx")):($default_vat!=''?vatrate($default_vat):'')); + $vattosuggest=preg_replace('/\s*\(.*\)$/','', $vattosuggest); + print ''; print ''; if (! empty($conf->dynamicprices->enabled)) //Only show price mode and expression selector if module is enabled diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index c5eca27b348..dae399a9907 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -1,6 +1,5 @@ - * Copyright (C) ---Put here your own copyright and developer email--- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,43 +16,14 @@ */ /** - * \file product/inventory/card.php + * \file htdocs/product/inventory/card.php * \ingroup inventory - * \brief This file is an example of a php page - * Put here some comments + * \brief Inventory card */ -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) - -// Load Dolibarr environment -$res=0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"); -// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME -$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1; -while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; } -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php"); -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php"); -// Try main.inc.php using relative path -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php"); -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php"); -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php"); -if (! $res) die("Include of main fails"); - -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); -dol_include_once('/inventory/class/inventory.class.php'); +require '../../main.inc.php'; +include_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; // Load traductions files requiredby by page $langs->loadLangs(array("inventory","other")); @@ -572,7 +542,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formmail->withdeliveryreceipt = 1; $formmail->withcancel = 1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit ['__ORDERREF__'] = $object->ref; $custcontact = ''; diff --git a/htdocs/product/inventory/list.php b/htdocs/product/inventory/list.php index 6f443324f6b..a8ce9c404e6 100644 --- a/htdocs/product/inventory/list.php +++ b/htdocs/product/inventory/list.php @@ -1,6 +1,5 @@ - * Copyright (C) ---Put here your own copyright and developer email--- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,45 +16,16 @@ */ /** - * \file product/inventory/list.php + * \file htdocs/product/inventory/list.php * \ingroup inventory - * \brief List page for monmodule + * \brief List page for inventory */ -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) - - -// Load Dolibarr environment -$res=0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"); -// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME -$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1; -while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; } -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php"); -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php"); -// Try main.inc.php using relative path -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php"); -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php"); -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php"); -if (! $res) die("Include of main fails"); - -require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -dol_include_once('/inventory/class/inventory.class.php'); +require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; // Load traductions files requiredby by page $langs->loadLangs(array("inventory","other")); @@ -177,7 +147,7 @@ if (empty($reshook)) $permtoread = $user->rights->inventory->read; $permtodelete = $user->rights->inventory->delete; $uploaddir = $conf->inventory->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + //include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; // TODO to fix for product module } diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 7c58069585e..af9fa2a927f 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -107,8 +107,15 @@ if (empty($reshook)) $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' // We must define tva_tx, npr and local taxes + $tva_tx = $tva_tx_txt; $vatratecode = ''; - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -217,8 +224,15 @@ if (empty($reshook)) $tva_tx_txt = $newvattx[$i]; + $tva_tx = $tva_tx_txt; $vatratecode = ''; - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = $newlocaltax1_tx[$i]; $localtax1_type = $newlocaltax1_type[$i]; @@ -266,9 +280,15 @@ if (empty($reshook)) { $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' + $tva_tx = $tva_tx_txt; $vatratecode = ''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -280,7 +300,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -469,11 +489,17 @@ if (empty($reshook)) $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); - $tva_tx_txt = GETPOST("tva_tx"); + $tva_tx_txt = GETPOST("tva_tx",'alpha'); + $tva_tx = $tva_tx_txt; $vatratecode = ''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -485,7 +511,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -565,9 +591,15 @@ if (empty($reshook)) $tva_tx_txt = GETPOST("tva_tx"); - $vatratecode=''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + $tva_tx = $tva_tx_txt; + $vatratecode = ''; + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -579,7 +611,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -712,17 +744,34 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // TVA - print '' . $langs->trans("VATRate") . '' . vatrate($object->multiprices_tva_tx[$soc->price_level], true) . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; + + $positiverates=''; + if (price2num($object->multiprices_tva_tx[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_tva_tx[$soc->price_level]); + if (price2num($object->multiprices_localtax1_type[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_localtax1_tx[$soc->price_level]); + if (price2num($object->multiprices_localtax2_type[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_localtax2_tx[$soc->price_level]); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + //print vatrate($object->multiprices_tva_tx[$soc->price_level], true); + print ''; } else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true); + else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/ print ''; } @@ -732,19 +781,27 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // We show only vat for level 1 - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; print '' . vatrate($object->multiprices_tva_tx[1], true) . ''; print ''; } else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true); + else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/ print ''; } print ''; @@ -888,12 +945,20 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx, true, $object->tva_npr, true); + else print vatrate($object->tva_tx, true, $object->tva_npr, true);*/ print ''; // Price @@ -1058,7 +1123,7 @@ if ($action == 'edit_vat' && ($user->rights->produit->creer || $user->rights->se print ''; // VAT - print ''; @@ -1092,7 +1157,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) print '
' . $langs->trans("VATRate") . ''; + print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
'; // VAT - print ''; @@ -1233,7 +1298,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) print ''; - if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) print ''; + if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) print ''; else print ''; print ''; @@ -1317,7 +1382,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_price') && ! in_array($action, array('edit_price','edit_vat'))) { - $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.recuperableonly,"; + $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.recuperableonly, p.localtax1_tx, p.localtax1_type, p.localtax2_tx, p.localtax2_type,"; $sql .= " p.price_level, p.price_min, p.price_min_ttc,p.price_by_qty,"; $sql .= " p.date_price as dp, p.fk_price_expression, u.rowid as user_id, u.login"; $sql .= " FROM " . MAIN_DB_PREFIX . "product_price as p,"; @@ -1374,7 +1439,7 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_ print ''; print $conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL; - if (empty($conf->global->PRODUIT_MULTIPRICES)) print ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) print ''; print ''; print ''; if (! empty($conf->dynamicprices->enabled)) { @@ -1413,11 +1478,19 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_ if (empty($conf->global->PRODUIT_MULTIPRICES)) { print '"; } @@ -1533,7 +1606,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; // VAT - print ''; @@ -1622,7 +1695,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; // VAT - print ''; @@ -1726,7 +1799,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; @@ -1770,7 +1843,17 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ""; print ""; print '"; - print '"; + print '"; print '"; print '"; @@ -1837,7 +1920,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; @@ -1874,8 +1957,16 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '"; print '"; print '"; @@ -1940,7 +2031,16 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ""; print '"; - print '"; + print '"; print '"; print '"; diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 55fe5908c7f..2811ccce891 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -357,17 +357,17 @@ if ($usevirtualstock) if ($salert == 'on') // Option to see when stock is lower than alert { - $sql.= ' AND ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')'; + $sql.= ' AND ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')'; $sql.= ' - ('.$sqlCommandesCli.' - '.$sqlExpeditionsCli.') + ('.$sqlCommandesFourn.' - '.$sqlReceptionFourn.')))'; $alertchecked = 'checked'; } } else { - $sql.= ' HAVING (('.$sqldesiredtock.' > 0 AND ('.$sqldesiredtock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; - $sql.= ' OR ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").'))))'; + $sql.= ' HAVING (('.$sqldesiredtock.' >= 0 AND ('.$sqldesiredtock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; + $sql.= ' OR ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").'))))'; if ($salert == 'on') // Option to see when stock is lower than alert { - $sql.= ' AND ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; + $sql.= ' AND ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; $alertchecked = 'checked'; } } diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index 004662972c4..791da80c05d 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -205,7 +205,7 @@ $linkback = ''.$langs->trans("BackTo $shownav = 1; if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0; -dol_banner_tab($object, 'ref', $linkback, shownav, 'ref'); +dol_banner_tab($object, 'ref', $linkback, shownav, 'ref', '', '', '', 0, '', '', 1); dol_fiche_end(); diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 98efb786f72..1b5c11df748 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -135,6 +135,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', { $search_ref=""; $search_label=""; + $search_type=""; $search_array_options=array(); $filter=array(); } @@ -163,14 +164,7 @@ if ($action == 'delete_resource') print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1); } -// Load object list -$ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset, $filter); -if($ret == -1) { - dol_print_error($db,$object->error); - exit; -} else { - print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $ret+1, $object->num_all,'title_generic.png'); -} + $var=true; @@ -187,6 +181,26 @@ print ''; print ''; print ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $ret = $object->fetch_all('', '', 0, 0, $filter); + if($ret == -1) { + dol_print_error($db,$object->error); + exit; + } else { + $nbtotalofrecords = $ret; + } +} + +// Load object list +$ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset, $filter); +if($ret == -1) { + dol_print_error($db,$object->error); + exit; +} else { + print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $ret+1, $nbtotalofrecords,'title_generic.png', 0, '', '', $limit); +} + $moreforfilter = ''; print '
'; diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 3b56046e55f..236faaaa232 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -2485,7 +2485,7 @@ else $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Array of substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit['__THIRDPARTY_ID__']=$object->id; // substit in setSubstitFromObject was wrong for this one $formmail->substit['__THIRDPARTY_NAME__']=$object->name; // substit in setSubstitFromObject was wrong for this one $formmail->substit['__PERSONALIZED__']=''; // deprecated diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 55a328e2538..56ca7d3042b 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1077,7 +1077,7 @@ class Societe extends CommonObject $sql = 'SELECT s.rowid, s.nom as name, s.name_alias, s.entity, s.ref_ext, s.ref_int, s.address, s.datec as date_creation, s.prefix_comm'; $sql .= ', s.status'; $sql .= ', s.price_level'; - $sql .= ', s.tms as date_modification'; + $sql .= ', s.tms as date_modification, s.fk_user_creat, s.fk_user_modif'; $sql .= ', s.phone, s.fax, s.email, s.skype, s.url, s.zip, s.town, s.note_private, s.note_public, s.model_pdf, s.client, s.fournisseur'; $sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6'; $sql .= ', s.capital, s.tva_intra'; @@ -1144,8 +1144,10 @@ class Societe extends CommonObject $this->ref_ext = $obj->ref_ext; $this->ref_int = $obj->ref_int; - $this->date_creation = $this->db->jdate($obj->date_creation); + $this->date_creation = $this->db->jdate($obj->date_creation); $this->date_modification = $this->db->jdate($obj->date_modification); + $this->user_creation = $obj->fk_user_creat; + $this->user_modification = $obj->fk_user_modif; $this->address = $obj->address; $this->zip = $obj->zip; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index f280a9db89c..5009a668ba3 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -1024,6 +1024,7 @@ while ($i < min($num, $limit)) $companystatic->id=$obj->rowid; $companystatic->name=$obj->name; + $companystatic->name_alias=$obj->name_alias; $companystatic->canvas=$obj->canvas; $companystatic->client=$obj->client; $companystatic->status=$obj->status; @@ -1053,7 +1054,6 @@ while ($i < min($num, $limit)) } if (! empty($arrayfields['s.name_alias']['checked'])) { - $companystatic->name_alias=$obj->name_alias; // Added after the getNomUrl print '
\n"; diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php index 0cc15c7fb60..9aaed7cf0b9 100644 --- a/htdocs/stripe/config.php +++ b/htdocs/stripe/config.php @@ -1,6 +1,7 @@ * Copyright (C) 2017 Saasprov + * Copyright (C) 2017 Ferran Marcet * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +33,7 @@ global $conf; //use \includes\stripe as stripe; $stripe = array(); -if (empty($conf->global->SKYPE_LIVE)) +if (empty($conf->global->STRIPE_LIVE)) { $stripe = array( "secret_key" => $conf->global->STRIPE_TEST_SECRET_KEY, diff --git a/htdocs/theme/eldy/img/stcomm0.png b/htdocs/theme/eldy/img/stcomm0.png index b6c11d4569a..1220cf8113e 100644 Binary files a/htdocs/theme/eldy/img/stcomm0.png and b/htdocs/theme/eldy/img/stcomm0.png differ diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index c1841f6cb9a..71f741a907b 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -689,6 +689,12 @@ div.myavailability { text-overflow: ellipsis; white-space: nowrap; } +.tdoverflowmax200 { /* For tdoverflow, the max-midth become a minimum ! */ + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} .tdoverflowmax300 { /* For tdoverflow, the max-midth become a minimum ! */ max-width: 300px; overflow: hidden; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 64d852b0395..02705f63801 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -700,6 +700,12 @@ div.myavailability { text-overflow: ellipsis; white-space: nowrap; } +.tdoverflowmax200 { /* For tdoverflow, the max-midth become a minimum ! */ + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} .tdoverflowmax300 { max-width: 300px; overflow: hidden; diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 273c71d8e8c..40fa4db7a37 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1760,7 +1760,7 @@ else $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit['__LASTNAME__']=$object->lastname; $formmail->substit['__FIRSTNAME__']=$object->firstname; diff --git a/htdocs/user/group/ldap.php b/htdocs/user/group/ldap.php index c195136863e..ae0d974be9a 100644 --- a/htdocs/user/group/ldap.php +++ b/htdocs/user/group/ldap.php @@ -63,30 +63,31 @@ $object->getrights(); if ($action == 'dolibarr2ldap') { - $db->begin(); - $ldap=new Ldap(); $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); + if ($result > 0) + { + $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We can say that old dn = dn as we force synchro + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } - $result=$ldap->update($dn,$info,$user,$olddn); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We can say that old dn = dn as we force synchro + + $result=$ldap->update($dn,$info,$user,$olddn); + } if ($result >= 0) { setEventMessages($langs->trans("GroupSynchronized"), null, 'mesgs'); - $db->commit(); } else { setEventMessages($ldap->error, $ldap->errors, 'errors'); - $db->rollback(); } } @@ -206,12 +207,10 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print '
' . $langs->trans("VATRate") . ''; + print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
'.$langs->trans("PriceLevel").''.$langs->trans("VATRate").''.$langs->trans("DefaultTaxRate").''.$langs->trans("SellingPrice").'' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . ''; + + $positiverates=''; + if (price2num($objp->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($objp->tva_tx); + if (price2num($objp->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax1_tx); + if (price2num($objp->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($objp->default_vat_code?' ('.$objp->default_vat_code.')':''), '%', $objp->tva_npr); + /* if ($objp->default_vat_code) { print vatrate($objp->tva_tx, true) . ' ('.$objp->default_vat_code.')'; } - else print vatrate($objp->tva_tx, true, $objp->recuperableonly); + else print vatrate($objp->tva_tx, true, $objp->recuperableonly);*/ print "
' . $langs->trans("VATRate") . ''; + print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
' . $langs->trans("VATRate") . ''; + print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $prodcustprice->default_vat_code ? $prodcustprice->tva_tx.' ('.$prodcustprice->default_vat_code.')' : $prodcustprice->tva_tx, $mysoc, '', $object->id, $prodcustprice->recuperableonly, $object->type, false, 1); print '
' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '" . $staticsoc->getNomUrl(1) . "" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "' . vatrate($tva_tx, true, $line->recuperableonly) . "'; +var_dump($prodcustprice);exit; + $positiverates=''; + if (price2num($objp->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($objp->tva_tx); + if (price2num($objp->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax1_tx); + if (price2num($objp->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($objp->default_vat_code?' ('.$objp->default_vat_code.')':''), '%', $objp->tva_npr); + + //. vatrate($tva_tx, true, $line->recuperableonly) . + print "' . price($line->price) . "' . price($line->price_ttc) . "' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '' . $langs->trans($object->price_base_type) . "'; - print vatrate($object->tva_tx, true, $object->recuperableonly); - print $object->default_vat_code?' ('.$object->default_vat_code.')':''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + + //print vatrate($object->tva_tx, true, $object->tva_npr); + //print $object->default_vat_code?' ('.$object->default_vat_code.')':''; print "' . price($object->price) . "" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "' . vatrate($tva_tx, true, $line->recuperableonly) . "'; + + $positiverates=''; + if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); + if (price2num($line->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); + if (price2num($line->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($line->default_vat_code?' ('.$line->default_vat_code.')':''), '%', $line->tva_npr); + + print "' . price($line->price) . "' . price($line->price_ttc) . "'; print $companystatic->name_alias; print "
'; llxFooter(); - $db->close(); - diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php index 49739fa7c77..001915a8004 100644 --- a/htdocs/user/ldap.php +++ b/htdocs/user/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2015 Regis Houssin + * Copyright (C) 2006-2017 Regis Houssin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -214,7 +214,7 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; diff --git a/htdocs/variants/admin/admin.php b/htdocs/variants/admin/admin.php index eedacb086b3..f3752469538 100644 --- a/htdocs/variants/admin/admin.php +++ b/htdocs/variants/admin/admin.php @@ -37,6 +37,12 @@ if ($_POST) { setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); } + if (dolibarr_set_const($db, 'PRODUIT_ATTRIBUTES_SEPARATOR', GETPOST('PRODUIT_ATTRIBUTES_SEPARATOR'), 'chaine', 0, '', $conf->entity)) { + setEventMessage($langs->trans('RecordSaved')); + } else { + setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); + } + } $title = $langs->trans('ModuleSetup').' '.$langs->trans('ProductAttributes'); @@ -55,6 +61,13 @@ print ''.$langs->trans("Value").''."\n"; print ' '."\n"; print ''.$langs->trans('HideProductCombinations').''; print $form->selectyesno("PRODUIT_ATTRIBUTES_HIDECHILD",$conf->global->PRODUIT_ATTRIBUTES_HIDECHILD,1).''; +print ''.$langs->trans('CombinationsSeparator').''; +if(isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { + $separator = $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR; +} else { + $separator = "_"; +} +print ''; print ''; print '
'; print ''; diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index d3e6964aea6..04b987192e1 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -476,7 +476,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; */ public function createProductCombination(Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false) { - global $db, $user; + global $db, $user, $conf; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php'; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'; @@ -542,7 +542,11 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']); } - $newproduct->ref .= '_'.$prodattrval->ref; + if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { + $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; + } else { + $newproduct->ref .= '_'.$prodattrval->ref; + } //The first one should not contain a linebreak if ($newproduct->description) { @@ -660,4 +664,4 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; return 1; } -} \ No newline at end of file +} diff --git a/scripts/members/sync_members_types_dolibarr2ldap.php b/scripts/members/sync_members_types_dolibarr2ldap.php new file mode 100755 index 00000000000..939a98c8728 --- /dev/null +++ b/scripts/members/sync_members_types_dolibarr2ldap.php @@ -0,0 +1,131 @@ +#!/usr/bin/env php + + * Copyright (C) 2006 Laurent Destailleur + * Copyright (C) 2017 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file scripts/user/sync_members_types_dolibarr2ldap.php + * \ingroup ldap core + * \brief Script de mise a jour des types de membres dans LDAP depuis base Dolibarr + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +if (! isset($argv[1]) || ! $argv[1]) { + print "Usage: ".$script_file." now\n"; + exit(-1); +} +$now=$argv[1]; + +require_once($path."../../htdocs/master.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php"); +require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"); + +// Global variables +$version=DOL_VERSION; +$error=0; + + +/* + * Main + */ + +@set_time_limit(0); +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +dol_syslog($script_file." launched with arg ".join(',',$argv)); + +/* +if (! $conf->global->LDAP_SYNCHRO_ACTIVE) +{ + print $langs->trans("LDAPSynchronizationNotSetupInDolibarr"); + exit(-1); +} +*/ + +$sql = "SELECT rowid"; +$sql .= " FROM ".MAIN_DB_PREFIX."adherent_type"; + +$resql = $db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + while ($i < $num) + { + $ldap->error=""; + + $obj = $db->fetch_object($resql); + + $membertype = new AdherentType($db); + $membertype->id = $obj->rowid; + $membertype->fetch($membertype->id); + + print $langs->trans("UpdateMemberType")." rowid=".$membertype->id." ".$membertype-label; + + $oldobject=$membertype; + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + $info=$membertype->_load_ldap_info(); + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); // Wil fail if already exists + $result=$ldap->update($dn,$info,$user,$olddn); + if ($result > 0) + { + print " - ".$langs->trans("OK"); + } + else + { + $error++; + print " - ".$langs->trans("KO").' - '.$ldap->error; + } + print "\n"; + + $i++; + } + + $ldap->unbind(); + $ldap->close(); + } + else { + print $ldap->error; + } +} +else +{ + dol_print_error($db); +} + +exit($error); diff --git a/scripts/members/sync_members_types_ldap2dolibarr.php b/scripts/members/sync_members_types_ldap2dolibarr.php new file mode 100755 index 00000000000..fb8fb160d36 --- /dev/null +++ b/scripts/members/sync_members_types_ldap2dolibarr.php @@ -0,0 +1,221 @@ +#!/usr/bin/env php + + * Copyright (C) 2006-2012 Laurent Destailleur + * Copyright (C) 2013 Maxime Kohlhaas + * Copyright (C) 2017 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file scripts/user/sync_members_types_ldap2dolibarr.php + * \ingroup ldap member + * \brief Script to update members types into Dolibarr from LDAP + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +require_once($path."../../htdocs/master.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php"); +require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"); + +$langs->load("main"); +$langs->load("errors"); + + +// Global variables +$version=DOL_VERSION; +$error=0; +$forcecommit=0; +$confirmed=0; + + +/* + * Main + */ + +@set_time_limit(0); +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +dol_syslog($script_file." launched with arg ".join(',',$argv)); + +// List of fields to get from LDAP +$required_fields = array( + $conf->global->LDAP_KEY_MEMBERS_TYPES, + $conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME, + $conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION, + $conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS +); + +// Remove from required_fields all entries not configured in LDAP (empty) and duplicated +$required_fields=array_unique(array_values(array_filter($required_fields, "dolValidElement"))); + + +if (! isset($argv[1])) { + //print "Usage: $script_file (nocommitiferror|commitiferror) [id_group]\n"; + print "Usage: $script_file (nocommitiferror|commitiferror) [--server=ldapserverhost] [--excludeuser=user1,user2...] [-y]\n"; + exit(-1); +} + +foreach($argv as $key => $val) +{ + if ($val == 'commitiferror') $forcecommit=1; + if (preg_match('/--server=([^\s]+)$/',$val,$reg)) $conf->global->LDAP_SERVER_HOST=$reg[1]; + if (preg_match('/--excludeuser=([^\s]+)$/',$val,$reg)) $excludeuser=explode(',',$reg[1]); + if (preg_match('/-y$/',$val,$reg)) $confirmed=1; +} + +print "Mails sending disabled (useless in batch mode)\n"; +$conf->global->MAIN_DISABLE_ALL_MAILS=1; // On bloque les mails +print "\n"; +print "----- Synchronize all records from LDAP database:\n"; +print "host=".$conf->global->LDAP_SERVER_HOST."\n"; +print "port=".$conf->global->LDAP_SERVER_PORT."\n"; +print "login=".$conf->global->LDAP_ADMIN_DN."\n"; +print "pass=".preg_replace('/./i','*',$conf->global->LDAP_ADMIN_PASS)."\n"; +print "DN to extract=".$conf->global->LDAP_MEMBER_TYPE_DN."\n"; +print 'Filter=('.$conf->global->LDAP_KEY_MEMBERS_TYPES.'=*)'."\n"; +print "----- To Dolibarr database:\n"; +print "type=".$conf->db->type."\n"; +print "host=".$conf->db->host."\n"; +print "port=".$conf->db->port."\n"; +print "login=".$conf->db->user."\n"; +print "database=".$conf->db->name."\n"; +print "----- Options:\n"; +print "commitiferror=".$forcecommit."\n"; +print "Mapped LDAP fields=".join(',',$required_fields)."\n"; +print "\n"; + +if (! $confirmed) +{ + print "Hit Enter to continue or CTRL+C to stop...\n"; + $input = trim(fgets(STDIN)); +} + +if (empty($conf->global->LDAP_MEMBER_TYPE_DN)) +{ + print $langs->trans("Error").': '.$langs->trans("LDAP setup for members types not defined inside Dolibarr"); + exit(-1); +} + + +$ldap = new Ldap(); +$result = $ldap->connect_bind(); +if ($result >= 0) +{ + $justthese=array(); + + + // We disable synchro Dolibarr-LDAP + $conf->global->LDAP_MEMBER_TYPE_ACTIVE=0; + + $ldaprecords = $ldap->getRecords('*',$conf->global->LDAP_MEMBER_TYPE_DN, $conf->global->LDAP_KEY_MEMBERS_TYPES, $required_fields, 0, array($conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)); + if (is_array($ldaprecords)) + { + $db->begin(); + + // Warning $ldapuser has a key in lowercase + foreach ($ldaprecords as $key => $ldapgroup) + { + $membertype = new AdherentType($db); + $membertype->fetch('', $ldapgroup[$conf->global->LDAP_KEY_MEMBERS_TYPES]); + $membertype->label = $ldapgroup[$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME]; + $membertype->description = $ldapgroup[$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION]; + $membertype->entity = $conf->entity; + + //print_r($ldapgroup); + + if ($membertype->id > 0) { // Member type update + print $langs->transnoentities("MemberTypeUpdate").' # '.$key.': name='.$membertype->label; + $res=$membertype->update($user); + + if ($res > 0) + { + print ' --> Updated member type id='.$membertype->id.' name='.$membertype->label; + } + else + { + $error++; + print ' --> '.$res.' '.$membertype->error; + } + print "\n"; + } else { // Member type creation + print $langs->transnoentities("MemberTypeCreate").' # '.$key.': name='.$membertype->label; + $res=$membertype->create($user); + + if ($res > 0) + { + print ' --> Created member type id='.$membertype->id.' name='.$membertype->label; + } + else + { + $error++; + print ' --> '.$res.' '.$membertype->error; + } + print "\n"; + } + + //print_r($membertype); + } + + if (! $error || $forcecommit) + { + if (! $error) print $langs->transnoentities("NoErrorCommitIsDone")."\n"; + else print $langs->transnoentities("ErrorButCommitIsDone")."\n"; + $db->commit(); + } + else + { + print $langs->transnoentities("ErrorSomeErrorWereFoundRollbackIsDone",$error)."\n"; + $db->rollback(); + } + print "\n"; + } + else + { + dol_print_error('',$ldap->error); + $error++; + } +} +else +{ + dol_print_error('',$ldap->error); + $error++; +} + + +exit($error); + + +/** + * Function to say if a value is empty or not + * + * @param string $element Value to test + * @return boolean True of false + */ +function dolValidElement($element) +{ + return (trim($element) != ''); +} + diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index b29f8508a8e..4c92f507f66 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -138,8 +138,8 @@ class AdherentTest extends PHPUnit_Framework_TestCase $localobject=new AdherentType($this->savdb); $localobject->statut=1; - $localobject->libelle='Adherent type test'; - $localobject->cotisation=1; + $localobject->label='Adherent type test'; + $localobject->subscription=1; $localobject->vote=1; $result=$localobject->create($user); print __METHOD__." result=".$result."\n";