+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \file htdocs/multicompany/actions_multicompany.class.php
+ * \ingroup multicompany
+ * \brief File Class multicompany
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+dol_include_once('/multicompany/class/dao_multicompany.class.php', 'DaoMulticompany');
+dol_include_once('/multicompany/lib/multicompany.lib.php');
+
+/**
+ * Class Actions of the module multicompany
+ */
+class ActionsMulticompany
+{
+ /** @var DoliDB */
+ var $db;
+ /** @var DaoMulticompany */
+ var $dao;
+
+ var $mesg;
+ var $error;
+ var $errors=array();
+ //! Numero de l'erreur
+ var $errno = 0;
+
+ var $template_dir;
+ var $template;
+
+ var $label;
+ var $description;
+
+ var $referent;
+
+ var $sharings=array();
+ var $options=array();
+ var $entities=array();
+ var $dict=array();
+ var $tpl=array();
+
+ var $addzero=array();
+ var $sharingelements=array();
+ var $sharingobjects=array();
+ var $sharingdicts=array();
+
+ private $config=array();
+
+ // For Hookmanager return
+ var $resprints;
+ var $results=array();
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $conf;
+
+ $this->db = $db;
+
+ $this->addzero = array(
+ 'user',
+ 'usergroup',
+ 'c_email_templates',
+ 'email_template',
+ 'default_values'
+ );
+
+ // Default sharing elements
+ $this->sharingelements = array(
+ 'thirdparty' => array(
+ 'type' => 'element',
+ 'icon' => 'building',
+ 'active' => true, // for setEntity() function
+ 'disable' => true // disable in options tab
+ ),
+ 'member' => array(
+ 'type' => 'element',
+ 'icon' => 'address-card',
+ 'input' => array(
+ 'global' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'member_type' => array(
+ 'type' => 'element',
+ 'icon' => 'address-card',
+ 'display' => '! empty($conf->global->MULTICOMPANY_MEMBER_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'member' => array(
+ 'showhide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'product' => array(
+ 'type' => 'element',
+ 'icon' => 'cube',
+ 'tooltip' => 'ProductSharingInfo',
+ 'enable' => '(! empty($conf->product->enabled) || ! empty($conf->service->enabled))',
+ 'input' => array(
+ 'global' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ 'active' => true
+ ),
+ 'productprice' => array(
+ 'type' => 'element',
+ 'icon' => 'money',
+ 'tooltip' => 'ProductPriceSharingInfo',
+ 'enable' => '(! empty($conf->product->enabled) || ! empty($conf->service->enabled))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'product' => array(
+ 'showhide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'productsupplierprice' => array(
+ 'type' => 'element',
+ 'icon' => 'money',
+ 'enable' => '((! empty($conf->product->enabled) || ! empty($conf->service->enabled)) && ! empty($conf->fournisseur->enabled))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'product' => array(
+ 'showhide' => true,
+ 'del' => true
+ )
+ ),
+ ),
+ 'stock' => array(
+ 'type' => 'element',
+ 'icon' => 'cubes',
+ //'tooltip' => 'SharingStockInfo',
+ 'enable' => '(! empty($conf->stock->enabled) && (! empty($conf->product->enabled) || ! empty($conf->service->enabled)))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'product' => array(
+ 'showhide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'category' => array(
+ 'type' => 'element',
+ 'icon' => 'paperclip',
+ 'input' => array(
+ 'global' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'agenda' => array(
+ 'type' => 'element',
+ 'icon' => 'calendar',
+ 'input' => array(
+ 'global' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'bankaccount' => array(
+ 'type' => 'element',
+ 'icon' => 'bank',
+ 'input' => array(
+ 'global' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'expensereport' => array(
+ 'type' => 'element',
+ 'icon' => 'edit',
+ 'input' => array(
+ 'global' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'holiday' => array(
+ 'type' => 'element',
+ 'icon' => 'paper-plane-o',
+ 'input' => array(
+ 'global' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'project' => array(
+ 'type' => 'element',
+ 'icon' => 'code-fork',
+ 'input' => array(
+ 'global' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+
+ // Object
+
+ 'proposal' => array(
+ 'type' => 'object',
+ 'icon' => 'file-pdf-o',
+ 'mandatory' => 'thirdparty',
+ 'enable' => '(! empty($conf->propal->enabled) && ! empty($conf->societe->enabled))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'thirdparty' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ 'active' => true
+ ),
+ 'proposalnumber' => array(
+ 'type' => 'objectnumber',
+ 'icon' => 'cogs',
+ 'mandatory' => 'thirdparty',
+ 'tooltip' => 'ProposalNumberSharingInfo',
+ 'enable' => '(! empty($conf->propal->enabled) && ! empty($conf->societe->enabled))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'thirdparty' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'order' => array(
+ 'type' => 'object',
+ 'icon' => 'file-pdf-o', // Font Awesome icon
+ 'mandatory' => 'thirdparty',
+ 'enable' => '(! empty($conf->commande->enabled) && ! empty($conf->societe->enabled))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'thirdparty' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ 'active' => true,
+ //'disable' => true // Disable if not stable
+ ),
+ 'ordernumber' => array(
+ 'type' => 'objectnumber',
+ 'icon' => 'cogs',
+ 'mandatory' => 'thirdparty',
+ 'tooltip' => 'OrderNumberSharingInfo',
+ 'enable' => '(! empty($conf->commande->enabled) && ! empty($conf->societe->enabled))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'thirdparty' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ //'disable' => true
+ ),
+ 'invoice' => array(
+ 'type' => 'object',
+ 'icon' => 'file-pdf-o',
+ 'mandatory' => 'thirdparty',
+ 'enable' => '(! empty($conf->facture->enabled) && ! empty($conf->societe->enabled))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'thirdparty' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ 'active' => true
+ ),
+ 'invoicenumber' => array(
+ 'type' => 'objectnumber',
+ 'icon' => 'cogs',
+ 'mandatory' => 'thirdparty',
+ 'tooltip' => 'InvoiceNumberSharingInfo',
+ 'enable' => '(! empty($conf->facture->enabled) && ! empty($conf->societe->enabled))',
+ 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ ),
+ 'thirdparty' => array(
+ 'showhide' => true,
+ 'hide' => true,
+ 'del' => true
+ )
+ )
+ ),
+ 'supplier_proposal' => array(
+ 'type' => 'object',
+ 'icon' => 'file-pdf-o',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ 'disable' => true
+ ),
+ 'supplier_order' => array(
+ 'type' => 'object',
+ 'icon' => 'file-pdf-o',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ 'disable' => true
+ ),
+ 'supplier_invoice' => array(
+ 'type' => 'object',
+ 'icon' => 'file-pdf-o',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ 'disable' => true
+ ),
+ 'intervention' => array(
+ 'type' => 'object',
+ 'icon' => 'wrench',
+ 'input' => array(
+ 'global' => array(
+ 'hide' => true,
+ 'del' => true
+ )
+ ),
+ 'disable' => true
+ )
+ );
+
+ // Module name if different of object name (eg $conf->commande->enabled)
+ $this->sharingmodulename = array(
+ 'thirdparty' => 'societe',
+ 'proposal' => 'propal',
+ 'proposalnumber' => 'propal',
+ 'order' => 'commande',
+ 'ordernumber' => 'commande',
+ 'invoice' => 'facture',
+ 'invoicenumber' => 'facture',
+ 'product' => (empty($conf->product->enabled) && !empty($conf->service->enabled) ? 'service' : 'product'),
+ 'productprice' => 'product',
+ 'productsupplierprice' => 'product',
+ 'project' => 'projet',
+ 'member' => 'adherent',
+ 'membertype' => 'adherent',
+ 'member_type' => 'adherent', // deprecated
+ //'membertype' => 'member_type', // deprecated
+ 'intervention' => 'ficheinter',
+ 'category' => 'categorie',
+ 'bankaccount' => 'banque',
+ 'bank_account' => 'banque', // deprecated
+ //'bankaccount' => 'banque_account', // deprecated
+ );
+
+ $this->sharingdicts = array(
+ 'c_paiement' => array(
+ 'societe' => array(
+ 'mode_reglement',
+ 'mode_reglement_supplier'
+ ),
+ 'propal' => 'fk_mode_reglement',
+ 'commande' => 'fk_mode_reglement',
+ 'facture' => 'fk_mode_reglement',
+ 'facture_rec' => 'fk_mode_reglement',
+ 'commande_fournisseur' => 'fk_mode_reglement',
+ 'facture_fourn' => 'fk_mode_reglement',
+ 'supplier_proposal' => 'fk_mode_reglement',
+ 'chargesociales' => 'fk_mode_reglement',
+ 'don' => 'fk_payment',
+ 'paiement' => 'fk_paiement',
+ 'paiementfourn' => 'fk_paiement',
+ 'paiement_facture' => 'fk_paiement',
+ 'expensereport' => 'fk_c_paiement',
+ 'paiementcharge' => 'fk_typepaiement',
+ 'tva' => 'fk_typepayment',
+ 'payment_various' => 'fk_typepayment',
+ 'payment_salary' => 'fk_typepayment',
+ 'payment_expensereport' => 'fk_typepayment',
+ 'payment_donation' => 'fk_typepayment',
+ 'loan_schedule' => 'fk_typepayment',
+ 'payment_loan' => 'fk_typepayment'
+ ),
+ 'c_payment_term' => array(
+ 'societe' => array(
+ 'cond_reglement',
+ 'cond_reglement_supplier'
+ ),
+ 'propal' => 'fk_cond_reglement',
+ 'commande' => 'fk_cond_reglement',
+ 'facture' => 'fk_cond_reglement',
+ 'facture_rec' => 'fk_cond_reglement',
+ 'commande_fournisseur' => 'fk_cond_reglement',
+ 'facture_fourn' => 'fk_cond_reglement',
+ 'supplier_proposal' => 'fk_cond_reglement'
+ )
+ );
+
+ if (! empty($conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING))
+ {
+ $externalmodules = json_decode($conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING, true);
+
+ if (is_array($externalmodules) && ! empty($externalmodules))
+ {
+ foreach($externalmodules as $params)
+ {
+ if (is_array($params) && ! empty($params))
+ {
+ if (is_array($params['addzero']) && ! empty($params['addzero'])) {
+ array_push($this->addzero, $params['addzero']);
+ }
+
+ if (is_array($params['sharingelements']) && ! empty($params['sharingelements'])) {
+ $this->sharingelements = array_merge($this->sharingelements, $params['sharingelements']);
+ }
+
+ if (is_array($params['sharingmodulename']) && ! empty($params['sharingmodulename']))
+ {
+ $this->sharingmodulename = array_merge($this->sharingmodulename, $params['sharingmodulename']);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Instantiation of DAO class
+ *
+ * @return void
+ */
+ private function getInstanceDao()
+ {
+ if (! is_object($this->dao))
+ {
+ $this->dao = new DaoMulticompany($this->db);
+ }
+ }
+
+
+ /**
+ * setHtmlTitle
+ *
+ * @param array $parameters Hook metadatas (context, etc...)
+ */
+ public function setHtmlTitle($parameters=false)
+ {
+ global $conf;
+
+ if (empty($conf->global->MULTICOMPANY_HIDE_HTML_TITLE)) {
+ $this->resprints = ' + multicompany';
+ }
+
+ return 0;
+ }
+
+
+ /**
+ * Enter description here ...
+ *
+ * @param string $action Action type
+ */
+ public function doAdminActions(&$action='')
+ {
+ global $conf, $user, $langs;
+
+ $this->getInstanceDao();
+
+ $id = GETPOST('id','int');
+ $label = GETPOST('label','alpha');
+ $name = GETPOST('name','alpha');
+ $description = GETPOST('description','alpha');
+ $cancel = GETPOST('cancel', 'alpha');
+ $addandstay = GETPOST('addandstay', 'alpha');
+ $cancelandstay = GETPOST('cancelandstay', 'alpha');
+ $updateandstay = GETPOST('updateandstay', 'alpha');
+ $template = (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) ? null : GETPOST('template', 'int'));
+ $usetemplate = (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) ? null : GETPOST('usetemplate', 'int'));
+ $visible = GETPOST('visible', 'int');
+ $active = GETPOST('active', 'int');
+
+ if ($action === 'add' && empty($cancel) && $user->admin && ! $user->entity)
+ {
+ $error=0;
+
+ if (empty($label))
+ {
+ $error++;
+ setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")), 'errors');
+ $action = 'create';
+ }
+ else if (empty($name))
+ {
+ $error++;
+ setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("CompanyName")), 'errors');
+ $action = 'create';
+ }
+
+ // Verify if label already exist in database
+ if (! $error)
+ {
+ $this->dao->getEntities();
+ if (! empty($this->dao->entities))
+ {
+ foreach($this->dao->entities as $entity)
+ {
+ if (strtolower($entity->label) == strtolower($label)) $error++;
+ }
+ if ($error)
+ {
+ setEventMessage($langs->trans("ErrorEntityLabelAlreadyExist"), 'errors');
+ $action = 'create';
+ }
+ }
+ }
+
+ if (! $error)
+ {
+ $this->db->begin();
+
+ $this->dao->label = $label;
+ $this->dao->description = $description;
+ $this->dao->visible = ((! empty($template) && empty($usetemplate)) ? 2 : ((! empty($visible) || ! empty($conf->global->MULTICOMPANY_VISIBLE_BY_DEFAULT)) ? 1 : 0));
+ $this->dao->active = ((! empty($active) || ! empty($conf->global->MULTICOMPANY_ACTIVE_BY_DEFAULT))?1:0);
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) {
+ $this->dao->options['proposalnumber_referent'] = (GETPOST('proposalnumber_referring_entity', 'int') ? GETPOST('proposalnumber_referring_entity', 'int') : null);
+ $this->dao->options['invoicenumber_referent'] = (GETPOST('invoicenumber_referring_entity', 'int') ? GETPOST('invoicenumber_referring_entity', 'int') : null);
+ foreach ($this->sharingelements as $element => $params) {
+ if ((($params['object'] || $params['objectnumber']) && ! isset($params['disable'])) && (empty($conf->societe->enabled) || empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED))) continue;
+ $uppername = strtoupper($element);
+ $constname = 'MULTICOMPANY_' . $uppername . '_SHARING_ENABLED';
+ if (! empty($conf->global->$constname)) {
+ $shareentities = GETPOST($element.'_to', 'array');
+ $shareentities = array_unique($shareentities); sort($shareentities);
+ $this->dao->options['sharings'][$element] = (! empty($shareentities) ? $shareentities : null);
+ if (! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) {
+ $this->dao->options['addtoallother'][$element] = GETPOST('addtoallother_'.$element, 'int');
+ }
+ }
+ }
+ }
+
+ $extrafields = new ExtraFields($this->db);
+ $extralabels = $extrafields->fetch_name_optionals_label($this->dao->table_element, true);
+ $extrafields->setOptionalsFromPost($extralabels, $this->dao);
+
+ $id = $this->dao->create($user);
+ if ($id <= 0)
+ {
+ $error++;
+ $errors=($this->dao->error ? array($this->dao->error) : $this->dao->errors);
+ setEventMessage($errors, 'errors');
+ $action = 'create';
+ }
+
+ if (! $error && $id > 0)
+ {
+ if (! empty($usetemplate) && is_numeric($usetemplate))
+ {
+ $const = $this->dao->getEntityConfig($usetemplate);
+ if (! empty($const))
+ {
+ // Reload modules
+ foreach ($const as $key => $value)
+ {
+ if (preg_match('/^MAIN\_MODULE\_([0-9A-Z]+)$/', $key, $reg))
+ {
+ if (! empty($reg[1]))
+ {
+ $classname = 'mod' . ucfirst(strtolower($reg[1]));
+
+ $res = @include_once DOL_DOCUMENT_ROOT.'/core/modules/'.$classname.'.class.php';
+
+ if ($res) {
+ dol_syslog(get_class($this)."::reloadModules template=".$usetemplate." module=".$key." classname=".$classname, LOG_DEBUG);
+ $mod=new $classname($this->db);
+ $mod->init('forceactivate');
+ } else {
+ dol_syslog(get_class($this)."::reloadModules template=".$usetemplate." module=".$key." classname=".$classname, LOG_ERR);
+ }
+ }
+ }
+ }
+
+ // Overwrite with template
+ foreach ($const as $key => $value)
+ {
+ dolibarr_set_const($this->db, $key, $value, 'chaine', 0, '', $id);
+ }
+ }
+ }
+
+ $country_id = GETPOST('country_id', 'int');
+ $country = getCountry($country_id, 'all');
+ $country_code = $country['code'];
+ $country_label = $country['label'];
+
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_COUNTRY", $country_id.':'.$country_code.':'.$country_label,'chaine',0,'',$id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_NOM",$name,'chaine',0,'',$id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_ADDRESS",GETPOST('address', 'alpha'),'chaine',0,'',$id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_TOWN",GETPOST('town', 'alpha'),'chaine',0,'',$id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_ZIP",GETPOST('zipcode', 'alpha'),'chaine',0,'',$id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_STATE",GETPOST('departement_id', 'int'),'chaine',0,'',$id);
+ dolibarr_set_const($this->db, "MAIN_MONNAIE",GETPOST('currency_code', 'alpha'),'chaine',0,'',$id);
+ dolibarr_set_const($this->db, "MAIN_LANG_DEFAULT",GETPOST('main_lang_default', 'alpha'),'chaine',0,'',$id);
+
+ if (empty($usetemplate))
+ {
+ $dir = "/multicompany/sql/";
+
+ // Load sql init_new_entity.sql file
+ $file = 'init_new_entity_nocrypt.sql';
+ if (! empty($conf->db->dolibarr_main_db_encryption) && ! empty($conf->db->dolibarr_main_db_cryptkey))
+ {
+ $file = 'init_new_entity.sql';
+ }
+ $fullpath = dol_buildpath($dir.$file);
+
+ if (file_exists($fullpath))
+ {
+ $result=run_sql($fullpath,1,$id);
+ }
+
+ $dir = "/multicompany/sql/dict/";
+
+ foreach($this->sharingdicts as $dict => $data)
+ {
+ // Load sql init_new_entity_dict.sql file
+ $file = 'init_new_entity_'.$dict.'.sql';
+ $fullpath = dol_buildpath($dir.$file);
+
+ if (file_exists($fullpath))
+ {
+ $result = run_sql($fullpath, 1, $id);
+ }
+ }
+ }
+ else
+ {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+
+ $modulesdir = dolGetModulesDirs();
+
+ foreach ($modulesdir as $dir)
+ {
+ // Load modules attributes in arrays (name, numero, orders) from dir directory
+ //print $dir."\n ";
+ $handle=@opendir(dol_osencode($dir));
+ if (is_resource($handle))
+ {
+ while (($file = readdir($handle))!==false)
+ {
+ if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php')
+ {
+ $modName = substr($file, 0, dol_strlen($file) - 10);
+
+ if ($modName)
+ {
+ include_once $dir."/".$file;
+ $objMod = new $modName($this->db);
+ // Load all lang files of module
+ if (isset($objMod->langfiles) && is_array($objMod->langfiles))
+ {
+ foreach($objMod->langfiles as $domain)
+ {
+ $langs->load($domain);
+ }
+ }
+ // Load all permissions
+ if ($objMod->rights_class)
+ {
+ $ret=$objMod->insert_permissions(0, $id);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Add entity to all others entities
+ if (! empty($this->dao->options['addtoallother']))
+ {
+ $this->dao->getEntities(true, array($id), false);
+ foreach ($this->dao->entities as $entity)
+ {
+ if (! is_array($entity->options)) $entity->options = array();
+ if (! is_array($entity->options['sharings'])) $entity->options['sharings'] = array();
+
+ foreach($this->dao->options['sharings'] as $element => $values)
+ {
+ if (! is_array($entity->options['sharings'][$element])) $entity->options['sharings'][$element] = array();
+
+ if ($this->dao->options['addtoallother'][$element] == '1')
+ {
+ array_push($entity->options['sharings'][$element], (string) $id);
+ $entity->update($entity->id, $user);
+ }
+ }
+ }
+ }
+
+ $listofgroups = $this->dao->getListOfGroups();
+ if (! empty($listofgroups))
+ {
+ foreach($listofgroups as $groupid)
+ {
+ // Duplicate usergroup rights
+ $ret = $this->duplicateUserGroupRights($groupid, $usetemplate, array($id));
+ if ($ret < 0) $error++;
+
+ // Add users to groups if linked with template
+ $userslist = $this->dao->getListOfUsersInGroupByTemplate($groupid, $usetemplate);
+ if ($userslist < 0) $error++;
+ elseif (! empty($userslist))
+ {
+ foreach($userslist as $usertemplate)
+ {
+ $result = $usertemplate->SetInGroup($groupid, $id);
+ if ($result < 0)
+ {
+ $error++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (! $error)
+ {
+ $this->db->commit();
+ }
+ else
+ {
+ $this->db->rollback();
+ }
+
+ if (! empty($addandstay))
+ {
+ header("Location: " . $_SERVER['PHP_SELF'].'?action=edit&id='.$id);
+ exit;
+ }
+ }
+ else
+ {
+ $this->db->rollback();
+ }
+ }
+ }
+ else if ($action === 'edit' && $user->admin && ! $user->entity)
+ {
+ $error=0;
+
+ if (! empty($cancel))
+ {
+ header("Location: " . $_SERVER['PHP_SELF']);
+ exit;
+ }
+
+ if ($this->dao->fetch($id) < 0)
+ {
+ $error++;
+ setEventMessage($langs->trans("ErrorEntityIsNotValid"), 'errors');
+ $action = '';
+ }
+ }
+ else if ($action === 'update' && empty($cancel) && $id > 0 && $user->admin && ! $user->entity)
+ {
+ $error=0;
+
+ if (! empty($cancelandstay))
+ {
+ $action = 'edit';
+ return;
+ }
+
+ $ret = $this->dao->fetch($id);
+ if ($ret < 0)
+ {
+ $error++;
+ setEventMessage($langs->trans("ErrorEntityIsNotValid"), 'errors');
+ $action = '';
+ }
+ else if (empty($label))
+ {
+ $error++;
+ setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")), 'errors');
+ $action = 'edit';
+ }
+ else if (empty($name))
+ {
+ $error++;
+ setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("CompanyName")), 'errors');
+ $action = 'edit';
+ }
+
+ // Verify if label already exist in database
+ if (! $error)
+ {
+ $this->dao->getEntities();
+ if (! empty($this->dao->entities))
+ {
+ foreach($this->dao->entities as $entity)
+ {
+ if ($entity->id == $this->dao->id) continue;
+ if (strtolower($entity->label) == strtolower($label)) $error++;
+ }
+ if ($error)
+ {
+ setEventMessage($langs->trans("ErrorEntityLabelAlreadyExist"), 'errors');
+ $action = 'edit';
+ }
+ }
+ }
+
+ if (! $error)
+ {
+ $this->db->begin();
+
+ $this->dao->label = $label;
+ $this->dao->description = $description;
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) {
+ $this->dao->options['proposalnumber_referent'] = (GETPOST('proposalnumber_referring_entity', 'int') ? GETPOST('proposalnumber_referring_entity', 'int') : null);
+ $this->dao->options['invoicenumber_referent'] = (GETPOST('invoicenumber_referring_entity', 'int') ? GETPOST('invoicenumber_referring_entity', 'int') : null);
+ foreach ($this->sharingelements as $element => $params) {
+ if ((($params['object'] || $params['objectnumber']) && ! isset($params['disable'])) && (empty($conf->societe->enabled) || empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED))) continue;
+ $uppername = strtoupper($element);
+ $constname = 'MULTICOMPANY_' . $uppername . '_SHARING_ENABLED';
+ if (! empty($conf->global->$constname)) {
+ $shareentities = GETPOST($element.'_to', 'array');
+ $shareentities = array_unique($shareentities); sort($shareentities);
+ $this->dao->options['sharings'][$element] = (! empty($shareentities) ? $shareentities : null);
+ if (! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) {
+ $this->dao->options['addtoallother'][$element] = GETPOST('addtoallother_'.$element, 'int');
+ }
+ }
+ }
+ }
+
+ $extrafields = new ExtraFields($this->db);
+ $extralabels = $extrafields->fetch_name_optionals_label($this->dao->table_element, true);
+ $extrafields->setOptionalsFromPost($extralabels, $this->dao);
+
+ $ret = $this->dao->update($this->dao->id, $user);
+ if ($ret <= 0)
+ {
+ $error++;
+ $errors=($this->dao->error ? array($this->dao->error) : $this->dao->errors);
+ setEventMessage($errors, 'errors');
+ $action = 'edit';
+ }
+
+ if (! $error && $ret > 0)
+ {
+ $country_id = GETPOST('country_id', 'int');
+ $country = getCountry($country_id, 'all');
+ $country_code = $country['code'];
+ $country_label = $country['label'];
+
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_COUNTRY", $country_id.':'.$country_code.':'.$country_label,'chaine',0,'',$this->dao->id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_NOM",$name,'chaine',0,'',$this->dao->id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_ADDRESS",GETPOST('address', 'alpha'),'chaine',0,'',$this->dao->id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_TOWN",GETPOST('town', 'alpha'),'chaine',0,'',$this->dao->id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_ZIP",GETPOST('zipcode', 'alpha'),'chaine',0,'',$this->dao->id);
+ dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_STATE",GETPOST('departement_id', 'int'),'chaine',0,'',$this->dao->id);
+ dolibarr_set_const($this->db, "MAIN_MONNAIE",GETPOST('currency_code', 'alpha'),'chaine',0,'',$this->dao->id);
+ dolibarr_set_const($this->db, "MAIN_LANG_DEFAULT",GETPOST('main_lang_default', 'alpha'),'chaine',0,'',$this->dao->id);
+
+ $this->db->commit();
+
+ if (! empty($updateandstay)) {
+ $action = 'edit';
+ }
+ }
+ else
+ {
+ $this->db->rollback();
+ }
+ }
+ }
+ }
+
+ /**
+ * Return action of hook
+ * @param object Linked object
+ */
+ public function doActions($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ // Clear constants cache after company infos update
+ if (is_array($currentcontext))
+ {
+ if ((in_array('admincompany', $currentcontext) || in_array('adminihm', $currentcontext)) && ($action == 'update' || $action == 'updateedit'))
+ {
+ clearCache($conf->entity);
+ clearCache('constants_' . $conf->entity);
+ }
+ else if ((in_array('groupcard', $currentcontext) || in_array('groupperms', $currentcontext)) && $object->element == 'usergroup')
+ {
+ global $entity;
+
+ // Users/Groups management only in master entity if transverse mode
+ if ($conf->entity > 1 && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ accessforbidden();
+ }
+
+ if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ $entity=(GETPOST('entity','int') ? GETPOST('entity','int') : $conf->entity);
+ } else {
+ $entity=(! empty($object->entity) ? $object->entity : $conf->entity);
+ }
+
+ // Add/Remove user into group
+ if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && in_array('groupcard', $currentcontext) && ($action == 'adduser' || $action =='removeuser') && (! empty($userid) && $userid > 0) && $caneditperms)
+ {
+ if ($action == 'adduser')
+ {
+ $entities = GETPOST("entities", "array", 3);
+
+ if (is_array($entities) && ! empty($entities))
+ {
+ $error=0;
+
+ foreach ($entities as $entity_id)
+ {
+ $object->fetch($id);
+ $object->oldcopy = clone $object;
+
+ $edituser = new User($this->db);
+ $edituser->fetch($userid);
+ $result=$edituser->SetInGroup($object->id, $entity_id);
+ if ($result < 0)
+ {
+ $error++;
+ break;
+ }
+ }
+ if (!$error)
+ {
+ header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $object->id);
+ exit;
+ }
+ else
+ {
+ $this->error = $edituser->error;
+ $this->errors = $edituser->errors;
+ return -1;
+ }
+ }
+ }
+ else if ($action == 'removeuser')
+ {
+ $object->fetch($id);
+ $object->oldcopy = clone $object;
+
+ $edituser = new User($this->db);
+ $edituser->fetch($userid);
+ $result=$edituser->RemoveFromGroup($object->id, $entity);
+
+ if ($result > 0)
+ {
+ header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
+ exit;
+ }
+ else
+ {
+ $this->error = $object->error;
+ $this->errors = $object->errors;
+ return -1;
+ }
+ }
+ return 1;
+ }
+ }
+ else if ((in_array('usercard', $currentcontext) || in_array('userperms', $currentcontext)) && $object->element == 'user')
+ {
+ global $entity, $caneditperms;
+
+ // Users/Groups management only in master entity if transverse mode
+ if ($conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)
+ {
+ if (in_array('usercard', $currentcontext) && ($action == 'create' || $action == 'adduserldap')) {
+ accessforbidden();
+ } else if (in_array('userperms', $currentcontext)) {
+ $caneditperms = false;
+ }
+ }
+
+ if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ if (GETPOSTISSET('entity')) {
+
+ $entity = GETPOST('entity','int');
+
+ } else {
+
+ $entity = $conf->entity;
+
+ // Check usergroup if user not in master entity
+ if (in_array('userperms', $currentcontext) && ! empty($user->admin) && empty($user->entity) && $conf->entity == 1)
+ {
+ require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
+ $group = new UserGroup($this->db);
+ $ret = $group->listGroupsForUser($object->id, false);
+ if (! empty(current($ret)->usergroup_entity)) {
+ sort(current($ret)->usergroup_entity);
+ if (current($ret)->usergroup_entity[0] > 1) {
+ $entity = current($ret)->usergroup_entity[0];
+ }
+ }
+ }
+ }
+ } else {
+ $entity=(! empty($object->entity) ? $object->entity : $conf->entity);
+ }
+
+ // Action add usergroup
+ if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && in_array('usercard', $currentcontext) && ($action == 'addgroup' || $action == 'removegroup') && (! empty($group) && $group > 0) && $caneditgroup)
+ {
+ if ($action == 'addgroup')
+ {
+ $entities = GETPOST("entities", "array", 3);
+
+ if (is_array($entities) && ! empty($entities))
+ {
+ $error=0;
+
+ foreach ($entities as $entity_id)
+ {
+ $object->fetch($id);
+ $result = $object->SetInGroup($group, $entity_id);
+ if ($result < 0)
+ {
+ $error++;
+ break;
+ }
+ }
+ if ($error)
+ {
+ $this->error = $object->error;
+ $this->errors = $object->errors;
+ return -1;
+ }
+ else
+ {
+ header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $object->id);
+ exit;
+ }
+ }
+ }
+ else if ($action == 'removegroup')
+ {
+ $object->fetch($id);
+ $result = $object->RemoveFromGroup($group, $entity);
+ if ($result > 0) {
+ header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $object->id);
+ exit;
+ }
+ else
+ {
+ $this->error = $object->error;
+ $this->errors = $object->errors;
+ return -1;
+ }
+ }
+ return 1;
+ }
+ }
+ else if (in_array('productcard', $currentcontext) && ($object->element == 'product' || $object->element == 'service'))
+ {
+ if ($action != 'create' && $action != 'add')
+ {
+ if ($object->entity != $conf->entity)
+ {
+ global $usercanread, $usercancreate, $usercandelete;
+
+ /*if (empty($user->rights->multicompany->product->read)) {
+ $usercanread = false;
+ }*/
+ if (empty($user->rights->multicompany->product->write)) {
+ $usercancreate = false;
+ }
+ if (empty($user->rights->multicompany->product->delete)) {
+ $usercandelete = false;
+ }
+ }
+ }
+ }
+ else if (in_array('propalcard', $currentcontext) && $object->element == 'propal')
+ {
+ if ($action != 'create' && $action != 'add')
+ {
+ if ($object->entity != $conf->entity)
+ {
+ global $usercanread, $usercancreate, $usercandelete, $usercanvalidate, $usercansend, $usercanclose;
+ global $permissionnote, $permissiondellink, $permissiontoedit;
+ global $disableedit, $disablemove, $disableremove;
+
+ $this->getInstanceDao();
+
+ $constants = array(
+ 'PROPALE_ADDON',
+ 'PROPALE_SAPHIR_MASK',
+ 'PROPALE_ADDON_PDF',
+ 'PROPALE_ADDON_PDF_ODT_PATH'
+ );
+
+ if (empty($conf->global->MULTICOMPANY_PROPOSALNUMBER_SHARING_ENABLED) || empty($mc->sharings['proposalnumber'])) // Check if current entity not use the proposalnumber sharing
+ {
+ foreach ($constants as $constname)
+ {
+ $res = $this->dao->getEntityConfig($object->entity, $constname);
+ if (! empty($res[$constname])) {
+ $conf->global->$constname = $res[$constname]; // override current entity config with object entity config
+ }
+ }
+ }
+ else
+ {
+ foreach ($constants as $constname)
+ {
+ $referent = (! empty($mc->proposalnumber_referent)?$mc->proposalnumber_referent:1);
+ $res = $this->dao->getEntityConfig($referent, $constname);
+ if (! empty($res[$constname])) {
+ $conf->global->$constname = $res[$constname]; // override current entity config with referent config
+ }
+ }
+ }
+
+ // Override $mysoc with data of object entity
+ if ($action == 'builddoc')
+ {
+ global $mysoc;
+
+ $current = $this->dao->getEntityConfig($conf->entity, 'MAIN_INFO_*');
+ if (! empty($current))
+ {
+ foreach($current as $constname => $value)
+ {
+ unset($conf->global->$constname);
+ }
+ }
+
+ $other = $this->dao->getEntityConfig($object->entity, 'MAIN_INFO_*');
+ if (! empty($other))
+ {
+ foreach($other as $constname => $value)
+ {
+ $conf->global->$constname = $value; // override current entity config with referent config
+ }
+ }
+
+ $mysoc->setMysoc($conf);
+ }
+
+ if (empty($user->rights->multicompany->propal->read)) {
+ $usercanread = false;
+ }
+ if (empty($user->rights->multicompany->propal->write)) {
+ $usercancreate = false;
+
+ $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
+ $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
+ $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php
+
+ // for object lines
+ $disableedit = true;
+ $disablemove = true;
+ $disableremove = true;
+ }
+ if (empty($user->rights->multicompany->propal->delete)) {
+ $usercandelete = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->propal_advance->validate))) {
+ $usercanvalidate = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercanread)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->propal_advance->send))) {
+ $usercansend = false;
+ }
+ if (empty($user->rights->multicompany->propal->close)) {
+ $usercanclose = false;
+ }
+ }
+ }
+ }
+ else if (in_array('ordercard', $currentcontext) && $object->element == 'commande')
+ {
+ if ($action != 'create' && $action != 'add')
+ {
+ if ($object->entity != $conf->entity)
+ {
+ global $usercanread, $usercancreate, $usercandelete, $usercanvalidate, $usercansend, $usercanclose, $usercancancel;
+ global $permissionnote, $permissiondellink, $permissiontoedit;
+ global $disableedit, $disablemove, $disableremove;
+
+ $this->getInstanceDao();
+
+ $constants = array(
+ 'COMMANDE_ADDON',
+ 'COMMANDE_SAPHIR_MASK',
+ 'COMMANDE_ADDON_PDF',
+ 'COMMANDE_ADDON_PDF_ODT_PATH'
+ );
+
+ if (empty($conf->global->MULTICOMPANY_ORDERNUMBER_SHARING_ENABLED) || empty($mc->sharings['ordernumber'])) // Check if current entity not use the proposalnumber sharing
+ {
+ foreach ($constants as $constname)
+ {
+ $res = $this->dao->getEntityConfig($object->entity, $constname);
+ if (! empty($res[$constname])) {
+ $conf->global->$constname = $res[$constname]; // override current entity config with object entity config
+ }
+ }
+ }
+ else
+ {
+ foreach ($constants as $constname)
+ {
+ $referent = (! empty($mc->ordernumber_referent)?$mc->ordernumber_referent:1);
+ $res = $this->dao->getEntityConfig($referent, $constname);
+ if (! empty($res[$constname])) {
+ $conf->global->$constname = $res[$constname]; // override current entity config with referent config
+ }
+ }
+ }
+
+ // Override $mysoc with data of object entity
+ if ($action == 'builddoc')
+ {
+ global $mysoc;
+
+ $current = $this->dao->getEntityConfig($conf->entity, 'MAIN_INFO_*');
+ if (! empty($current))
+ {
+ foreach($current as $constname => $value)
+ {
+ unset($conf->global->$constname);
+ }
+ }
+
+ $other = $this->dao->getEntityConfig($object->entity, 'MAIN_INFO_*');
+ if (! empty($other))
+ {
+ foreach($other as $constname => $value)
+ {
+ $conf->global->$constname = $value; // override current entity config with referent config
+ }
+ }
+
+ $mysoc->setMysoc($conf);
+ }
+
+ if (empty($user->rights->multicompany->order->read)) {
+ $usercanread = false;
+ }
+ if (empty($user->rights->multicompany->order->write)) {
+ $usercancreate = false;
+
+ $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
+ $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
+ $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php
+
+ // for object lines
+ $disableedit = true;
+ $disablemove = true;
+ $disableremove = true;
+ }
+ if (empty($user->rights->multicompany->order->delete)) {
+ $usercandelete = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->order_advance->validate))) {
+ $usercanvalidate = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->order_advance->cancel))) {
+ $usercancancel = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercanread)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->order_advance->send))) {
+ $usercansend = false;
+ }
+ if (empty($user->rights->multicompany->order->close)) {
+ $usercanclose = false;
+ }
+ }
+ }
+ }
+ else if (in_array('invoicecard', $currentcontext) && $object->element == 'facture')
+ {
+ if ($action != 'create' && $action != 'add')
+ {
+ if ($object->entity != $conf->entity)
+ {
+ global $usercanread, $usercancreate, $usercandelete, $usercanvalidate, $usercansend, $usercanreopen, $usercanunvalidate;
+ global $permissionnote, $permissiondellink, $permissiontoedit;
+ global $disableedit, $disablemove, $disableremove;
+
+ $this->getInstanceDao();
+
+ $constants = array(
+ 'FACTURE_ADDON',
+ 'FACTURE_MERCURE_MASK_INVOICE',
+ 'FACTURE_MERCURE_MASK_CREDIT',
+ 'FACTURE_MERCURE_MASK_DEPOSIT',
+ 'FACTURE_MERCURE_MASK_REPLACEMENT',
+ 'PROPALE_ADDON_PDF',
+ 'FACTURE_ADDON_PDF_ODT_PATH'
+ );
+
+ if (empty($conf->global->MULTICOMPANY_INVOICENUMBER_SHARING_ENABLED) || empty($mc->sharings['invoicenumber'])) // Check if current entity not use the proposalnumber sharing
+ {
+ foreach ($constants as $constname)
+ {
+ $res = $this->dao->getEntityConfig($object->entity, $constname);
+ if (! empty($res[$constname])) {
+ $conf->global->$constname = $res[$constname]; // override current entity config with object entity config
+ }
+ }
+ }
+ else
+ {
+ foreach ($constants as $constname)
+ {
+ $referent = (! empty($mc->invoicenumber_referent)?$mc->invoicenumber_referent:1);
+ $res = $this->dao->getEntityConfig($referent, $constname);
+ if (! empty($res[$constname])) {
+ $conf->global->$constname = $res[$constname]; // override current entity config with referent config
+ }
+ }
+ }
+
+ // Override $mysoc with data of object entity
+ if ($action == 'builddoc')
+ {
+ global $mysoc;
+
+ $current = $this->dao->getEntityConfig($conf->entity, 'MAIN_INFO_*');
+ if (! empty($current))
+ {
+ foreach($current as $constname => $value)
+ {
+ unset($conf->global->$constname);
+ }
+ }
+
+ $other = $this->dao->getEntityConfig($object->entity, 'MAIN_INFO_*');
+ if (! empty($other))
+ {
+ foreach($other as $constname => $value)
+ {
+ $conf->global->$constname = $value; // override current entity config with referent config
+ }
+ }
+
+ $mysoc->setMysoc($conf);
+ }
+
+ if (empty($user->rights->multicompany->invoice->read)) {
+ $usercanread = false;
+ }
+ if (empty($user->rights->multicompany->invoice->write)) {
+ $usercancreate = false;
+
+ $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
+ $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
+ $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php
+
+ // for object lines
+ $disableedit = true;
+ $disablemove = true;
+ $disableremove = true;
+ }
+ if (empty($user->rights->multicompany->invoice->delete)) {
+ $usercandelete = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->invoice_advance->validate))) {
+ $usercanvalidate = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercanread)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->invoice_advance->send))) {
+ $usercansend = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->invoice_advance->reopen))) {
+ $usercanreopen = false;
+ }
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->multicompany->invoice_advance->unvalidate))) {
+ $usercanunvalidate = false;
+ }
+ }
+ }
+ }
+ }
+
+ //var_dump($_POST);
+/*
+ if (empty($_SESSION['dol_tables_list_fk_soc']))
+ {
+ $_SESSION['dol_tables_list_fk_soc'] = getTablesWithField('fk_soc', array());
+ }
+ var_dump($_SESSION['dol_tables_list_fk_soc']);
+*/
+ //$include=false;
+ //$exclude=false;
+/*
+ $exclude = array(
+ MAIN_DB_PREFIX . 'user',
+ MAIN_DB_PREFIX . 'user_employment',
+ MAIN_DB_PREFIX . 'user_param',
+ MAIN_DB_PREFIX . 'user_rib',
+ MAIN_DB_PREFIX . 'user_rights',
+ MAIN_DB_PREFIX . 'usergroup',
+ MAIN_DB_PREFIX . 'usergroup_rights',
+ MAIN_DB_PREFIX . 'usergroup_user',
+ MAIN_DB_PREFIX . 'rights_def',
+ );
+*/
+ //$exclude = '/(const|user|rights\_def)+/';
+ //$include = '/(const|user|rights\_def)+/';
+
+ //if (empty($_SESSION['dol_tables_list_entity']))
+/* {
+ $_SESSION['dol_tables_list_entity'] = getTablesWithField('entity', $exclude, $include);
+ }
+
+ var_dump($_SESSION['dol_tables_list_entity']);
+*/
+/*
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED) && ! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty']))
+ {
+ if (in_array($contextpage, $this->thirdpartycontextlist) || in_array($contextpage, $this->contactcontextlist))
+ {
+ if (GETPOST('confirmmassaction') && GETPOST('massaction') == 'modify_entity')
+ {
+ var_dump($_POST['toselect']);
+ }
+ }
+ }
+*/
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function showLinkedObjectBlock($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ //var_dump($object->linkedObjects);
+
+ foreach($object->linkedObjects as $objecttype => $objects)
+ {
+ foreach($objects as $key => $tmpobj)
+ {
+ if (empty($tmpobj->entity)) continue; // for debug
+
+ if ($tmpobj->entity != $conf->entity)
+ {
+ $element = $objecttype;
+ if ($objecttype == 'propal') $element = 'proposal';
+ if ($objecttype == 'commande') $element = 'order';
+ if ($objecttype == 'facture') $element = 'invoice';
+
+ //var_dump($element);var_dump($mc->sharings[$element]);
+ //var_dump($object->linkedObjects[$objecttype][$key]);
+
+ if (! empty($mc->sharings[$element]) && in_array($tmpobj->entity, $mc->sharings[$element]))
+ {
+ //nothing
+ }
+ else
+ {
+ unset($object->linkedObjects[$objecttype][$key]);
+ }
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function showLinkToObjectBlock($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ $perms = 1;
+ $propalperms = 1;
+ $orderperms = 1 ;
+ $invoiceperms = 1 ;
+
+ if (in_array('propalcard', $currentcontext) && $object->element == 'propal')
+ {
+ if ($object->entity != $conf->entity)
+ {
+ $propalperms = ! empty($user->rights->multicompany->propal->write);
+ }
+ }
+ elseif (in_array('ordercard', $currentcontext) && $object->element == 'commande')
+ {
+ if ($object->entity != $conf->entity)
+ {
+ $orderperms = ! empty($user->rights->multicompany->order->write);
+ }
+ }
+ elseif (in_array('invoicecard', $currentcontext) && $object->element == 'facture')
+ {
+ if ($object->entity != $conf->entity)
+ {
+ $invoiceperms = ! empty($user->rights->multicompany->invoice->write);
+ }
+ }
+
+ $this->results = array('propal' => array('enabled'=>$conf->propal->enabled, 'perms'=>$propalperms, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('propal').')'),
+ 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>$orderperms, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande').')'),
+ 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>$invoiceperms, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('invoice').')'),
+ 'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>$perms, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('contract').')'),
+ 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>$perms, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('intervention').')'),
+ 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>$perms, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('supplier_proposal').')'),
+ 'order_supplier'=>array('enabled'=>$conf->supplier_order->enabled , 'perms'=>$perms, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande_fournisseur').')'),
+ 'invoice_supplier'=>array('enabled'=>$conf->supplier_invoice->enabled , 'perms'=>$perms, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture_fourn').')')
+ );
+
+ return 1;
+ }
+
+ /**
+ *
+ */
+ public function addMoreActionsButtons($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ /*if (in_array('productcard', $currentcontext) && ($object->element == 'product' || $object->element == 'service'))
+ {
+ if ($object->entity != $conf->entity)
+ {
+ $user->rights->produit->creer = 0;
+ $user->rights->produit->supprimer = 0;
+ $user->rights->service->creer = 0;
+ $user->rights->service->supprimer = 0;
+
+ //return 1;
+ }
+ }*/
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function printUserPasswordField($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ $langs->load('multicompany@multicompany');
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ $this->resprints = "\n".''."\n";
+
+ if (in_array('usercard', $currentcontext) && $object->element == 'user' && ! empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX) && checkMulticompanyAutentication())
+ {
+ if ($action == 'create')
+ {
+ $this->resprints.= ' ';
+ }
+ else if ($action == 'edit')
+ {
+ if ($caneditpassword)
+ {
+ $this->resprints.= ' ';
+ }
+ else
+ {
+ $this->resprints.= preg_replace('/./i','*',$object->pass);
+ }
+ }
+ else
+ {
+ if ($object->pass) $this->resprints.= preg_replace('/./i','*',$object->pass);
+ else
+ {
+ if ($user->admin) $this->resprints.= ($valuetoshow?(' '.$langs->trans("or").' '):'').$langs->trans("Crypted").': '.$object->pass_indatabase_crypted;
+ else $this->resprints.= $langs->trans("Hidden");
+ }
+ }
+ }
+
+ $this->resprints.= ''."\n";
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function formConfirm($parameters=false, &$object, &$action='')
+ {
+ global $conf, $langs;
+ global $mc, $form;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ $langs->load('multicompany@multicompany');
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $return = 0;
+ $currentcontext = explode(':', $parameters['context']);
+
+ $this->resprints = "\n".''."\n";
+
+ if (in_array('propalcard', $currentcontext) && $object->element == 'propal')
+ {
+ if ($action == 'clone' && ! empty($mc->entities['proposal'])) {
+ // Create an array for form
+ $formquestion = array(
+ // 'text' => $langs->trans("ConfirmClone"),
+ // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
+ // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
+ array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')),
+ array('type' => 'other', 'name' => 'entity', 'label' => $langs->trans("SelectEntity"), 'value' => $mc->select_entities($conf->entity, 'entity', '', false, false, false, explode(',', $mc->entities['proposal'])))
+ );
+ if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->date_livraison)) {
+ $formquestion[] = array('type' => 'date', 'name' => 'date_delivery', 'label' => $langs->trans("DeliveryDate"), 'value' => $object->date_livraison);
+ }
+ // Incomplete payment. We ask if reason = discount or other
+ $this->resprints.= $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmClonePropal', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
+ $return++;
+ }
+ }
+
+ $this->resprints.= ''."\n";
+
+ return $return;
+ }
+
+ /**
+ *
+ */
+ public function formObjectOptions($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+ global $form;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ $langs->load('multicompany@multicompany');
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ $this->resprints = "\n".''."\n";
+
+ if (in_array('thirdpartycard', $currentcontext) && $object->element == 'societe' && ! empty($user->admin) && empty($user->entity))
+ {
+ if ($action == 'create')
+ {
+ $this->resprints.= ''.fieldLabel('Entity','entity').' ';
+ $s = $this->select_entities($conf->entity);
+ $this->resprints.= $form->textwithpicto($s,$langs->trans("ThirdpartyEntityDesc"),1);
+ $this->resprints.= ' '."\n";
+ }
+ }
+ else if (in_array('contactcard', $currentcontext) && $object->element == 'contact' && ! empty($user->admin) && empty($user->entity))
+ {
+ if ($action == 'create' && empty($objsoc))
+ {
+ $this->resprints.= ''.fieldLabel('Entity','entity').' ';
+ $s = $this->select_entities($conf->entity);
+ $this->resprints.= $form->textwithpicto($s,$langs->trans("ContactEntityDesc"),1);
+ $this->resprints.= ' '."\n";
+ }
+ }
+ else if (in_array('usercard', $currentcontext) && $object->element == 'user')
+ {
+ if ($action == 'edit')
+ {
+ // TODO check if user not linked with the current entity before change entity (thirdparty, invoice, etc.) !!
+ if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && ! empty($user->admin) && empty($user->entity))
+ {
+ $this->resprints.= ''.$langs->trans("Entity").' ';
+ $this->resprints.= ''.$this->select_entities($object->entity);
+ $this->resprints.= " \n";
+ }
+ else
+ {
+ $this->resprints.= ' ';
+ }
+ }
+ else if ($action == 'create')
+ {
+ if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && ! empty($user->admin) && empty($user->entity))
+ {
+ $this->resprints.= ''.$langs->trans("Entity").' ';
+ $this->resprints.= ''.$this->select_entities($conf->entity);
+ $this->resprints.= " \n";
+ }
+ else
+ {
+ $this->resprints.= ' ';
+ }
+ }
+ else if ($action != 'adduserldap')
+ {
+ if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && ! empty($user->admin) && empty($user->entity))
+ {
+ $this->resprints.= ''.$langs->trans("Entity").' ';
+ if (empty($object->entity))
+ {
+ $this->resprints.= $langs->trans("AllEntities");
+ }
+ else
+ {
+ $this->getInfo($object->entity);
+ $this->resprints.= $this->label;
+ }
+ $this->resprints.= " \n";
+ }
+ }
+ }
+ else if ((in_array('propalcard', $currentcontext) && $object->element == 'propal')
+ || (in_array('ordercard', $currentcontext) && $object->element == 'commande')
+ || (in_array('invoicecard', $currentcontext) && $object->element == 'facture')
+ )
+ {
+ if ($action == 'create')
+ {
+ $this->resprints.= ''.$langs->trans("Entity").' ';
+ $this->resprints.= ''.$this->select_entities($conf->entity);
+ $this->resprints.= " \n";
+ }
+ }
+
+ $this->resprints.= ''."\n";
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function formCreateThirdpartyOptions($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+ global $form;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ $langs->load('multicompany@multicompany');
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ //echo 'OK';
+
+ //$this->resprints = 'OK';
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function formAddUserToGroup($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+ global $form, $mc, $exclude;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ $langs->load('multicompany@multicompany');
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ $this->resprints = '';
+
+ if (is_array($currentcontext))
+ {
+ if (in_array('usercard', $currentcontext) && $object->element == 'user')
+ {
+ if ($action != 'edit' && $action != 'presend' && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+ {
+ $this->resprints = "\n".''."\n";
+
+ if (! empty($groupslist))
+ {
+ $exclude=array();
+ }
+
+ if ($caneditgroup)
+ {
+ $this->resprints.= '';
+ }
+
+ $this->resprints.= ''."\n";
+
+ return 1;
+ }
+ }
+ else if (in_array('groupcard', $currentcontext) && $object->element == 'usergroup')
+ {
+ if ($action != 'edit' && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+ {
+ $this->resprints = "\n".''."\n";
+
+ if (! empty($object->members))
+ {
+ $exclude=array();
+ }
+
+ if ($caneditperms && empty($user->entity))
+ {
+ $this->resprints.= ''."\n";
+ $this->resprints.= ' ';
+ }
+
+ /*
+ * Group members
+ */
+ $this->resprints.= '';
+ $this->resprints.= '';
+ $this->resprints.= ''.$langs->trans("Login").' ';
+ $this->resprints.= ''.$langs->trans("Lastname").' ';
+ $this->resprints.= ''.$langs->trans("Firstname").' ';
+ if ($conf->entity == 1)
+ {
+ $this->resprints.= ''.$langs->trans("Entity").' ';
+ }
+ $this->resprints.= ''.$langs->trans("Status").' ';
+ $this->resprints.= ' ';
+ $this->resprints.= " \n";
+
+ if (! empty($object->members))
+ {
+ foreach($object->members as $useringroup)
+ {
+ $this->resprints.= '';
+ $this->resprints.= '';
+ $this->resprints.= $useringroup->getNomUrl(-1, '', 0, 0, 24, 0, 'login');
+ if ($useringroup->admin && ! $useringroup->entity) $this->resprints.= img_picto($langs->trans("SuperAdministrator"),'redstar');
+ else if ($useringroup->admin) $this->resprints.= img_picto($langs->trans("Administrator"),'star');
+ $this->resprints.= ' ';
+ $this->resprints.= ''.$useringroup->lastname.' ';
+ $this->resprints.= ''.$useringroup->firstname.' ';
+ if ($conf->entity == 1 && ! empty($user->admin))
+ {
+ $this->resprints.= '';
+ if (! empty($useringroup->usergroup_entity))
+ {
+ foreach($useringroup->usergroup_entity as $group_entity)
+ {
+ $mc->getInfo($group_entity);
+ if (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) && $mc->visible == 2) continue;
+
+ $this->resprints.= '';
+ if ($mc->visible == 2) {
+ $this->resprints.= ' ';
+ } else {
+ $this->resprints.= ' ';
+ }
+ $this->resprints.= $mc->label . (empty($mc->active) ? ' ('.$langs->trans('Disabled').')' : ($mc->visible == 2 ? ' ('.$langs->trans('Template').')' : (empty($mc->visible) ? ' ('.$langs->trans('Hidden').')' : '')) );
+ if (empty($user->entity)) {
+ $this->resprints.= '';
+ $this->resprints.= img_picto($langs->trans("RemoveFromGroup"), 'unlink');
+ $this->resprints.= ' ';
+ }
+ $this->resprints.= ' ';
+ }
+ }
+ $this->resprints.= ' ';
+ }
+ $this->resprints.= ''.$useringroup->getLibStatut(3).' ';
+ $this->resprints.= '';
+ $this->resprints.= "-";
+ $this->resprints.= " \n";
+ }
+ }
+ else
+ {
+ $this->resprints.= ''.$langs->trans("None").' ';
+ }
+ $this->resprints.= "
";
+
+ $this->resprints.= ''."\n";
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function moreHtmlRef($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ $this->resprints = "\n".''."\n";
+
+ // if global sharings is enabled
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED))
+ {
+ $this->getInfo(! empty($object->entity) ? $object->entity : $conf->entity);
+
+ // if third party sharing is enabled (is mandatory for some sharings)
+ if (! empty($conf->societe->enabled) && ! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty']))
+ {
+ if ($object->element == 'societe')
+ {
+ if (in_array('thirdpartycard', $currentcontext))
+ {
+ if ($action != 'create' && $action != 'edit')
+ {
+ if ($object->isObjectUsed($object->id) === 0 && ((! empty($user->admin) && ! $user->entity) || ! empty($user->rights->multicompany->thirdparty->write)))
+ {
+ $selectEntities = $this->getModifyEntityDialog('thirdparty', 'modifyEntity', $object);
+
+ if (! empty($selectEntities)) {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ $this->resprints.= $selectEntities;
+ } else {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ }
+ }
+ else
+ {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ }
+ }
+ }
+ else
+ {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ }
+ }
+ else if ($object->element == 'contact')
+ {
+ if (in_array('contactcard', $currentcontext))
+ {
+ if ($action != 'create' && $action != 'edit')
+ {
+ if (empty($object->socid) && ((! empty($user->admin) && ! $user->entity) || ! empty($user->rights->multicompany->contact->write)))
+ {
+ $selectEntities = $this->getModifyEntityDialog('contact', 'modifyEntity', $object);
+
+ if (! empty($selectEntities)) {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ $this->resprints.= $selectEntities;
+ } else {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ }
+ }
+ else
+ {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ }
+ }
+ }
+ else
+ {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ }
+ }
+ }
+
+ if (((! empty($conf->product->enabled) || ! empty($conf->service->enabled)) && $object->element == 'product' && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product']))
+ || (! empty($conf->propal->enabled) && $object->element == 'propal' && in_array('propalcard', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal']))
+ || (! empty($conf->commande->enabled) && $object->element == 'commande' && in_array('ordercard', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order']))
+ || (! empty($conf->facture->enabled) && $object->element == 'facture' && in_array('invoicecard', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice']))
+ || (! empty($conf->stock->enabled) && $object->element == 'stock' && in_array('warehousecard', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock']))
+ )
+ {
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ }
+ }
+
+ if ($object->element == 'user' || $object->element == 'usergroup')
+ {
+ if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && ! empty($user->admin) && empty($user->entity))
+ {
+ $this->getInfo($object->entity);
+ $this->resprints.= '';
+ $this->resprints.= ''.$this->label.' ';
+ $this->resprints.= '
';
+ }
+ }
+
+ $this->resprints.= ''."\n";
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function moreHtmlStatus($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ //$this->resprints.= 'OK';
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function printUserListWhere($parameters=false)
+ {
+ global $conf, $user;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $this->resprints = '';
+
+ if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
+ $this->resprints.= " WHERE u.entity IS NOT NULL"; // Show all users
+ } else {
+ $this->resprints.= ",".MAIN_DB_PREFIX."usergroup_user as ug";
+ $this->resprints.= " WHERE ((ug.fk_user = u.rowid";
+ $this->resprints.= " AND ug.entity IN (".getEntity('usergroup')."))";
+ $this->resprints.= " OR u.entity = 0)"; // Show always superadmin
+ }
+ return 1;
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ * @return number
+ */
+ public function addMoreMassActions($parameters=false)
+ {
+ global $conf, $user, $langs;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED))
+ {
+ // name="massaction"
+ if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty']))
+ {
+ if (in_array('thirdpartylist', $currentcontext) || in_array('contactlist', $currentcontext))
+ {
+ $langs->load('multicompany@multicompany');
+ $this->resprints = ''.$langs->trans('ModifyEntity').' ';
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ * @return number
+ */
+ public function printFieldListSelect($parameters=false)
+ {
+ global $conf;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED))
+ {
+ // Thirdparty sharing is mandatory to share document (propal, etc...)
+ if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty']))
+ {
+ if (in_array('thirdpartylist', $currentcontext))
+ {
+ //if (! empty($arrayfields['s.entity']['checked']))
+ {
+ $this->resprints = ", s.entity";
+ }
+ }
+ else if (in_array('contactlist', $currentcontext))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = ", p.entity";
+ }
+ }
+ else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = ", p.entity";
+ }
+ }
+ else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = ", c.entity";
+ }
+ }
+ else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = ", f.entity";
+ }
+ }
+ }
+
+ if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = ", p.entity";
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ * @param boolean $parameters
+ * @return number
+ */
+ public function printFieldListWhere($parameters=false)
+ {
+ global $conf;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED))
+ {
+ if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty']))
+ {
+ if (in_array('thirdpartylist', $currentcontext))
+ {
+ //if (! empty($arrayfields['s.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ if ($search_entity > 0)
+ {
+ $this->resprints = " AND s.entity = " . $search_entity;
+ }
+ }
+ }
+ else if (in_array('contactlist', $currentcontext))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ if ($search_entity > 0)
+ {
+ $this->resprints = " AND p.entity = " . $search_entity;
+ }
+ }
+ }
+ else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ if ($search_entity > 0)
+ {
+ $this->resprints = " AND p.entity = " . $search_entity;
+ }
+ }
+ }
+ else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ if ($search_entity > 0)
+ {
+ $this->resprints = " AND c.entity = " . $search_entity;
+ }
+ }
+ }
+ else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice']))
+ {
+ //if (! empty($arrayfields['f.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ if ($search_entity > 0)
+ {
+ $this->resprints = " AND f.entity = " . $search_entity;
+ }
+ }
+ }
+ }
+
+ if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ if ($search_entity > 0)
+ {
+ $this->resprints = " AND p.entity = " . $search_entity;
+ }
+ }
+ }
+ if (in_array('stocklist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ if ($search_entity > 0)
+ {
+ $this->resprints = " AND t.entity = " . $search_entity;
+ }
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ * @param boolean $parameters
+ * @return number
+ */
+ public function printFieldListOption($parameters=false)
+ {
+ global $conf;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED))
+ {
+ if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty']))
+ {
+ if (in_array('thirdpartylist', $currentcontext) || in_array('contactlist', $currentcontext))
+ {
+ //if (! empty($arrayfields['s.entity']['checked']) || ! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ // Entity
+ $this->resprints = '';
+ $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['thirdparty']),'','minwidth100imp');
+ $this->resprints.= ' ';
+ }
+ }
+ else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ // Entity
+ $this->resprints = '';
+ $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['proposal']),'','minwidth100imp');
+ $this->resprints.= ' ';
+ }
+ }
+ else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ // Entity
+ $this->resprints = '';
+ $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['order']),'','minwidth100imp');
+ $this->resprints.= ' ';
+ }
+ }
+ else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice']))
+ {
+ //if (! empty($arrayfields['f.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ // Entity
+ $this->resprints = '';
+ $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['invoice']),'','minwidth100imp');
+ $this->resprints.= ' ';
+ }
+ }
+ }
+
+ if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ // Entity
+ $this->resprints = '';
+ $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['product']),'','minwidth100imp');
+ $this->resprints.= ' ';
+ }
+ }
+ if (in_array('stocklist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $search_entity = GETPOST('search_entity','int');
+
+ 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_entity = '';
+ }
+
+ // Entity
+ $this->resprints = '';
+ $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['stock']),'','minwidth100imp');
+ $this->resprints.= ' ';
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ * @param boolean $parameters
+ * @return number
+ */
+ public function printFieldListTitle($parameters=false)
+ {
+ global $conf;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED))
+ {
+ if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty']))
+ {
+ if (in_array('thirdpartylist', $currentcontext))
+ {
+ //if (! empty($arrayfields['s.entity']['checked']))
+ {
+ $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"s.entity","",$param,'align="center"',$sortfield,$sortorder);
+ }
+ }
+ else if (in_array('contactlist', $currentcontext))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"p.entity","",$param,'align="center"',$sortfield,$sortorder);
+ }
+ }
+ else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"p.entity","",$param,'align="center"',$sortfield,$sortorder);
+ }
+ }
+ else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"c.entity","",$param,'align="center"',$sortfield,$sortorder);
+ }
+ }
+ else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice']))
+ {
+ //if (! empty($arrayfields['f.entity']['checked']))
+ {
+ $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"f.entity","",$param,'align="center"',$sortfield,$sortorder);
+ }
+ }
+ }
+
+ if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"p.entity","",$param,'align="center"',$sortfield,$sortorder);
+ }
+ }
+
+ if (in_array('stocklist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"t.entity","",$param,'align="center"',$sortfield,$sortorder);
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ * @param boolean $parameters
+ * @return number
+ */
+ public function printFieldListValue($parameters=false)
+ {
+ global $conf;
+ global $totalarray;
+ global $mc;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED))
+ {
+ if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty']))
+ {
+ if (in_array('thirdpartylist', $currentcontext) || in_array('contactlist', $currentcontext))
+ {
+ //if (! empty($arrayfields['s.entity']['checked']) || ! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->getInfo($obj->entity);
+ $this->resprints = ''.$this->label." \n";
+ }
+ }
+ else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->getInfo($obj->entity);
+ $this->resprints = ''.$this->label." \n";
+ if (! $i) $totalarray['nbfield']++;
+ }
+ }
+ else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->getInfo($obj->entity);
+ $this->resprints = ''.$this->label." \n";
+ if (! $i) $totalarray['nbfield']++;
+ }
+ }
+ else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice']))
+ {
+ //if (! empty($arrayfields['f.entity']['checked']))
+ {
+ $this->getInfo($obj->entity);
+ $this->resprints = ''.$this->label." \n";
+ if (! $i) $totalarray['nbfield']++;
+ }
+ }
+ }
+
+ if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->getInfo($obj->entity);
+ $this->resprints = ''.$this->label." \n";
+ }
+ }
+
+ if (in_array('stocklist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock']))
+ {
+ //if (! empty($arrayfields['p.entity']['checked']))
+ {
+ $this->getInfo($obj->entity);
+ $this->resprints = ''.$this->label." \n";
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function insertExtraHeader($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user, $langs;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1 && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+ {
+ if (in_array('userperms', $currentcontext) || in_array('groupperms', $currentcontext))
+ {
+ $this->getInstanceDao();
+
+ if ($object->element == 'user')
+ {
+ $aEntities=array_keys($permsgroupbyentity);
+
+ // Check usergroup if user not in master entity
+ if (empty($aEntities) || ! array_key_exists(1, $permsgroupbyentity))
+ {
+ require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
+ $aEntities=array();
+ $group = new UserGroup($this->db);
+ $ret = $group->listGroupsForUser($object->id, false);
+ if (! empty($ret)) {
+ foreach($ret as $groupid => $data)
+ {
+ $aEntities = array_merge($aEntities, $data->usergroup_entity);
+ }
+ sort($aEntities);
+ }
+ }
+
+ if (! empty($aEntities))
+ {
+ $entity = (GETPOST('entity', 'int')?GETPOST('entity', 'int'):$aEntities[0]);
+ $head = entity_prepare_head($object, $aEntities);
+ $title = $langs->trans("Entities");
+ dol_fiche_head($head, $entity, $title, 1, 'multicompany@multicompany');
+ }
+ else
+ {
+ print get_htmloutput_mesg(img_warning('default') . ' ' . $langs->trans("ErrorLinkUserGroupEntity"), '', 'mc-upgrade-alert', 1);
+ }
+ }
+ else if ($object->element == 'usergroup')
+ {
+ $this->dao->getEntities();
+ $aEntities=array();
+
+ foreach ($this->dao->entities as $objEntity)
+ {
+ $aEntities[] = $objEntity->id;
+ }
+
+ $entity = (GETPOST('entity', 'int')?GETPOST('entity', 'int'):$aEntities[0]);
+ $head = entity_prepare_head($object, $aEntities);
+ $title = $langs->trans("Entities");
+ dol_fiche_head($head, $entity, $title, 1, 'multicompany@multicompany');
+
+ if (! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) {
+ print '
+
+
'.img_info().' '.$langs->transnoentities('DuplicateRightsInfo').'
+
'.$langs->transnoentities('SelectRightsOfEntityToDuplicate').' '.$this->select_entities('', 'template', '', false, false, false, false, '', 'minwidth200imp', true, true).'
+
'.$langs->transnoentities('SelectEntitiesToOverride').'
+
+
+
+
'.$langs->transnoentities("EntitiesSelected").'
+ '.$this->multiselectEntitiesToOverride('overrideentities', true).'
+
+
+
+
'.$langs->transnoentities("EntitiesAvailable").'
+ '.$this->multiselectEntitiesToOverride('overrideentities', false).'
+
+
+
+
+
+ ';
+ }
+ }
+
+ // Check if advanced perms is enabled for current object entity
+ $res = $this->dao->getEntityConfig($entity, 'MAIN_USE_ADVANCED_PERMS');
+ if (empty($res['MAIN_USE_ADVANCED_PERMS'])) {
+ unset($conf->global->MAIN_USE_ADVANCED_PERMS);
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function insertExtraFooter($parameters=false, &$object, &$action='')
+ {
+ global $conf, $user;
+
+ if (empty($conf->multicompany->enabled)) return 0;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key=>$value)
+ {
+ $$key=$value;
+ }
+ }
+
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1 && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+ {
+ if (in_array('userperms', $currentcontext) || in_array('groupperms', $currentcontext))
+ {
+ // Restore advanced perms if enabled for current entity
+ $this->getInstanceDao();
+ $res = $this->dao->getEntityConfig($conf->entity, 'MAIN_USE_ADVANCED_PERMS');
+ if (! empty($res['MAIN_USE_ADVANCED_PERMS'])) {
+ $conf->global->MAIN_USE_ADVANCED_PERMS = $res['MAIN_USE_ADVANCED_PERMS'];
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Return combo list of entities.
+ *
+ * @param int $selected Preselected entity
+ * @param int $htmlname Name
+ * @param string $option Option
+ * @param boolean $login If use in login page or not
+ * @param boolean $exclude Exclude
+ * @param boolean $emptyvalue Emptyvalue
+ * @param boolean $only Only
+ * @param string $all Add 'All entities' value in combo list
+ * @param string $cssclass specific css class. eg 'minwidth150imp mycssclass'
+ * @param bool $ajax Enable ajax combobox
+ * @param bool $template Show template of entities
+ * @return string
+ */
+ public function select_entities($selected = '', $htmlname = 'entity', $option = '', $login = false, $exclude = false, $emptyvalue = false, $only = false, $all = '', $cssclass = 'minwidth150imp', $ajax = true, $template = false)
+ {
+ global $conf, $user, $langs;
+
+ $this->getInstanceDao();
+
+ $this->dao->getEntities($login, $exclude);
+
+ $out = '';
+
+ if (is_array($this->dao->entities) && ! empty($this->dao->entities))
+ {
+ $out.= '';
+
+ if ($emptyvalue)
+ $out.= ' ';
+
+ if ($all)
+ $out.= ''.$langs->trans("AllEntities").' ';
+
+ foreach ($this->dao->entities as $entity)
+ {
+ if (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) && $entity->visible == 2) continue;
+ if ($template === 'only' && $entity->visible != 2) continue;
+ if (! $template && $entity->visible == 2) continue;
+
+ if ($entity->active == 1 && ($entity->visible == 1 || ($user->admin && ! $user->entity)))
+ {
+ if (is_array($only) && ! empty($only) && ! in_array($entity->id, $only)) continue;
+ if (! empty($user->login) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && ! empty($user->entity) && $this->checkRight($user->id, $entity->id) < 0) continue;
+
+ $out.= 'id) {
+ $out.= ' selected="selected"';
+ }
+ $out.= '>';
+ $out.= $entity->label;
+ if (empty($entity->visible)) {
+ $out.= ' ('.$langs->trans('Hidden').')';
+ } elseif ($entity->visible == 2) {
+ $out.= ' ('.$langs->trans('Template').')';
+ }
+ $out.= ' ';
+ }
+ }
+
+ $out.= ' ';
+
+ // Make select dynamic
+ if ($ajax) {
+ include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
+ $out.= ajax_combobox($htmlname);
+ }
+ }
+
+ return $out;
+ }
+
+ /**
+ * Return multiselect list of entities.
+ *
+ * @param string $htmlname Name of select
+ * @param DaoMulticompany $current Current entity to manage
+ * @param bool $onlyselected true: show only selected, false: hide only selected
+ * @return string
+ */
+ public function multiselect_entities($htmlname, $current, $onlyselected=false)
+ {
+ global $langs;
+
+ $this->getInstanceDao();
+ $this->dao->getEntities();
+
+ $selectname = ($onlyselected ? $htmlname.'_to[]' : 'from[]');
+ $selectid = ($onlyselected ? 'multiselect_shared_'.$htmlname.'_to' : 'multiselect_shared_'.$htmlname);
+
+ $return = '';
+ if (is_array($this->dao->entities))
+ {
+ foreach ($this->dao->entities as $entity)
+ {
+ if ($entity->visible == 2) continue;
+ if (is_object($current) && $current->id != $entity->id && $entity->active == 1)
+ {
+ if ((! $onlyselected && (empty($current->options['sharings'][$htmlname]) || ! in_array($entity->id, $current->options['sharings'][$htmlname]))) // All unselected
+ || ($onlyselected && is_array($current->options['sharings'][$htmlname]) && in_array($entity->id, $current->options['sharings'][$htmlname]))) // All selected
+ {
+ $return.= '';
+ $return.= $entity->label;
+ if (empty($entity->visible))
+ {
+ $return.= ' ('.$langs->trans('Hidden').')';
+ }
+ $return.= ' ';
+ }
+ }
+ }
+ }
+ $return.= ' ';
+
+ return $return;
+ }
+
+ /**
+ * Return multiselect list of entities to override.
+ *
+ * @param string $htmlname Name of select
+ * @param bool $onlyselected true: show only selected, false: hide only selected
+ * @return string
+ */
+ public function multiselectEntitiesToOverride($htmlname, $onlyselected=false)
+ {
+ global $langs;
+
+ $this->getInstanceDao();
+ $this->dao->getEntities();
+
+ $selectname = ($onlyselected ? $htmlname.'_to[]' : 'from[]');
+ $selectid = ($onlyselected ? 'multiselect_'.$htmlname.'_to' : 'multiselect_'.$htmlname);
+
+ $out = '';
+ if (!$onlyselected && is_array($this->dao->entities))
+ {
+ foreach ($this->dao->entities as $entity)
+ {
+ if ($entity->active == 1)
+ {
+ $out.= '';
+ $out.= $entity->label;
+ if (empty($entity->visible)) {
+ $out.= ' ('.$langs->trans('Hidden').')';
+ } elseif ($entity->visible == 2) {
+ $out.= ' ('.$langs->trans('Template').')';
+ }
+ $out.= ' ';
+ }
+ }
+ }
+ $out.= ' ';
+
+ return $out;
+ }
+
+ /**
+ * Return multiselect list of entities.
+ *
+ * @param string $htmlname Name of select
+ * @param array $selected Entities already selected
+ * @param string $option Option
+ * @return string
+ */
+ public function multiSelectEntities($htmlname, $selected=null, $option=null)
+ {
+ global $langs;
+
+ $this->getInstanceDao();
+ $this->dao->getEntities();
+
+ $return = '';
+ if (is_array($this->dao->entities))
+ {
+ foreach ($this->dao->entities as $entity)
+ {
+ if ($entity->visible == 2) continue;
+
+ $return.= 'id, $selected))
+ {
+ $return.= 'selected="selected"';
+ }
+ $return.= '>';
+ $return.= $entity->label;
+ if (empty($entity->visible))
+ {
+ $return.= ' ('.$langs->trans('Hidden').')';
+ }
+ $return.= ' ';
+ }
+ }
+ $return.= ' ';
+
+ return $return;
+ }
+
+ /**
+ * Switch to another entity.
+ *
+ * @param int $id User id
+ * @param int $entity Entity id
+ * @return int
+ */
+ public function checkRight($id, $entity)
+ {
+ global $user;
+
+ $this->getInstanceDao();
+
+ if ($this->dao->fetch($entity) > 0)
+ {
+ // Controle des droits sur le changement
+ if ($this->dao->verifyRight($entity, $id) || $user->admin)
+ {
+ return 1;
+ }
+ else
+ {
+ return -2;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ /**
+ * Switch to another entity.
+ * @param int $id Id of the destination entity
+ * @param int $userid
+ * @return int
+ */
+ public function switchEntity($id, $userid=null)
+ {
+ global $conf, $user;
+
+ $this->getInstanceDao();
+
+ if (!empty($userid))
+ {
+ $user=new User($this->db);
+ $user->fetch($userid);
+ }
+
+ if ($this->dao->fetch($id) > 0 && ! empty($this->dao->active)) // check if the entity is still active
+ {
+ // Controle des droits sur le changement
+ if (!empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX)
+ || (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $this->dao->verifyRight($id, $user->id))
+ || $user->admin)
+ {
+ $_SESSION['dol_entity'] = $id;
+ //$conf = new Conf(); FIXME some constants disappear
+ $conf->entity = $id;
+ $conf->setValues($this->db);
+ return 1;
+ }
+ else
+ {
+ //var_dump($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX);
+ //var_dump($conf->global->MULTICOMPANY_TRANSVERSE_MODE);
+ //var_dump($this->dao->verifyRight($id, $user->id));
+ return -2;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ /**
+ * Get entity info
+ * @param int $id Object id
+ */
+ public function getInfo($id)
+ {
+ $this->getInstanceDao();
+ $this->dao->fetch($id);
+
+ $this->id = $this->dao->id;
+ $this->label = $this->dao->label;
+ $this->country_id = $this->dao->country_id;
+ $this->country_code = $this->dao->country_code;
+ $this->currency_code = $this->dao->currency_code;
+ $this->language_code = $this->dao->language_code;
+ $this->description = $this->dao->description;
+ $this->options = $this->dao->options;
+ $this->active = $this->dao->active;
+ $this->visible = $this->dao->visible;
+ }
+
+ /**
+ * Get action title
+ * @param string $action Type of action
+ * @return string
+ */
+ public function getTitle($action='')
+ {
+ global $langs;
+
+ if ($action == 'create') return $langs->trans("AddEntity");
+ else if ($action == 'edit') return $langs->trans("EditEntity");
+ else return $langs->trans("EntitiesManagement");
+ }
+
+
+ /**
+ * Assigne les valeurs pour les templates
+ * @param string $action Type of action
+ */
+ public function assign_values($action='view')
+ {
+ global $conf, $langs, $user;
+ global $form, $formcompany, $formadmin;
+
+ require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
+
+ $this->tpl['extrafields'] = new ExtraFields($this->db);
+ // fetch optionals attributes and labels
+ $this->tpl['extralabels'] = $this->tpl['extrafields']->fetch_name_optionals_label('entity');
+
+ $this->getInstanceDao();
+
+ $this->template_dir = dol_buildpath('/multicompany/admin/tpl/');
+ $this->template = 'list.tpl.php';
+
+ if ($action == 'create' || $action == 'edit')
+ {
+ $this->template = 'card.tpl.php';
+
+ if ($action == 'edit' && GETPOSTISSET('id')) {
+ $ret = $this->dao->fetch(GETPOST('id', 'int'));
+ }
+
+ if (! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT))
+ {
+ $templatevalue = (GETPOSTISSET('template') ? GETPOST('template', 'int') : ($this->dao->visible === '2' ? 1 : 0));
+
+ if ($action == 'create') {
+ $this->tpl['template'] = $form->selectyesno('template', $templatevalue, 1);
+ $this->tpl['select_template'] = $this->select_entities('','usetemplate','',false,false,true,'','','minwidth200imp',true,'only');
+ } elseif ($templatevalue === 1) {
+ $this->tpl['template'] = $templatevalue;
+ }
+ }
+
+ // action
+ $this->tpl['action'] = $action;
+
+ // id
+ $this->tpl['id'] = (GETPOSTISSET('id')?GETPOST('id', 'int'):null);
+
+ // Label
+ $this->tpl['label'] = (GETPOSTISSET('label')?GETPOST('label', 'alpha'):$this->dao->label);
+
+ // Description
+ $this->tpl['description'] = (GETPOSTISSET('description')?GETPOST('description', 'alpha'):$this->dao->description);
+
+ // Company name
+ $this->tpl['name'] = (GETPOSTISSET('name')?GETPOST('name', 'alpha'):$this->dao->name);
+
+ // Address
+ $this->tpl['address'] = (GETPOSTISSET('address')?GETPOST('address', 'alpha'):$this->dao->address);
+
+ // Zip
+ $this->tpl['select_zip'] = $formcompany->select_ziptown((GETPOSTISSET('zipcode')?GETPOST('zipcode', 'alpha'):$this->dao->zip),'zipcode',array('town','selectcountry_id','departement_id'),6);
+
+ // Town
+ $this->tpl['select_town'] = $formcompany->select_ziptown((GETPOSTISSET('town')?GETPOST('town', 'alpha'):$this->dao->town),'town',array('zipcode','selectcountry_id','departement_id'),40);
+
+ if ($user->admin) $this->tpl['info_admin'] = info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
+
+
+ // We define country_id
+ if (GETPOSTISSET('country_id'))
+ {
+ $country_id = GETPOST('country_id', 'int');
+ }
+ else if (! empty($this->dao->country_id))
+ {
+ $country_id = $this->dao->country_id;
+ }
+ else if (! empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY))
+ {
+ $tmp = explode(':', $conf->global->MAIN_INFO_SOCIETE_COUNTRY);
+ $country_id = $tmp[0];
+ }
+ else
+ {
+ $country_id = 0;
+ }
+
+ $this->tpl['select_country'] = $form->select_country($country_id,'country_id');
+ $this->tpl['select_state'] = $formcompany->select_state((GETPOSTISSET('departement_id')?GETPOST('departement_id', 'int'):$this->dao->state_id),$country_id,'departement_id');
+ $this->tpl['select_currency'] = $form->selectCurrency((GETPOSTISSET('currency_code')?GETPOST('currency_code', 'alpha'):($this->dao->currency_code?$this->dao->currency_code:$conf->currency)),"currency_code");
+ $this->tpl['select_language'] = $formadmin->select_language((GETPOSTISSET('main_lang_default')?GETPOST('main_lang_default', 'alpha'):($this->dao->language_code?$this->dao->language_code:$conf->global->MAIN_LANG_DEFAULT)),'main_lang_default',1);
+
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) {
+ foreach ($this->sharingelements as $element => $params) {
+ if ((($params['object'] || $params['objectnumber']) && ! isset($params['disable'])) && (empty($conf->societe->enabled) || empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED))) continue;
+ $uppername = strtoupper($element);
+ $constname = 'MULTICOMPANY_' . $uppername . '_SHARING_ENABLED';
+ if (! empty($conf->global->$constname)) {
+ $this->tpl['multiselect_from_' . $element] = $this->multiselect_entities($element, $this->dao, false);
+ $this->tpl['multiselect_to_' . $element] = $this->multiselect_entities($element, $this->dao, true);
+ if ($element == 'proposalnumber' || $element == 'invoicenumber') {
+ $this->tpl['select_'.$element.'_entity'] = $this->select_entities($this->dao->options[$element.'_referent'], $element.'_referring_entity');
+ }
+ $addtoallother = (GETPOSTISSET('addtoallother_' . $element) ? GETPOST('addtoallother_' . $element, 'int') : $this->dao->options['addtoallother'][$element]);
+ $this->tpl['addtoallother_' . $element] = $form->selectyesno('addtoallother_' . $element, $addtoallother, 1);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Display the template
+ */
+ public function display()
+ {
+ global $conf, $langs;
+ global $form, $object;
+
+ include $this->template_dir.$this->template;
+ }
+
+ /**
+ * Set values of global conf for multicompany
+ *
+ * @param Conf $conf Object conf
+ * @return void
+ */
+ public function setValues(&$conf)
+ {
+ if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED))
+ {
+ $this->getInstanceDao();
+ $this->dao->fetch($conf->entity);
+
+ $this->sharings = $this->dao->options['sharings'];
+ //$this->referent = $this->dao->options['referent'];
+ $this->proposalnumber_referent = (isset($this->dao->options['proposalnumber_referent'])?$this->dao->options['proposalnumber_referent']:'');
+ $this->invoicenumber_referent = (isset($this->dao->options['invoicenumber_referent'])?$this->dao->options['invoicenumber_referent']:'');
+
+ // Load shared elements
+ $this->loadSharedElements();
+
+ // Define output dir for others entities
+ $this->setMultiOutputDir($conf);
+ }
+
+ if (! empty($this->sharingdicts))
+ {
+ foreach($this->sharingdicts as $dict => $data)
+ {
+ $constname = 'MULTICOMPANY_'.strtoupper($dict).'_SHARING_DISABLED';
+ if (! empty($conf->global->$constname)) {
+ $this->dict[$dict] = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Set status of an entity
+ *
+ * @param int $id Id of entity
+ * @param string $type Type of status (visible or active)
+ * @param string $value Value of status (0: disable, 1: enable)
+ * @return int
+ */
+ public function setStatus($id, $type='active', $value)
+ {
+ global $user;
+
+ if (! empty($user->admin) && ! $user->entity) {
+ $this->getInstanceDao();
+ return $this->dao->setEntity($id, $type, $value);
+ }
+ else {
+ return -1;
+ }
+ }
+
+ /**
+ * Delete an entity
+ *
+ * @param int $id Id of entity
+ * @return int
+ */
+ public function deleteEntity($id)
+ {
+ global $user;
+
+ if (! empty($user->admin) && ! $user->entity && $id != 1) {
+ $this->getInstanceDao();
+ return $this->dao->delete($id);
+ }
+ else {
+ return -1;
+ }
+ }
+
+ /**
+ * Get list of entity id to use.
+ *
+ * @param string $element Current element
+ * 'societe', 'socpeople', 'actioncomm', 'agenda', 'resource',
+ * 'product', 'productprice', 'stock',
+ * 'propal', 'supplier_proposal', 'invoice', 'facture_fourn', 'payment_various',
+ * 'categorie', 'bank_account', 'bank_account', 'adherent', 'user',
+ * 'commande', 'commande_fournisseur', 'expedition', 'intervention', 'survey',
+ * 'contract', 'tax', 'expensereport', 'holiday', 'multicurrency', 'project',
+ * 'email_template', 'event', 'donation'
+ * 'c_paiement', 'c_payment_term', ...
+ * @param int $shared 0=Return id of current entity only,
+ * 1=Return id of current entity + shared entities (default)
+ * @param object $currentobject Current object if needed
+ * @return mixed Entity id(s) to use ( eg. entity IN ('.getEntity(elementname).')' )
+ */
+ public function getEntity($element=false, $shared=1, $currentobject=null)
+ {
+ global $conf, $user;
+
+ $element = str_replace(MAIN_DB_PREFIX, '', $element);
+
+ if (in_array($element, $this->addzero))
+ {
+ if ($element == 'user' && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ return '0,1'; // In transverse mode all users except superadmin and groups are in entity 1
+ } else {
+ if ($element == 'usergroup' && $conf->entity == 1 && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && !empty($user->admin) && empty($user->entity))
+ {
+ return '0,'.implode(',', array_keys($this->getEntitiesList(true, false, true))); // Superadmin can always edit groups of another entities
+ }
+
+ return '0,'.$conf->entity;
+ }
+ }
+
+ // Sharing dictionnaries
+ if (array_key_exists($element, $this->sharingdicts))
+ {
+ if (! empty($this->dict[$element])) {
+ return $conf->entity;
+ } else {
+ return 1; // Master entity
+ }
+ }
+
+ // Check object entity when number sharing is disabled
+ if (is_object($currentobject) &&
+ (($element == 'proposalnumber' && empty($conf->global->MULTICOMPANY_PROPOSALNUMBER_SHARING_ENABLED))
+ || ($element == 'ordernumber' && empty($conf->global->MULTICOMPANY_ORDERNUMBER_SHARING_ENABLED))
+ || ($element == 'invoicenumber' && empty($conf->global->MULTICOMPANY_INVOICENUMBER_SHARING_ENABLED))
+ )
+ )
+ {
+ // Use object entity ID
+ $entity = ((isset($currentobject->entity) && is_numeric($currentobject->entity)) ? $currentobject->entity : $conf->entity);
+ return $entity;
+ }
+
+ $elementkey = $element;
+ if ($element == 'societe' || $element == 'socpeople' || $element == 'contact') {
+ $elementkey = 'thirdparty';
+ }
+ if ($element == 'adherent') $elementkey = 'member';
+ if ($element == 'bank_account') $elementkey = 'bankaccount';
+ if ($element == 'adherent_type') $elementkey = 'member_type';
+ if ($element == 'categorie') $elementkey = 'category';
+ if ($element == 'propal') $elementkey = 'proposal';
+ if ($element == 'commande') $elementkey = 'order';
+ if ($element == 'facture') $elementkey = 'invoice';
+
+ if (! empty($element) && ! empty($this->entities[$elementkey]))
+ {
+ if (! empty($shared))
+ {
+ return $this->entities[$elementkey];
+ }
+ else if (! empty($this->sharings['referent']))
+ {
+ if ($element == 'societe') return $this->sharings['referent'];
+ }
+ }
+
+ return $conf->entity;
+ }
+
+ /**
+ * Set entity id to use when to create an object
+ *
+ * @param object $currentobject Current object
+ * @return int Entity id to use
+ */
+ public function setEntity($currentobject)
+ {
+ global $conf;
+
+ $entity = $conf->entity;
+
+ if (is_object($currentobject) && ! empty($currentobject->element))
+ {
+ $element = array_search($currentobject->element, $this->sharingmodulename);
+ $element = (! empty($element) ? $element : $currentobject->element);
+ $constname = 'MULTICOMPANY_'.strtoupper($element).'_SHARING_ENABLED';
+ $newentity = $entity;
+
+ if (isset($this->sharingelements[$element])
+ && isset($this->sharingelements[$element]['active'])
+ && ! empty($conf->global->$constname)
+ )
+ {
+ if (GETPOSTISSET('entity') && GETPOST('entity', 'int', 2))
+ {
+ $newentity = GETPOST('entity', 'int', 2);
+ }
+ else if (isset($currentobject->entity) && is_numeric($currentobject->entity))
+ {
+ $newentity = $currentobject->entity;
+ }
+
+ if (isset($this->sharings[$element]) && in_array($newentity, $this->sharings[$element]))
+ {
+ $entity = $newentity;
+ }
+ }
+ else
+ {
+ $entity = (($currentobject->id > 0 && $currentobject->entity > 0) ? $currentobject->entity : $conf->entity);
+ }
+ }
+
+ return $entity;
+ }
+
+ /**
+ * Get entities list
+ *
+ * @param int $login If use in login page or not
+ * @param array $exclude Entity ids to exclude
+ * @param bool $onlyactive sort only active entities
+ * @param bool $showtemplate Show or not templates
+ * @return array Array of entities (id => label)
+ */
+ public function getEntitiesList($login = false, $exclude = false, $onlyactive = false, $showtemplate = false)
+ {
+ global $langs;
+
+ $this->getInstanceDao();
+ $this->dao->getEntities($login, $exclude, $onlyactive);
+
+ $entities=array();
+
+ foreach ($this->dao->entities as $entity)
+ {
+ if (empty($showtemplate) && $entity->visible == 2) continue;
+ $entities[$entity->id] = dol_html_entity_decode($entity->label, null) . (empty($entity->active) ? ' ('.$langs->transnoentities('Disabled').')' : ($entity->visible == 2 ? ' ('.$langs->transnoentities('Template').')' : (empty($entity->visible) ? ' ('.$langs->transnoentities('Hidden').')' : '')) );
+ }
+
+ return $entities;
+ }
+
+ /**
+ * Set object documents directory to use
+ *
+ * @param Conf $conf Object Conf
+ * @return void
+ */
+ public function setMultiOutputDir(&$conf)
+ {
+ if (! empty($this->entities))
+ {
+ foreach($this->entities as $element => $shares)
+ {
+ if ($element == 'thirdparty') $element = 'societe';
+ elseif ($element == 'member') $element = 'adherent';
+ elseif ($element == 'proposal') $element = 'propal';
+ elseif ($element == 'order') $element = 'commande';
+ elseif ($element == 'invoice') $element = 'facture';
+ elseif ($element == 'intervention') $element = 'ficheinter';
+
+ if (! empty($conf->$element->enabled) && isset($conf->$element->multidir_output) && isset($conf->$element->multidir_temp))
+ {
+ $elementpath=$element;
+ if ($element == 'product') $elementpath='produit';
+ elseif ($element == 'category') $elementpath='categorie';
+ elseif ($element == 'propal') $elementpath='propale';
+
+ $entities = explode(",", $shares);
+ $dir_output = array();
+ $dir_temp = array();
+ foreach($entities as $entity)
+ {
+ if (! array_key_exists($entity, $conf->$element->multidir_output))
+ {
+ $path = ($entity > 1 ? "/".$entity : '');
+
+ $dir_output[$entity] = DOL_DATA_ROOT.$path."/".$elementpath;
+ $dir_temp[$entity] = DOL_DATA_ROOT.$path."/".$elementpath."/temp";
+
+ $conf->$element->multidir_output += $dir_output;
+ $conf->$element->multidir_temp += $dir_temp;
+ }
+
+ if (in_array($element, array('propal', 'commande', 'facture')) && isset($conf->mycompany->multidir_output))
+ {
+ if (! array_key_exists($entity, $conf->mycompany->multidir_output))
+ {
+ $path = ($entity > 1 ? "/".$entity : '');
+
+ $dir_output[$entity] = DOL_DATA_ROOT.$path."/mycompany";
+ $dir_temp[$entity] = DOL_DATA_ROOT.$path."/mycompany/temp";
+
+ $conf->mycompany->multidir_output += $dir_output;
+ $conf->mycompany->multidir_temp += $dir_temp;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param bool $parameters
+ * @return int
+ */
+ public function printTopRightMenu($parameters=false)
+ {
+ echo $this->getTopRightMenu();
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function printBugtrackInfo($parameters=false)
+ {
+ global $conf;
+
+ if (! empty($conf->multicompany->enabled)) {
+ $this->resprints = urlencode("- **Multicompany**: " . $conf->global->MULTICOMPANY_MAIN_VERSION . "\n");
+ }
+
+ return 0;
+ }
+
+ /**
+ * @param bool $parameters
+ * @return int
+ */
+ /*public function afterLogin($parameters=false)
+ {
+ global $conf;
+
+ return 0;
+ }*/
+
+ /**
+ * @param bool $parameters
+ * @return int
+ */
+ public function updateSession($parameters=false)
+ {
+ global $conf;
+
+ // Switch to another entity
+ if (! empty($conf->multicompany->enabled) && GETPOST('action','aZ') == 'switchentity')
+ {
+ if ($this->switchEntity(GETPOST('entity','int')) > 0)
+ {
+ header("Location: ".DOL_URL_ROOT.'/');
+ exit;
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function getLoginPageOptions($parameters=false)
+ {
+ global $conf, $langs;
+
+ if (is_array($parameters) && ! empty($parameters))
+ {
+ foreach($parameters as $key => $value)
+ {
+ $$key=$value;
+ }
+ }
+
+ // Entity combobox
+ if (empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX))
+ {
+ if (empty($entity)) $entity=1;
+ $lastentity=(! empty($conf->global->MULTICOMPANY_FORCE_ENTITY)?$conf->global->MULTICOMPANY_FORCE_ENTITY:$entity);
+ $currentcontext = explode(':', $parameters['context']);
+
+ if (in_array('cashdeskloginpage', $currentcontext))
+ {
+ $select_entity = $this->select_entities($lastentity, 'entity', ' tabindex="3"', true, false, false, false, '', 'minwidth100imp');
+
+ $tableformat = '';
+ $tableformat.= ''.$langs->trans("Entity").' ';
+ $tableformat.= ''.$select_entity.' ';
+ $tableformat.= ' ';
+
+ $this->resprints = $tableformat;
+ }
+ else
+ {
+ $select_entity = $this->select_entities($lastentity, 'entity', ' tabindex="3"', true, false, false, false, '', 'login-entity minwidth180');
+
+ $divformat = "\n".'';
+
+ if (! empty($conf->global->MULTICOMPANY_LOGIN_LOGO_BY_ENTITY)) {
+ $divformat.= '
+ ';
+ }
+
+ $this->resprints = $divformat;
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ *
+ */
+ public function getPasswordForgottenPageOptions($parameters=false)
+ {
+ return $this->getLoginPageOptions($parameters);
+ }
+
+ /**
+ * Add all entities default dictionnaries in database
+ */
+ public function addAllEntitiesDefaultDicts()
+ {
+ if (! empty($this->sharingdicts))
+ {
+ $this->getInstanceDao();
+ $this->dao->getEntities();
+
+ $dir = "/multicompany/sql/dict/";
+
+ foreach($this->sharingdicts as $dict => $data)
+ {
+ // Load sql init_new_entity_dict.sql file
+ $file = 'init_new_entity_'.$dict.'.sql';
+ $fullpath = dol_buildpath($dir.$file);
+
+ if (file_exists($fullpath))
+ {
+ foreach ($this->dao->entities as $entity)
+ {
+ if ($entity->id == 1) continue;
+
+ $result=run_sql($fullpath,1,$entity->id);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Load shared elements
+ *
+ * @return void
+ */
+ private function loadSharedElements()
+ {
+ global $conf;
+
+ if (! empty($this->sharings))
+ {
+ $this->getInstanceDao();
+
+ foreach($this->sharings as $element => $ids)
+ {
+ $modulesharingenabled = 'MULTICOMPANY_'.strtoupper($element).'_SHARING_ENABLED';
+
+ $module = ((isset($this->sharingmodulename[$element]) && !empty($this->sharingmodulename[$element])) ? $this->sharingmodulename[$element] : $element);
+
+ if (! empty($conf->$module->enabled) && ! empty($conf->global->$modulesharingenabled))
+ {
+ $entities=array();
+
+ if (! empty($this->referent))
+ {
+ // Load configuration of referent entity
+ $this->config = $this->dao->getEntityConfig($this->referent);
+ $this->setConstant($conf, $element);
+ }
+
+ if (! empty($ids))
+ {
+ foreach ($ids as $id)
+ {
+ $ret=$this->dao->fetch($id);
+ if ($ret > 0 && $this->dao->active)
+ {
+ $entities[] = $id;
+ }
+ }
+
+ $this->entities[$element] = (! empty($entities) ? implode(",", $entities) : 0);
+ $this->entities[$element].= ','.$conf->entity;
+ }
+ }
+ }
+ }
+ //var_dump($this->entities);
+ }
+
+ /**
+ * Get modify entity dialog
+ */
+ private function getModifyEntityDialog($htmlname, $action, $object)
+ {
+ global $langs;
+
+ $langs->loadLangs(array('errors','multicompany@multicompany'));
+
+ $selectEntities = $this->select_entities('', 'entity' . $htmlname, '', false, array($object->entity));
+
+ $out = '';
+
+ if (! empty($selectEntities)) {
+
+ $out.= '';
+
+ $out.= '
+ ';
+
+ $out.= ''."\n";
+ $out.= '
' . img_warning() . ' ' . $langs->trans(ucfirst($htmlname) . 'ModifyEntityDescription') . '
'."\n";
+ $out.= '
' . $langs->trans('SelectAnEntity');
+ $out.= $selectEntities . '
'."\n";
+ $out.= '
'."\n";
+
+ $out.= '';
+ }
+
+ return $out;
+ }
+
+ /**
+ * Show entity info
+ */
+ private function getTopRightMenu()
+ {
+ global $conf, $user, $langs;
+
+ $langs->loadLangs(array('languages','admin','multicompany@multicompany'));
+
+ $out='';
+
+ if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) || ! empty($user->admin))
+ {
+ if (($conf->global->MAIN_THEME === 'eldy' && empty($conf->global->MULTICOMPANY_DROPDOWN_MENU_DISABLED) && ! GETPOSTISSET('theme')) || (GETPOSTISSET('theme') && GETPOST('theme', 'aZ', 1) === 'eldy'))
+ {
+ $out.= $this->getDropdownMenu();
+ }
+ else
+ {
+ $form=new Form($this->db);
+
+ $this->getInfo($conf->entity);
+
+ $selectEntities = $this->select_entities('', 'changeentity', '', false, array($conf->entity), false, false, '', 'minwidth200imp', true, true);
+
+ $text ='';
+ if (($conf->global->MAIN_THEME === 'eldy' && empty($conf->global->MULTICOMPANY_NO_TOP_MENU_ENTITY_LABEL) && ! GETPOSTISSET('theme')) || (GETPOSTISSET('theme') && GETPOST('theme', 'aZ', 1) === 'eldy')) {
+ $text.= '';
+ }
+ $text.= ' ';
+
+ if ($cache = getCache('country_' . $this->country_id)) {
+ $country = $cache;
+ } else {
+ $country = getCountry($this->country_id);
+ setCache('country_' . $this->country_id, $country);
+ }
+ $imgCountry=picto_from_langcode($this->country_code, 'class="multicompany-flag-country"');
+ $imgLang=picto_from_langcode($this->language_code, 'class="multicompany-flag-language"');
+
+ $htmltext =''.$langs->trans("Entity").' '."\n";
+ $htmltext.= ' ';
+ $htmltext.=''.$langs->trans("Label").' : '.$this->label."\n";
+ $htmltext.=''.$langs->trans("Country").' : '. ($imgCountry?$imgCountry.' ':'') . $country."\n";
+ $htmltext.=''.$langs->trans("Currency").' : '. currency_name($this->currency_code) . ' (' . $langs->getCurrencySymbol($this->currency_code) . ')'."\n";
+ $htmltext.=''.$langs->trans("Language").' : '. ($imgLang?$imgLang.' ':'') . ($this->language_code=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$this->language_code));
+ if (! empty($this->description)) $htmltext.=''.$langs->trans("Description").' : '.$this->description."\n";
+ $htmltext.= ' ';
+
+ $out.= $form->textwithtooltip('', $htmltext, 2, 1, $text, 'login_block_elem multicompany_block', 2);
+
+ if (! empty($selectEntities)) {
+ $out.= '
+ ';
+
+ $out.= ''."\n";
+ $out.= ' '.$langs->trans('SelectAnEntity');
+ $out.= $selectEntities;
+ $out.= '
'."\n";
+ } else {
+
+ }
+ }
+ }
+
+ if (($level = checkMultiCompanyVersion()) === -2)
+ {
+ $msg = get_htmloutput_mesg(img_warning('default') . ' ' . $langs->trans("MultiCompanyUpgradeIsNeeded"), '', 'mc-upgrade-alert', 1);
+ $out.= '
+ ';
+ }
+
+ $this->resprints = $out;
+ }
+
+ /**
+ *
+ * @return string
+ */
+ private function getDropdownMenu()
+ {
+ global $conf, $user, $langs;
+
+ $this->getInfo($conf->entity);
+
+ if ($cache = getCache('country_' . $this->country_id)) {
+ $country = $cache;
+ } else {
+ $country = getCountry($this->country_id);
+ setCache('country_' . $this->country_id, $country);
+ }
+ $imgCountry=picto_from_langcode($this->country_code, 'class="multicompany-flag-country"');
+ $imgLang=picto_from_langcode($this->language_code, 'class="multicompany-flag-language"');
+
+ $dropdownBody = '';
+ $dropdownBody.= '';
+ $dropdownBody.= '';
+
+ $selectEntities = $this->select_entities('', 'changeentity', '', false, array($conf->entity), false, false, '', 'minwidth200imp', true, true);
+
+ $entitySwitchLink ='';
+ $entityConfigLink ='';
+
+ $out = '';
+ $out.= '
';
+
+ $out.= '';
+
+ $out.= '
';
+
+ $out.= '
+ ';
+
+ return $out;
+ }
+
+ /**
+ * Set parameters with referent entity
+ *
+ * @param Conf $conf
+ * @param string $element
+ */
+ public function setConstant(&$conf, $element)
+ {
+ if (! empty($this->config))
+ {
+ $constants=array();
+
+ if ($element == 'thirdparty')
+ {
+ $constants = array(
+ 'SOCIETE_CODECLIENT_ADDON',
+ 'COMPANY_ELEPHANT_MASK_CUSTOMER',
+ 'COMPANY_ELEPHANT_MASK_SUPPLIER',
+ 'SOCIETE_IDPROF1_UNIQUE',
+ 'SOCIETE_IDPROF2_UNIQUE',
+ 'SOCIETE_IDPROF3_UNIQUE',
+ 'SOCIETE_IDPROF4_UNIQUE'
+ );
+ }
+
+ if (! empty($constants))
+ {
+ foreach($constants as $name)
+ {
+ if (! empty($this->config[$name])) $conf->global->$name = $this->config[$name];
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @param int $groupid
+ * @param int $template
+ * @param array $entities
+ * @return number
+ */
+ public function duplicateUserGroupRights($groupid, $template, $entities)
+ {
+ require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
+
+ $error=0;
+
+ dol_syslog(get_class($this)."::duplicateUserGroupRights groupid=".$groupid." template=".$template." entities=".implode(",", $entities), LOG_DEBUG);
+
+ $groupstatic = new UserGroup($this->db);
+ $ret = $groupstatic->fetch($groupid, '', false);
+ if ($ret > 0)
+ {
+ $this->getInstanceDao();
+ $permsgroupbyentity = $this->dao->getGroupRightsByEntity($groupid, $template);
+
+ if (! empty($entities))
+ {
+ foreach($entities as $entity)
+ {
+ if ($error > 0) break;
+
+ $ret = $groupstatic->delrights('', 'allmodules', '', $entity);
+ if ($ret < 0) {
+ $error++;
+ break;
+ }
+
+ foreach($permsgroupbyentity as $rid)
+ {
+ $ret = $groupstatic->addrights($rid, '', '', $entity);
+ if ($ret < 0) {
+ $error++;
+ break;
+ }
+ }
+ }
+
+ if (!$error) {
+ return 1;
+ } else {
+ return -1;
+ }
+
+ } else {
+ return -2;
+ }
+
+ } else {
+ return -3;
+ }
+ }
+
+}
diff --git a/htdocs/custom/multicompany/class/api_multicompany.class.php b/htdocs/custom/multicompany/class/api_multicompany.class.php
new file mode 100755
index 00000000000..46ba5284f75
--- /dev/null
+++ b/htdocs/custom/multicompany/class/api_multicompany.class.php
@@ -0,0 +1,334 @@
+
+ *
+ * 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;
+
+dol_include_once('/multicompany/class/dao_multicompany.class.php', 'DaoMulticompany');
+
+/**
+ * API class for multicompany
+ *
+ * @access protected
+ * @class DolibarrApiAccess {@requires user,external}
+ */
+class Multicompany extends DolibarrApi
+{
+ /**
+ * @var array $FIELDS Mandatory fields, checked when create and update object
+ */
+ static $FIELDS = array(
+ 'label'
+ );
+
+ /**
+ * Constructor
+ */
+ function __construct()
+ {
+ global $db, $conf;
+ $this->db = $db;
+ }
+
+ /**
+ * Get properties of an entity
+ *
+ * Return an array with entity informations
+ *
+ * @param int $id ID of entity
+ * @return array|mixed data without useless information
+ *
+ * @throws RestException
+ */
+ function get($id)
+ {
+ if (! DolibarrApiAccess::$user->rights->multicompany->read) {
+ throw new RestException(401);
+ }
+
+ // The DaoMulticompany::fetch() method uses the global variable $user.
+ global $user;
+ $user = DolibarrApiAccess::$user;
+
+ $multicompany = new DaoMulticompany($this->db);
+ $result = $multicompany->fetch($id);
+ if ( ! $result ) {
+ throw new RestException(404, 'entity not found');
+ }
+
+ return $this->_cleanObjectDatas($multicompany);
+ }
+
+ /**
+ * List entities
+ *
+ * Get a list of entities
+ *
+ * @param string $sortfield Sort field
+ * @param string $sortorder Sort order
+ * @param int $limit Limit for list
+ * @param int $page Page number
+ * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%') and (t.visible:=:'1')"
+ * @return array Array of entities objects
+ *
+ * @throws RestException
+ */
+ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') {
+ global $db, $conf;
+
+ $obj_ret = array();
+
+ if(! DolibarrApiAccess::$user->rights->multicompany->read) {
+ throw new RestException(401);
+ }
+
+ $sql = "SELECT t.rowid";
+ $sql.= " FROM ".MAIN_DB_PREFIX."entity as t";
+ $sql.= ' WHERE t.active = 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.= $db->order($sortfield, $sortorder);
+ if ($limit) {
+ if ($page < 0)
+ {
+ $page = 0;
+ }
+ $offset = $limit * $page;
+
+ $sql.= $db->plimit($limit + 1, $offset);
+ }
+
+ $result = $db->query($sql);
+ if ($result)
+ {
+ // The DaoMulticompany::fetch() method uses the global variable $user.
+ global $user;
+ $user = DolibarrApiAccess::$user;
+
+ $i=0;
+ $num = $db->num_rows($result);
+ $min = min($num, ($limit <= 0 ? $num : $limit));
+ while ($i < $min)
+ {
+ $obj = $db->fetch_object($result);
+ $multicompany= new DaoMulticompany($this->db);
+ if ($multicompany->fetch($obj->rowid)) {
+ $obj_ret[] = $this->_cleanObjectDatas($multicompany);
+ }
+ $i++;
+ }
+ }
+ else {
+ throw new RestException(503, 'Error when retrieve entities list : '.$db->lasterror());
+ }
+ if ( ! count($obj_ret)) {
+ throw new RestException(404, 'No entities found');
+ }
+
+ return $obj_ret;
+ }
+
+ /**
+ * Create entity object
+ *
+ * @param array $request_data Request data
+ * @return int ID of entity
+ */
+ /*function post($request_data = null)
+ {
+ if (! DolibarrApiAccess::$user->rights->adherent->configurer) {
+ throw new RestException(401);
+ }
+ // Check mandatory fields
+ $result = $this->_validate($request_data);
+
+ $membertype = new AdherentType($this->db);
+ foreach($request_data as $field => $value) {
+ $membertype->$field = $value;
+ }
+ if ($membertype->create(DolibarrApiAccess::$user) < 0) {
+ throw new RestException(500, 'Error creating member type', array_merge(array($membertype->error), $membertype->errors));
+ }
+ return $membertype->id;
+ }*/
+
+ /**
+ * Update entity
+ *
+ * @param int $id ID of entity to update
+ * @param array $request_data Datas
+ * @return int
+ */
+ /*function put($id, $request_data = null)
+ {
+ if (! DolibarrApiAccess::$user->rights->adherent->configurer) {
+ throw new RestException(401);
+ }
+
+ $membertype = new AdherentType($this->db);
+ $result = $membertype->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'member type not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('member',$membertype->id,'adherent_type')) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ foreach($request_data as $field => $value) {
+ if ($field == 'id') continue;
+ // Process the status separately because it must be updated using
+ // the validate() and resiliate() methods of the class AdherentType.
+ $membertype->$field = $value;
+ }
+
+ // If there is no error, update() returns the number of affected rows
+ // so if the update is a no op, the return value is zero.
+ if ($membertype->update(DolibarrApiAccess::$user) >= 0)
+ return $this->get($id);
+
+ return false;
+ }*/
+
+ /**
+ * Delete entity
+ *
+ * @param int $id entity ID
+ * @return array
+ */
+ /*function delete($id)
+ {
+ if (! DolibarrApiAccess::$user->rights->adherent->configurer) {
+ throw new RestException(401);
+ }
+ $membertype = new AdherentType($this->db);
+ $result = $membertype->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'member type not found');
+ }
+
+ if ( ! DolibarrApi::_checkAccessToResource('member',$membertype->id,'adherent_type')) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ if (! $membertype->delete($membertype->id)) {
+ throw new RestException(401,'error when deleting member type');
+ }
+
+ return array(
+ 'success' => array(
+ 'code' => 200,
+ 'message' => 'member type deleted'
+ )
+ );
+ }*/
+
+ /**
+ * Validate fields before creating an object
+ *
+ * @param array|null $data Data to validate
+ * @return array
+ *
+ * @throws RestException
+ */
+ function _validate($data)
+ {
+ $membertype = array();
+ foreach (MembersTypes::$FIELDS as $field) {
+ if (!isset($data[$field]))
+ throw new RestException(400, "$field field missing");
+ $membertype[$field] = $data[$field];
+ }
+ return $membertype;
+ }
+
+ /**
+ * Clean sensible object datas
+ *
+ * @param object $object Object to clean
+ * @return array Array of cleaned object properties
+ */
+ function _cleanObjectDatas($object) {
+
+ $object = parent::_cleanObjectDatas($object);
+
+ // Remove constants
+ foreach($object as $key => $value)
+ {
+ if (preg_match('/^MAIN_/', $key))
+ {
+ unset($object->$key);
+ }
+ }
+
+ unset($object->language);
+ unset($object->fk_tables);
+ unset($object->import_key);
+ unset($object->array_options);
+ unset($object->linkedObjectsIds);
+ unset($object->context);
+ unset($object->canvas);
+ unset($object->fk_project);
+ unset($object->contact);
+ unset($object->contact_id);
+ unset($object->thirdparty);
+ unset($object->user);
+ unset($object->origin);
+ unset($object->origin_id);
+ unset($object->ref_ext);
+ unset($object->barcode_type);
+ unset($object->barcode_type_code);
+ unset($object->barcode_type_label);
+ unset($object->barcode_type_coder);
+ unset($object->mode_reglement_id);
+ unset($object->cond_reglement_id);
+ unset($object->cond_reglement);
+ unset($object->fk_delivery_address);
+ unset($object->shipping_method_id);
+ unset($object->modelpdf);
+ unset($object->fk_account);
+ unset($object->note_public);
+ unset($object->note_private);
+ unset($object->fk_incoterms);
+ unset($object->libelle_incoterms);
+ unset($object->location_incoterms);
+ unset($object->name);
+ unset($object->lastname);
+ unset($object->firstname);
+ unset($object->civility_id);
+ unset($object->total_ht);
+ unset($object->total_tva);
+ unset($object->total_localtax1);
+ unset($object->total_localtax2);
+ unset($object->total_ttc);
+ unset($object->ref);
+ unset($object->statut);
+ unset($object->note);
+
+ return $object;
+ }
+
+}
diff --git a/htdocs/custom/multicompany/class/dao_multicompany.class.php b/htdocs/custom/multicompany/class/dao_multicompany.class.php
new file mode 100755
index 00000000000..1760b43094f
--- /dev/null
+++ b/htdocs/custom/multicompany/class/dao_multicompany.class.php
@@ -0,0 +1,990 @@
+
+ * Copyright (C) 2011 Herve Prot
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \file htdocs/multicompany/dao_multicompany.class.php
+ * \ingroup multicompany
+ * \brief File Class multicompany
+ */
+require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
+
+/**
+ * \class DaoMulticompany
+ * \brief Class of the module multicompany
+ */
+class DaoMulticompany extends CommonObject
+{
+ public $element = 'entity'; // !< Id that identify managed objects
+ public $table_element = 'entity'; // !< Name of table without prefix where object is stored
+
+ public $id;
+ public $label;
+ public $description;
+
+ public $options=array();
+ public $options_json;
+
+ public $entity=array();
+ public $entities=array();
+
+ public $fk_tables=array();
+
+ public $visible;
+ public $active;
+ public $currency;
+ public $language;
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ $this->db = $db;
+
+ $this->fk_tables = array(
+ 'societe' => array(
+ 'key' => 'fk_soc',
+ 'childs' => array(
+ 'societe_address',
+ 'societe_commerciaux',
+ 'societe_log',
+ 'societe_prices',
+ 'societe_remise',
+ 'societe_remise_except',
+ 'societe_rib',
+ 'socpeople'
+ )
+ ),
+ 'product' => array(
+ 'key' => 'fk_product',
+ 'childs' => array(
+ 'product_ca',
+ 'product_lang',
+ 'product_price',
+ 'product_stock',
+ 'product_fournisseur_price' => array(
+ 'key' => 'fk_product_fournisseur',
+ 'childs' => array('product_fournisseur_price_log')
+ ),
+ )
+ ),
+ 'projet' => array(
+ 'key' => 'fk_projet',
+ 'childs' => array(
+ 'projet_task' => array(
+ 'key' => 'fk_task',
+ 'childs' => array('projet_task_time')
+ )
+ )
+ )
+ );
+ }
+
+ /**
+ * Fetch entity
+ *
+ * @param int $id
+ * @return int
+ */
+ public function fetch($id)
+ {
+ global $user;
+
+ //clearCache($id);
+ if ($cache = getCache($id))
+ {
+ foreach ($cache as $key => $value)
+ {
+ $this->$key = $value;
+ }
+ }
+ else
+ {
+ $sql = "SELECT rowid, label, description, options, visible, active";
+ $sql.= " FROM ".MAIN_DB_PREFIX."entity";
+ $sql.= " WHERE rowid = ".$id;
+
+ $result = $this->db->query($sql);
+ if ($result)
+ {
+ if ($this->db->num_rows($result))
+ {
+ $obj = $this->db->fetch_object($result);
+
+ $this->id = $obj->rowid;
+ $this->label = $obj->label;
+ $this->description = $obj->description;
+ $this->options = json_decode($obj->options, true);
+ $this->visible = $obj->visible;
+ $this->active = $obj->active;
+
+ if (is_array($this->options) && ! empty($this->options) && is_array($this->options['sharings']))
+ {
+ // for backward compatibility
+ if (array_key_exists('referent', $this->options['sharings']))
+ {
+ if (empty($this->options['referent']))
+ {
+ $this->options['referent'] = $this->options['sharings']['referent'];
+ }
+ unset($this->options['sharings']['referent']);
+ }
+
+ // for backward compatibility
+ if (array_key_exists('societe', $this->options['sharings']))
+ {
+ if (empty($this->options['sharings']['thirdparty']))
+ {
+ $this->options['sharings']['thirdparty'] = $this->options['sharings']['societe'];
+ }
+ unset($this->options['sharings']['societe']);
+ }
+
+ // for backward compatibility
+ if (array_key_exists('bank_account', $this->options['sharings']))
+ {
+ if (empty($this->options['sharings']['bankaccount']))
+ {
+ $this->options['sharings']['bankaccount'] = $this->options['sharings']['bank_account'];
+ }
+ unset($this->options['sharings']['bank_account']);
+ }
+ }
+
+ $this->fetch_optionals();
+
+ $cache = array(
+ 'id' => $this->id,
+ 'label' => $this->label,
+ 'description' => $this->description,
+ 'options' => $this->options,
+ 'visible' => $this->visible,
+ 'active' => $this->active,
+ 'array_options' => $this->array_options
+ );
+
+ setCache($this->id, $cache);
+ }
+ else
+ {
+ return -2;
+ }
+ }
+ else
+ {
+ return -3;
+ }
+ }
+
+ if (! empty($user->login))
+ {
+ $this->getConstants();
+ }
+
+ return 1;
+ }
+
+ /**
+ * Create entity
+ *
+ * @param User $user Object of user that ask creation
+ * @param int $call_trigger false = no, true = yes
+ * @return int >= 0 if OK, < 0 if KO
+ */
+ public function create(User $user, $call_trigger = true)
+ {
+ global $conf;
+
+ $error=0;
+
+ // Clean parameters
+ $this->label = trim($this->label);
+ $this->description = trim($this->description);
+ $this->options_json = json_encode($this->options);
+
+ dol_syslog(get_class($this)."::create ".$this->label);
+
+ $this->db->begin();
+
+ $now=dol_now();
+
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."entity (";
+ $sql.= "label";
+ $sql.= ", description";
+ $sql.= ", datec";
+ $sql.= ", fk_user_creat";
+ $sql.= ", options";
+ $sql.= ", visible";
+ $sql.= ", active";
+ $sql.= ") VALUES (";
+ $sql.= "'".$this->db->escape($this->label)."'";
+ $sql.= ", '".$this->db->escape($this->description)."'";
+ $sql.= ", '".$this->db->idate($now)."'";
+ $sql.= ", ".$user->id;
+ $sql.= ", '".$this->db->escape($this->options_json)."'";
+ $sql.= ", ".(! empty($this->visible)?$this->db->escape($this->visible):0);
+ $sql.= ", ".(! empty($this->active)?$this->db->escape($this->active):0);
+ $sql.= ")";
+
+ dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG);
+ $result=$this->db->query($sql);
+ if ($result)
+ {
+ $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."entity");
+
+ if (! $error) {
+
+ if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) {
+ $result = $this->insertExtraFields();
+ if ($result < 0) {
+ $error ++;
+ }
+ }
+ }
+
+ dol_syslog(get_class($this)."::Create success id=".$this->id);
+ }
+
+ if (!$error && $call_trigger)
+ {
+ // Call trigger
+ $result = $this->call_trigger('MULTICOMPANY_CREATE', $user);
+ if ($result < 0) $error++;
+ // End call triggers
+ }
+
+ if (empty($error)) {
+ $this->db->commit();
+ return $this->id;
+ }
+ else
+ {
+ dol_syslog(get_class($this)."::Create echec ".$this->error);
+ $this->db->rollback();
+ return -1;
+ }
+ }
+
+ /**
+ * Update entity
+ *
+ * @param int $id Id of entity (deprecated, use 0 here and call update on an object loaded by a fetch)
+ * @param User $user User who requests the update
+ * @param int $call_trigger false = no, true = yes
+ * @return int <0 if KO, >=0 if OK
+ */
+ public function update($id, User $user, $call_trigger = true)
+ {
+ global $conf;
+
+ $error=0;
+
+ if (empty($id)) $id = $this->id;
+
+ // Clean parameters
+ $this->label = trim($this->label);
+ $this->description = trim($this->description);
+ $this->options_json = json_encode($this->options);
+
+ dol_syslog(get_class($this)."::update id=".$id." label=".$this->label);
+
+ $this->db->begin();
+
+ $sql = "UPDATE ".MAIN_DB_PREFIX."entity SET";
+ $sql.= " label = '" . $this->db->escape($this->label) ."'";
+ $sql.= ", description = '" . $this->db->escape($this->description) ."'";
+ $sql.= ", options = '" . $this->db->escape($this->options_json) ."'";
+ $sql.= " WHERE rowid = " . $id;
+
+ dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG);
+ $result=$this->db->query($sql);
+ if ($result)
+ {
+ dol_syslog(get_class($this)."::Update success id=".$id);
+
+ if (! $error) {
+
+ if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) {
+ $result = $this->insertExtraFields();
+ if ($result < 0) {
+ $error ++;
+ }
+ }
+ }
+ }
+
+ if (!$error && $call_trigger)
+ {
+ // Call trigger
+ $result = $this->call_trigger('MULTICOMPANY_MODIFY', $user);
+ if ($result < 0) $error++;
+ // End call triggers
+ }
+
+ if (empty($error)) {
+ $this->db->commit();
+ clearCache($id);
+ clearCache('constants_' . $id);
+ return 1;
+ }
+ else
+ {
+ dol_syslog(get_class($this)."::Update echec ".$this->error, LOG_ERR);
+ $this->db->rollback();
+ return -1;
+ }
+ }
+
+ /**
+ * Delete entity
+ *
+ * @param int $id Id of entity to delete
+ * @param int $call_trigger false = no, true = yes
+ * @return int <0 if KO, >0 if OK
+ */
+ public function delete($id, $call_trigger = true)
+ {
+ global $user;
+
+ $error=0;
+
+ $this->db->begin();
+
+ if (!$error && $call_trigger)
+ {
+ // Call trigger
+ $result = $this->call_trigger('MULTICOMPANY_DELETE', $user);
+ if ($result < 0) $error++;
+ // End call triggers
+ }
+
+ if (! $error)
+ {
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
+ $sql.= " WHERE entity = " . $id;
+ dol_syslog(get_class($this)."::Delete sql=".$sql, LOG_DEBUG);
+ if ($this->db->query($sql))
+ {
+ // TODO remove records of all tables
+ }
+ else
+ {
+ $error++;
+ $this->error .= $this->db->lasterror();
+ dol_syslog(get_class($this)."::Delete erreur -1 ".$this->error, LOG_ERR);
+ }
+ }
+
+ // Removed extrafields
+ if (!$error)
+ {
+ $result = $this->deleteExtraFields();
+ if ($result < 0)
+ {
+ $error++;
+ dol_syslog(get_class($this)."::delete error -2 ".$this->error, LOG_ERR);
+ }
+ }
+
+ if (! $error)
+ {
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."entity";
+ $sql.= " WHERE rowid = " . $id;
+ dol_syslog(get_class($this)."::Delete sql=".$sql, LOG_DEBUG);
+ if (!$this->db->query($sql)) {
+ $error++;
+ $this->error .= $this->db->lasterror();
+ dol_syslog(get_class($this)."::Delete erreur -1 ".$this->error, LOG_ERR);
+ }
+ }
+
+ if (! $error)
+ {
+ dol_syslog(get_class($this)."::Delete success id=".$id);
+ $this->db->commit();
+ clearCache($id);
+ clearCache('constants_' . $id);
+ return 1;
+ }
+ else
+ {
+ dol_syslog(get_class($this)."::Delete echec ".$this->error);
+ $this->db->rollback();
+ return -1;
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ public function getConstants()
+ {
+ $key = 'constants_' . $this->id;
+ //clearCache('constants_' . $this->id);
+
+ if ($cache = getCache($key))
+ {
+ foreach ($cache as $key => $value)
+ {
+ $this->$key = $value;
+ }
+ }
+ else
+ {
+ $cache=array();
+
+ $sql = "SELECT ";
+ $sql.= $this->db->decrypt('name')." as name";
+ $sql.= ", ".$this->db->decrypt('value')." as value";
+ $sql.= " FROM ".MAIN_DB_PREFIX."const";
+ $sql.= " WHERE entity = ".$this->id;
+ $sql.= " AND ".$this->db->decrypt('name')." LIKE 'MAIN_%'";
+
+ $result = $this->db->query($sql);
+ if ($result)
+ {
+ $num=$this->db->num_rows($result);
+ $i=0;
+
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($result);
+
+ if ($obj->name === 'MAIN_INFO_SOCIETE_COUNTRY')
+ {
+ $tmp = explode(':', $obj->value);
+ $this->country_id = $tmp[0];
+ $cache['country_id'] = $this->country_id;
+ $this->country_code = $tmp[1];
+ $cache['country_code'] = $this->country_code;
+ }
+ else if ($obj->name === 'MAIN_MONNAIE')
+ {
+ $this->currency_code = $obj->value;
+ $cache['currency_code'] = $this->currency_code;
+ }
+ else if ($obj->name === 'MAIN_LANG_DEFAULT')
+ {
+ $this->language_code = $obj->value;
+ $cache['language_code'] = $this->language_code;
+ }
+ else if ($obj->name === 'MAIN_INFO_SOCIETE_NOM')
+ {
+ $this->name = $obj->value;
+ $cache['name'] = $this->name;
+ }
+ else if ($obj->name === 'MAIN_INFO_SOCIETE_ZIP')
+ {
+ $this->zip = $obj->value;
+ $cache['zip'] = $this->zip;
+ }
+ else if ($obj->name === 'MAIN_INFO_SOCIETE_ADDRESS')
+ {
+ $this->address = $obj->value;
+ $cache['address'] = $this->address;
+ }
+ else if ($obj->name === 'MAIN_INFO_SOCIETE_TOWN')
+ {
+ $this->town = $obj->value;
+ $cache['town'] = $this->town;
+ }
+ else if ($obj->name === 'MAIN_INFO_SOCIETE_STATE')
+ {
+ $this->state_id = $obj->value;
+ $cache['state_id'] = $this->state_id;
+ }
+
+ $constname = $obj->name;
+ $this->$constname = $obj->value;
+ $cache[$constname] = $this->$constname;
+
+ $i++;
+ }
+
+ setCache($key, $cache);
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ return 1;
+ }
+
+ /**
+ * Remove all records of an entity
+ *
+ * @param int $id Entity id
+ * @return int
+ */
+ private function deleteEntityRecords($id)
+ {
+ $error=1;
+
+ $this->db->begin();
+
+ $tables = $this->db->DDLListTables($this->db->database_name);
+ if (is_array($tables) && ! empty($tables))
+ {
+ foreach($tables as $table)
+ {
+ $fields = $this->db->DDLInfoTable($table);
+ foreach ($fields as $field)
+ {
+ if (is_array($field) && in_array('entity', $field))
+ {
+ $tablewithoutprefix = str_replace(MAIN_DB_PREFIX, '', $table);
+ $objIds = $this->getIdByForeignKey($tablewithoutprefix, $id);
+ if (! empty($objIds))
+ {
+ if (array_key_exists($tablewithoutprefix, $this->fk_tables))
+ {
+ // Level 0
+ $foreignKey = $this->fk_tables[$tablewithoutprefix]['key'];
+ foreach($this->fk_tables[$tablewithoutprefix]['childs'] as $childTable => $child)
+ {
+ // Level 1
+ if (! is_int($childTable) && is_array($child))
+ {
+ echo 'childTableLevel1='.$childTable.' ';
+ $objLevel1Ids = array();
+ foreach($objIds as $rowid)
+ {
+ $ret = $this->getIdByForeignKey($childTable, $rowid, $foreignKey);
+ if (!empty($ret))
+ $objLevel1Ids = array_merge($objLevel1Ids, $ret);
+ }
+
+ sort($objLevel1Ids);
+ //var_dump($objLevel1Ids);
+
+ // Level 2
+ foreach($child['childs'] as $childLevel2)
+ {
+ echo 'childTableLevel2='.$childLevel2.' ';
+ foreach($objLevel1Ids as $rowid)
+ {
+ $sql = "DELETE FROM " . MAIN_DB_PREFIX . $childLevel2;
+ $sql.= " WHERE " . $child['key'] . " = " . $rowid;
+ //echo $sql.' ';
+ //dol_syslog(get_class($this)."::deleteEntityRecords sql=" . $sql, LOG_DEBUG);
+ /*if (!$this->db->query($sql)) {
+ $error++;
+ $this->error .= $this->db->lasterror();
+ dol_syslog(get_class($this)."::deleteEntityRecords error -1 " . $this->error, LOG_ERR);
+ }*/
+ }
+ }
+
+ foreach($objIds as $rowid)
+ {
+ $sql = "DELETE FROM " . MAIN_DB_PREFIX . $childTable;
+ $sql.= " WHERE " . $foreignKey . " = " . $rowid;
+ //echo $sql.' ';
+ //dol_syslog(get_class($this)."::deleteEntityRecords sql=" . $sql, LOG_DEBUG);
+ /*if (!$this->db->query($sql)) {
+ $error++;
+ $this->error .= $this->db->lasterror();
+ dol_syslog(get_class($this)."::deleteEntityRecords error -1 " . $this->error, LOG_ERR);
+ }*/
+ }
+ }
+ else
+ {
+ foreach($objIds as $rowid)
+ {
+ $sql = "DELETE FROM " . MAIN_DB_PREFIX . $child;
+ $sql.= " WHERE " . $foreignKey . " = " . $rowid;
+ //echo $sql.' ';
+ //dol_syslog(get_class($this)."::deleteEntityRecords sql=" . $sql, LOG_DEBUG);
+ /*if (!$this->db->query($sql)) {
+ $error++;
+ $this->error .= $this->db->lasterror();
+ dol_syslog(get_class($this)."::deleteEntityRecords error -1 " . $this->error, LOG_ERR);
+ }*/
+ }
+ }
+ }
+ echo 'with childs = '.$table.' ';
+ }
+ else
+ {
+ echo 'without childs = '.$table.' ';
+ }
+ }
+ }
+ }
+ }
+
+ if (! $error)
+ {
+ dol_syslog(get_class($this)."::deleteEntityRecords success entity=".$id);
+ $this->db->commit();
+ return 1;
+ }
+ else
+ {
+ dol_syslog(get_class($this)."::deleteEntityRecords echec ".$this->error);
+ $this->db->rollback();
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Get all rowid from a table by couple foreign key / id
+ *
+ * @param string $table
+ * @param int $id
+ * @param string $foreignkey
+ * @param string $fieldname
+ * @return int[]
+ */
+ private function getIdByForeignKey($table, $id, $foreignkey = 'entity', $fieldname = 'rowid')
+ {
+ $objIds=array();
+ $foreignkey = (! empty($foreignkey) ? $foreignkey : 'entity');
+ $fieldname = (! empty($fieldname) ? $fieldname : 'rowid');
+
+ $sql = "SELECT " . $fieldname . " FROM " . MAIN_DB_PREFIX . $table;
+ $sql.= " WHERE " . $foreignkey . " = " . $id;
+ //echo $sql.' ';
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ $i = 0;
+ $num = $this->db->num_rows($resql);
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+ $objIds[] = $obj->$fieldname;
+ $i++;
+ }
+ }
+
+ return $objIds;
+ }
+
+ /**
+ * Set status of an entity
+ *
+ * @param int $id Id of entity
+ * @param string $type Type of status (visible or active)
+ * @param string $value Value of status (0: disable, 1: enable)
+ * @return int
+ */
+ public function setEntity($id, $type='active', $value)
+ {
+ $this->db->begin();
+
+ $sql = "UPDATE ".MAIN_DB_PREFIX."entity";
+ $sql.= " SET " . $this->db->escape($type) . " = " . (int) $value;
+ $sql.= " WHERE rowid = " . (int) $id;
+
+ dol_syslog(get_class($this)."::setEntity sql=".$sql, LOG_DEBUG);
+ $result = $this->db->query($sql);
+ if ($result)
+ {
+ $this->db->commit();
+ clearCache($id);
+ return 1;
+ }
+ else
+ {
+ $this->db->rollback();
+ return -1;
+ }
+ }
+
+ /**
+ * List of entities
+ *
+ * @param int $login If use in login page or not
+ * @param array $exclude Entity ids to exclude
+ * @param bool $onlyactive sort only active entities
+ * @return void
+ */
+ public function getEntities($login = false, $exclude = false, $onlyactive = false)
+ {
+ global $conf, $user;
+
+ $this->entities=array();
+
+ if ($login || empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) || (! empty($user->admin) && empty($user->entity)))
+ {
+ $sql = "SELECT DISTINCT(rowid), rang"; // Distinct parce que si user dans plusieurs groupes d'une entité, la liste d'entités de la petite terre affiche plusieurs fois la même entité
+ $sql.= " FROM ".MAIN_DB_PREFIX."entity";
+ if (! empty($user->admin) && empty($user->entity) && is_array($exclude) && ! empty($exclude))
+ {
+ $exclude = implode(",", $exclude);
+ $sql.= " WHERE rowid NOT IN (" . $exclude .")";
+ if (! empty($onlyactive)) $sql.= " AND active = 1";
+ }
+ else if (! empty($onlyactive)) {
+ $sql.= " WHERE active = 1";
+ }
+ if (!$login) {
+ $sql.= " ORDER BY rowid";
+ }
+ else {
+ $sql.= " ORDER BY rang DESC, rowid ASC";
+ }
+ }
+ else
+ {
+ $sql = "SELECT DISTINCT(entity) as rowid"; // Distinct parce que si user dans plusieurs groupes d'une entité, la liste d'entités de la petite terre affiche plusieurs fois la même entité
+ $sql.= " FROM ".MAIN_DB_PREFIX."usergroup_user";
+ $sql.= " WHERE fk_user = ".$user->id;
+ $sql.= " ORDER BY entity";
+ }
+
+ $result = $this->db->query($sql);
+ if ($result)
+ {
+ $num = $this->db->num_rows($result);
+ $i = 0;
+
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($result);
+
+ $objectstatic = new self($this->db);
+ $ret = $objectstatic->fetch($obj->rowid);
+
+ $this->entities[$i] = $objectstatic;
+
+ $i++;
+ }
+ }
+ }
+
+ /**
+ * Check user $userid belongs to at least one group created into entity $id
+ *
+ * @param int $entity
+ * @param int $userid
+ * @return int
+ */
+ public function verifyRight($entity, $userid)
+ {
+ global $conf;
+
+ $tmpuser=new User($this->db);
+ $tmpuser->fetch($userid);
+ //$tmpuser->fetch($userid, '', '',0, $entity); // TODO check compatibility with DAV authentication
+
+ if ($tmpuser->id)
+ {
+ if (empty($tmpuser->entity)) return 1; // superadmin always allowed
+ if ($tmpuser->entity == $entity && $tmpuser->admin) return 1; // entity admin allowed
+ if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+ {
+ if ($tmpuser->entity == $entity) return 1; // user allowed if belong to entity
+ }
+ else
+ {
+ $sql = "SELECT count(rowid) as nb";
+ $sql.= " FROM ".MAIN_DB_PREFIX."usergroup_user";
+ $sql.= " WHERE fk_user=".$userid;
+ $sql.= " AND entity=".$entity;
+ //echo $sql;
+
+ dol_syslog(get_class($this)."::verifyRight sql=".$sql, LOG_DEBUG);
+ $result = $this->db->query($sql);
+ if ($result)
+ {
+ $obj = $this->db->fetch_object($result);
+ return $obj->nb; // user allowed if at least in one group
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Get constants values of an entity
+ *
+ * @param int $entity Entity id
+ * @param string $constname Specific contant
+ * @return array Array of constants
+ */
+ public function getEntityConfig($entity, $constname=null)
+ {
+ $const=array();
+
+ $sql = "SELECT ".$this->db->decrypt('value')." as value";
+ $sql.= ", ".$this->db->decrypt('name')." as name";
+ $sql.= " FROM ".MAIN_DB_PREFIX."const";
+ $sql.= " WHERE entity = " . $entity;
+ if (! empty($constname)) {
+ if (preg_match('/\_\*$/', $constname))
+ {
+ $constname = str_replace('*', '', $constname);
+ $sql.= " AND ".$this->db->decrypt('name')." LIKE '" . $this->db->escape($constname) ."%'";
+ }
+ else
+ {
+ $sql.= " AND ".$this->db->decrypt('name')." = '" . $this->db->escape($constname) ."'";
+ }
+ }
+
+ dol_syslog(get_class($this)."::getEntityConfig sql=".$sql, LOG_DEBUG);
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ $i = 0;
+ $num = $this->db->num_rows($resql);
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ $const[$obj->name] = $obj->value;
+
+ $i++;
+ }
+
+ }
+ return $const;
+ }
+
+ /**
+ * Get group rights by entity
+ *
+ * @param int $group
+ * @param int $entity
+ * @return array[]
+ */
+ public function getGroupRightsByEntity($group, $entity)
+ {
+ $permsgroupbyentity = array();
+
+ $sql = "SELECT DISTINCT r.id, r.libelle, r.module, gr.entity";
+ $sql.= " FROM ".MAIN_DB_PREFIX."rights_def as r,";
+ $sql.= " ".MAIN_DB_PREFIX."usergroup_rights as gr";
+ $sql.= " WHERE gr.fk_id = r.id";
+ $sql.= " AND gr.entity = " . (int) $entity;
+ $sql.= " AND gr.fk_usergroup = " . (int) $group;
+
+ dol_syslog(get_class($this)."::getGroupRightsByEntity sql=".$sql, LOG_DEBUG);
+ $result=$this->db->query($sql);
+ if ($result)
+ {
+ $num = $this->db->num_rows($result);
+ $i = 0;
+
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($result);
+ array_push($permsgroupbyentity, $obj->id);
+ $i++;
+ }
+
+ $this->db->free($result);
+
+ return $permsgroupbyentity;
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+ }
+
+ /**
+ * Get list of groups
+ *
+ * @return array
+ */
+ public function getListOfGroups()
+ {
+ $ret=array();
+
+ $sql = "SELECT g.rowid";
+ $sql.= " FROM ".MAIN_DB_PREFIX."usergroup as g";
+ $sql.= " GROUP BY g.rowid";
+
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ while ($obj = $this->db->fetch_object($resql))
+ {
+ $ret[] = $obj->rowid;
+ }
+
+ $this->db->free($result);
+
+ return $ret;
+ }
+ else
+ {
+ $this->error=$this->db->lasterror();
+ return -1;
+ }
+ }
+
+ /**
+ *
+ * @param unknown $groupid
+ * @param unknown $template
+ * @return User[]|number
+ */
+ public function getListOfUsersInGroupByTemplate($groupid, $template)
+ {
+ $ret=array();
+
+ $sql = "SELECT u.rowid, ug.entity as usergroup_entity";
+ $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
+ $sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
+ $sql.= " WHERE ug.fk_user = u.rowid";
+ $sql.= " AND ug.fk_usergroup = " . (int) $groupid;
+ $sql.= " AND ug.entity = " . (int) $template;
+
+ dol_syslog(get_class($this)."::getListOfUsersInGroupByEntity groupid=".$groupid." template=".$template, LOG_DEBUG);
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ while ($obj = $this->db->fetch_object($resql))
+ {
+ if (! array_key_exists($obj->rowid, $ret))
+ {
+ $newuser=new User($this->db);
+ $newuser->fetch($obj->rowid);
+ $ret[$obj->rowid]=$newuser;
+ }
+ }
+
+ $this->db->free($resql);
+
+ return $ret;
+ }
+ else
+ {
+ $this->error=$this->db->lasterror();
+ return -1;
+ }
+ }
+
+}
diff --git a/htdocs/custom/multicompany/class/index.html b/htdocs/custom/multicompany/class/index.html
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/htdocs/custom/multicompany/class/ssp.class.php b/htdocs/custom/multicompany/class/ssp.class.php
new file mode 100755
index 00000000000..d048ea745ca
--- /dev/null
+++ b/htdocs/custom/multicompany/class/ssp.class.php
@@ -0,0 +1,412 @@
+
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \file /multicompany/class/ssp.class.php
+ * \ingroup multicompany
+ * \brief File of class to manage DataTables server-side processing
+ */
+
+/**
+ * \class SSP
+ * \brief DataTables server-side processing class
+ */
+class SSP
+{
+ /**
+ * Create the data output array for the DataTables rows
+ *
+ * @param array $columns Column information array
+ * @param array $data Data from the SQL get
+ * @return array Formatted data in a row based format
+ */
+ static function data_output ( $columns, $data )
+ {
+ $out = array();
+
+ for ( $i=0, $ien=count($data) ; $i<$ien ; $i++ ) {
+ $row = array();
+
+ for ( $j=0, $jen=count($columns) ; $j<$jen ; $j++ ) {
+ $column = $columns[$j];
+
+ // Is there a formatter?
+ if ( isset( $column['formatter'] ) ) {
+ $row[ $column['dt'] ] = $column['formatter']( $data[$i][ $column['db'] ], $data[$i] );
+ }
+ else {
+ $row[ $column['dt'] ] = $data[$i][ $columns[$j]['db'] ];
+ }
+ }
+
+ $out[] = $row;
+ }
+
+ return $out;
+ }
+
+
+ /**
+ * Paging
+ *
+ * Construct the LIMIT clause for server-side processing SQL query
+ *
+ * @param array $request Data sent to server by DataTables
+ * @param array $columns Column information array
+ * @return string SQL limit clause
+ */
+ static function limit ( $request, $columns, $db )
+ {
+ $limit = '';
+
+ if ( isset($request['start']) && $request['length'] != -1 ) {
+ $limit = $db->plimit(intval($request['length']), intval($request['start']));
+ }
+
+ return $limit;
+ }
+
+
+ /**
+ * Ordering
+ *
+ * Construct the ORDER BY clause for server-side processing SQL query
+ *
+ * @param array $request Data sent to server by DataTables
+ * @param array $columns Column information array
+ * @return string SQL order by clause
+ */
+ static function order ( $request, $columns, $db )
+ {
+ $order = '';
+ $sortfield = array();
+ $sortorder = array();
+
+ if ( isset($request['order']) && count($request['order']) ) {
+ $dtColumns = self::pluck( $columns, 'dt' );
+ for ( $i=0, $ien=count($request['order']) ; $i<$ien ; $i++ ) {
+ // Convert the column index into the column data property
+ $columnIdx = intval($request['order'][$i]['column']);
+ $requestColumn = $request['columns'][$columnIdx];
+
+ $columnIdx = array_search( $requestColumn['data'], $dtColumns );
+ $column = $columns[ $columnIdx ];
+
+ if ( $requestColumn['orderable'] == 'true' ) {
+ $dir = $request['order'][$i]['dir'] === 'asc' ? 'ASC' : 'DESC';
+ $sortfield[] = $column['db'];
+ $sortorder[] = $dir;
+ }
+ }
+
+ $order = $db->order(implode(', ', $sortfield), implode(', ', $sortorder));
+ }
+
+ return $order;
+ }
+
+
+ /**
+ * Searching / Filtering
+ *
+ * Construct the WHERE clause for server-side processing SQL query.
+ *
+ * NOTE this does not match the built-in DataTables filtering which does it
+ * word by word on any field. It's possible to do here performance on large
+ * databases would be very poor
+ *
+ * @param array $request Data sent to server by DataTables
+ * @param array $columns Column information array
+ * @param array $bindings Array of values for PDO bindings, used in the
+ * sql_exec() function
+ * @return string SQL where clause
+ */
+ static function filter ( $request, $columns, $db )
+ {
+ $globalSearch = array();
+ $columnSearch = array();
+ $dtColumns = self::pluck( $columns, 'dt' );
+
+ if ( isset($request['search']) && $request['search']['value'] != '' ) {
+ $str = $request['search']['value'];
+
+ for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) {
+ $requestColumn = $request['columns'][$i];
+ $columnIdx = array_search( $requestColumn['data'], $dtColumns );
+ $column = $columns[ $columnIdx ];
+
+ if ( $requestColumn['searchable'] == 'true' ) {
+ $globalSearch[] = $column['db']." LIKE '%" . $db->escape($str)."%'";
+ }
+ }
+ }
+
+ // Individual column filtering
+ if ( isset( $request['columns'] ) ) {
+ for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) {
+ $requestColumn = $request['columns'][$i];
+ $columnIdx = array_search( $requestColumn['data'], $dtColumns );
+ $column = $columns[ $columnIdx ];
+
+ $str = $requestColumn['search']['value'];
+
+ if ( $requestColumn['searchable'] == 'true' &&
+ $str != '' ) {
+ $columnSearch[] = $column['db']." LIKE '%" . $db->escape($str)."%'";
+ }
+ }
+ }
+
+ // Combine the filters into a single string
+ $where = '';
+
+ if ( count( $globalSearch ) ) {
+ $where = '('.implode(' OR ', $globalSearch).')';
+ }
+
+ if ( count( $columnSearch ) ) {
+ $where = $where === '' ?
+ implode(' AND ', $columnSearch) :
+ $where .' AND '. implode(' AND ', $columnSearch);
+ }
+
+ if ( $where !== '' ) {
+ $where = 'WHERE '.$where;
+ }
+
+ return $where;
+ }
+
+
+ /**
+ * Perform the SQL queries needed for an server-side processing requested,
+ * utilising the helper functions of this class, limit(), order() and
+ * filter() among others. The returned array is ready to be encoded as JSON
+ * in response to an SSP request, or can be modified if needed before
+ * sending back to the client.
+ *
+ * @param array $request Data sent to server by DataTables
+ * @param string $table SQL table to query
+ * @param string $primaryKey Primary key of the table
+ * @param array $columns Column information array
+ * @return array Server-side processing response array
+ */
+ static function simple ( $request, $db, $table, $primaryKey, $columns )
+ {
+ // Build the SQL query string from the request
+ $limit = self::limit( $request, $columns, $db );
+ $order = self::order( $request, $columns, $db );
+ $where = self::filter( $request, $columns, $db );
+
+ // Main query to actually get the data
+ $sql =
+ "SELECT ".implode(", ", self::pluck($columns, 'db'))."
+ FROM $table
+ $where
+ $order
+ $limit";
+
+ $data = self::sql_exec($db, $sql);
+ //print_r($data);
+
+ // Data set length after filtering
+ $resFilterLength = self::sql_exec($db,
+ "SELECT COUNT({$primaryKey})
+ FROM $table
+ $where"
+ );
+ $recordsFiltered = $resFilterLength[0][0];
+
+ // Total data set length
+ $resTotalLength = self::sql_exec($db,
+ "SELECT COUNT({$primaryKey})
+ FROM $table"
+ );
+ $recordsTotal = $resTotalLength[0][0];
+
+ /*
+ * Output
+ */
+ return array(
+ "draw" => isset ( $request['draw'] ) ?
+ intval( $request['draw'] ) :
+ 0,
+ "recordsTotal" => intval( $recordsTotal ),
+ "recordsFiltered" => intval( $recordsFiltered ),
+ "data" => self::data_output( $columns, $data )
+ );
+ }
+
+
+ /**
+ * The difference between this method and the `simple` one, is that you can
+ * apply additional `where` conditions to the SQL queries. These can be in
+ * one of two forms:
+ *
+ * * 'Result condition' - This is applied to the result set, but not the
+ * overall paging information query - i.e. it will not effect the number
+ * of records that a user sees they can have access to. This should be
+ * used when you want apply a filtering condition that the user has sent.
+ * * 'All condition' - This is applied to all queries that are made and
+ * reduces the number of records that the user can access. This should be
+ * used in conditions where you don't want the user to ever have access to
+ * particular records (for example, restricting by a login id).
+ *
+ * @param array $request Data sent to server by DataTables
+ * @param string $table SQL table to query
+ * @param string $primaryKey Primary key of the table
+ * @param array $columns Column information array
+ * @param string $whereResult WHERE condition to apply to the result set
+ * @param string $whereAll WHERE condition to apply to all queries
+ * @return array Server-side processing response array
+ */
+ static function complex ( $request, $db, $table, $primaryKey, $columns, $whereResult=null, $whereAll=null )
+ {
+ $whereAllSql = '';
+
+ // Build the SQL query string from the request
+ $limit = self::limit( $request, $columns, $db );
+ $order = self::order( $request, $columns, $db );
+ $where = self::filter( $request, $columns, $db );
+
+ $whereResult = self::_flatten( $whereResult );
+ $whereAll = self::_flatten( $whereAll );
+
+ if ( $whereResult ) {
+ $where = $where ?
+ $where .' AND '.$whereResult :
+ 'WHERE '.$whereResult;
+ }
+
+ if ( $whereAll ) {
+ $where = $where ?
+ $where .' AND '.$whereAll :
+ 'WHERE '.$whereAll;
+
+ $whereAllSql = 'WHERE '.$whereAll;
+ }
+
+ // Main query to actually get the data
+ $data = self::sql_exec($db,
+ "SELECT ".implode(", ", self::pluck($columns, 'db'))."
+ FROM $table
+ $where
+ $order
+ $limit"
+ );
+
+ // Data set length after filtering
+ $resFilterLength = self::sql_exec($db,
+ "SELECT COUNT({$primaryKey})
+ FROM $table
+ $where"
+ );
+ $recordsFiltered = $resFilterLength[0][0];
+
+ // Total data set length
+ $resTotalLength = self::sql_exec($db,
+ "SELECT COUNT({$primaryKey})
+ FROM $table ".
+ $whereAllSql
+ );
+ $recordsTotal = $resTotalLength[0][0];
+
+ /*
+ * Output
+ */
+ return array(
+ "draw" => isset ( $request['draw'] ) ?
+ intval( $request['draw'] ) :
+ 0,
+ "recordsTotal" => intval( $recordsTotal ),
+ "recordsFiltered" => intval( $recordsFiltered ),
+ "data" => self::data_output( $columns, $data )
+ );
+ }
+
+
+ /**
+ * Execute an SQL query on the database
+ *
+ * @param string $sql SQL query to execute.
+ * @return array Result from the query (all rows)
+ */
+ static function sql_exec ( $db, $sql )
+ {
+ $out=array();
+
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $i = 0;
+ $num_rows=$db->num_rows($resql);
+ while ($i < $num_rows)
+ {
+ $array = $db->fetch_array($resql);
+ array_push($out, $array);
+ $i++;
+ }
+ }
+
+ return $out;
+ }
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Internal methods
+ */
+
+ /**
+ * Pull a particular property from each assoc. array in a numeric array,
+ * returning and array of the property values from each item.
+ *
+ * @param array $a Array to get data from
+ * @param string $prop Property to read
+ * @return array Array of property values
+ */
+ static function pluck ( $a, $prop )
+ {
+ $out = array();
+
+ for ( $i=0, $len=count($a) ; $i<$len ; $i++ ) {
+ $out[] = $a[$i][$prop];
+ }
+
+ return $out;
+ }
+
+
+ /**
+ * Return a string from an array or a string
+ *
+ * @param array|string $a Array to join
+ * @param string $join Glue for the concatenation
+ * @return string Joined string
+ */
+ static function _flatten ( $a, $join = ' AND ' )
+ {
+ if ( ! $a ) {
+ return '';
+ }
+ else if ( $a && is_array($a) ) {
+ return implode( $join, $a );
+ }
+ return $a;
+ }
+}
+
diff --git a/htdocs/custom/multicompany/core/ajax/functions.php b/htdocs/custom/multicompany/core/ajax/functions.php
new file mode 100755
index 00000000000..335d84fc154
--- /dev/null
+++ b/htdocs/custom/multicompany/core/ajax/functions.php
@@ -0,0 +1,286 @@
+
+ * Copyright (C) 2011 Herve Prot
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \file multicompany/core/ajax/functions.php
+ * \brief File to return ajax result
+ */
+
+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');
+if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK',1);
+
+if (isset($_GET['action']) && $_GET['action'] === 'getEntityLogo') {
+ define("NOLOGIN",1); // This means this output page does not require to be logged.
+ $entity=(! empty($_GET['id']) ? (int) $_GET['id'] : 1);
+ if (is_numeric($entity)) define("DOLENTITY", $entity);
+}
+
+$res=@include("../../../main.inc.php"); // For root directory
+if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php"))
+ $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only
+if (! $res) $res=@include("../../../../main.inc.php"); // For "custom" directory
+
+dol_include_once('/multicompany/class/actions_multicompany.class.php', 'ActionsMulticompany');
+require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
+
+$id = GETPOST('id', 'int'); // id of entity
+$action = GETPOST('action', 'alpha'); // action method
+$type = GETPOST('type', 'alpha'); // type of action
+$element = GETPOST('element', 'alpha'); // type of element
+$fk_element = GETPOST('fk_element', 'int'); // id of element
+
+$template = GETPOST('template', 'int');
+if (GETPOSTISSET('entities')) {
+ $entities = json_decode(GETPOST('entities', 'none'), true);
+}
+
+/*
+ * View
+ */
+
+// Ajout directives pour resoudre bug IE
+//header('Cache-Control: Public, must-revalidate');
+//header('Pragma: public');
+
+//top_htmlhead("", "", 1); // Replaced with top_httphead. An ajax page does not need html header.
+top_httphead('application/json');
+
+if (empty($conf->multicompany->enabled)) {
+ echo json_encode(array('status' => 'error'));
+ $db->close();
+ exit();
+}
+
+//print ''."\n";
+
+// Registering the location of boxes
+if (! empty($action) && is_numeric($id))
+{
+ if ($action == 'switchEntity' && ! empty($user->login))
+ {
+ dol_syslog("multicompany action=".$action." entity=".$id, LOG_DEBUG);
+
+ $object = new ActionsMulticompany($db);
+ echo $object->switchEntity($id);
+ }
+ else if ($action == 'setStatusEnable' && ! empty($user->admin) && ! $user->entity)
+ {
+ dol_syslog("multicompany action=".$action." type=".$type." entity=".$id, LOG_DEBUG);
+
+ $object = new ActionsMulticompany($db);
+ $fieldname = ($type == 'activetemplate' ? 'active' : $type);
+ echo $object->setStatus($id, $fieldname, 1);
+ }
+ else if ($action == 'setStatusDisable' && ! empty($user->admin) && ! $user->entity)
+ {
+ dol_syslog("multicompany action=".$action." type=".$type." entity=".$id, LOG_DEBUG);
+
+ $object = new ActionsMulticompany($db);
+ $fieldname = ($type == 'activetemplate' ? 'active' : $type);
+ $ret = $object->setStatus($id, $fieldname, 0);
+ if ($ret == 1 && $type == 'active') {
+ $ret = $object->setStatus($id, 'visible', 0);
+ }
+ echo $ret;
+ }
+ else if ($action == 'deleteEntity' && $id != 1 && ! empty($user->admin) && ! $user->entity)
+ {
+ dol_syslog("multicompany action=".$action." entity=".$id, LOG_DEBUG);
+
+ $object = new ActionsMulticompany($db);
+ echo $object->deleteEntity($id);
+ }
+ else if ($action == 'setColOrder' && ! empty($user->admin) && ! $user->entity)
+ {
+ $id = (int) $id;
+ $direction = GETPOST('dir', 'aZ');
+ $colOrder = array('id' => $id, 'direction' => $direction);
+
+ if (dolibarr_set_const($db, 'MULTICOMPANY_COLORDER', json_encode($colOrder), 'chaine', 0, '', 0) > 0) {
+ $ret = json_encode(array('status' => 'success'));
+ }
+ else {
+ $ret = json_encode(array('status' => 'error'));
+ }
+
+ echo $ret;
+ }
+ else if ($action == 'setColHidden' && ! empty($user->admin) && ! $user->entity)
+ {
+ $state = GETPOST('state', 'aZ');
+ $colHidden = (! empty($conf->global->MULTICOMPANY_COLHIDDEN) ? json_decode($conf->global->MULTICOMPANY_COLHIDDEN, true) : array());
+
+ if ($state == 'visible') {
+ $colHidden = array_diff($colHidden, array(intval($id)));
+ } else if ($state == 'hidden') {
+ array_push($colHidden, intval($id));
+ }
+
+ sort($colHidden);
+
+ if (dolibarr_set_const($db, 'MULTICOMPANY_COLHIDDEN', json_encode($colHidden), 'chaine', 0, '', 0) > 0) {
+ $ret = json_encode(array('status' => 'success'));
+ }
+ else {
+ $ret = json_encode(array('status' => 'error'));
+ }
+
+ echo $ret;
+ }
+ else if ($action == 'modifyEntity' && ((! empty($user->admin) && ! $user->entity) || ! empty($user->rights->multicompany->thirdparty->write)))
+ {
+ if ($element == 'societe')
+ {
+ $object = new Societe($db);
+ $ret = $object->fetch($fk_element);
+ if ($ret > 0) {
+
+ $object->oldcopy = clone $object;
+
+ // To not set code if third party is not concerned. But if it had values, we keep them.
+ if (empty($object->client) && empty($object->oldcopy->code_client)) $object->code_client='';
+ if (empty($object->fournisseur) && empty($object->oldcopy->code_fournisseur)) $object->code_fournisseur='';
+
+ $object->entity = $id;
+
+ $ret = $object->update($object->id, $user, 0, $object->oldcopy->codeclient_modifiable(), $object->oldcopy->codefournisseur_modifiable(), 'update', 1);
+ if ($ret > 0) {
+ $ret = json_encode(array('status' => 'success'));
+ }
+ else {
+ $ret = json_encode(array('status' => 'error', 'error' => $object->errors));
+ }
+ }
+ else {
+ $ret = json_encode(array('status' => 'error', 'error' => $object->errors));
+ }
+ }
+ else if ($element == 'contact')
+ {
+ require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
+
+ $object = new Contact($db);
+ $ret = $object->fetch($fk_element);
+ if ($ret > 0) {
+
+ $object->entity = $id;
+
+ $ret = $object->update($object->id, $user, 1, 'update', 1);
+ if ($ret > 0) {
+ $ret = json_encode(array('status' => 'success'));
+ }
+ else {
+ $ret = json_encode(array('status' => 'error', 'error' => $object->errors));
+ }
+ }
+ else {
+ $ret = json_encode(array('status' => 'error', 'error' => $object->errors));
+ }
+ }
+
+ echo $ret;
+ }
+ else if ($action === 'getEntityOptions' && ! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) && ! empty($user->admin) && empty($user->entity))
+ {
+ $object = new ActionsMulticompany($db);
+ $object->getInfo($id);
+
+ $entities = $object->getEntitiesList(false, false, true, true);
+
+ echo json_encode(
+ array(
+ 'status' => 'success',
+ 'options' => $object->options,
+ 'labels' => $entities
+ )
+ );
+ }
+ else if ($action === 'duplicateUserGroupRights' && ! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) && ! empty($user->admin) && empty($user->entity) && ! empty($template) && ! empty($entities))
+ {
+ $multicompany = new ActionsMulticompany($db);
+ $ret = $multicompany->duplicateUserGroupRights($id, $template, $entities);
+ if ($ret > 0)
+ {
+ echo json_encode(array('status' => 'success'));
+ }
+ else
+ {
+ echo json_encode(array(
+ 'status' => 'error',
+ 'id' => $id,
+ 'template' => $template,
+ 'entities' => $entities
+ )
+ );
+ }
+ }
+ else if ($action === 'getEntityLogo' && empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX))
+ {
+ $urllogo = DOL_URL_ROOT.'/theme/login_logo.png';
+
+ if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small))
+ {
+ $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&entity='.$id.'&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
+ }
+ elseif (! empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo))
+ {
+ $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&entity='.$id.'&modulepart=mycompany&file='.urlencode('logos/'.$mysoc->logo);
+ $width = 128;
+ }
+ elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png'))
+ {
+ $urllogo = DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png';
+ }
+ elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.png'))
+ {
+ $urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.png';
+ }
+
+ $bgimg = null;
+ $unsplashimg = null;
+
+ if (! empty($conf->global->MULTICOMPANY_LOGIN_BACKGROUND_BY_ENTITY))
+ {
+ if (! empty($conf->global->ADD_UNSPLASH_LOGIN_BACKGROUND))
+ {
+ $unsplashimg = $conf->global->ADD_UNSPLASH_LOGIN_BACKGROUND;
+ }
+
+ if (! empty($conf->global->MAIN_LOGIN_BACKGROUND))
+ {
+ $bgimg = DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&entity='.$id.'&modulepart=mycompany&file=logos/'.urlencode($conf->global->MAIN_LOGIN_BACKGROUND);
+ }
+ }
+
+ echo json_encode(array(
+ 'status' => 'success',
+ 'urllogo' => dol_html_entity_decode($urllogo, null),
+ 'bgimg' => dol_html_entity_decode($bgimg, null),
+ 'unsplashimg' => dol_html_entity_decode($unsplashimg, null)
+ )
+ );
+ }
+}
+
+$db->close();
diff --git a/htdocs/custom/multicompany/core/ajax/index.html b/htdocs/custom/multicompany/core/ajax/index.html
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/htdocs/custom/multicompany/core/ajax/list.php b/htdocs/custom/multicompany/core/ajax/list.php
new file mode 100755
index 00000000000..30b48cce8bc
--- /dev/null
+++ b/htdocs/custom/multicompany/core/ajax/list.php
@@ -0,0 +1,248 @@
+
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \file /multicompany/core/ajax/list.php
+ * \brief File to return datables output of entities list
+ */
+
+if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Disables token renewal
+if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1');
+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');
+if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK',1);
+
+$res=@include("../../../main.inc.php"); // For root directory
+if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php"))
+ $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only
+if (! $res) $res=@include("../../../../main.inc.php"); // For "custom" directory
+
+require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
+dol_include_once('/multicompany/class/dao_multicompany.class.php', 'DaoMulticompany');
+dol_include_once('/multicompany/lib/multicompany.lib.php');
+dol_include_once('/multicompany/class/ssp.class.php');
+
+$langs->loadLangs(array('languages','admin','multicompany@multicompany'));
+
+// Defini si peux lire/modifier permisssions
+$canreadEntity=! empty($user->admin);
+$caneditEntity=! empty($user->admin);
+$candeleteEntity=! empty($user->admin);
+
+top_httphead('application/json');
+
+//print ''."\n";
+
+//print_r($_GET);
+
+if (empty($user->admin) || empty($conf->multicompany->enabled)) {
+ echo json_encode(array('status' => 'error'));
+ $db->close();
+ exit();
+}
+
+$object = new DaoMulticompany($db);
+
+$extrafields = new ExtraFields($db);
+// fetch optionals attributes and labels
+$extralabels = $extrafields->fetch_name_optionals_label($object->element);
+
+$start = array('start' => GETPOST('start', 'int'));
+$length = array('length' => GETPOST('length', 'int'));
+$draw = array('draw' => GETPOST('draw', 'int'));
+$order = array('order' => GETPOST('order', 'array'));
+$columns = array('columns' => GETPOST('columns', 'array'));
+$search = array('search' => GETPOST('search', 'array'));
+
+$request = $start + $length + $draw + $order + $columns + $search;
+//print_r($request);
+
+// DB table to use
+$table = MAIN_DB_PREFIX . "entity";
+
+// Table's primary key
+$primaryKey = 'rowid';
+
+// Array of database columns which should be read and sent back to DataTables.
+// The `db` parameter represents the column name in the database, while the `dt`
+// parameter represents the DataTables column identifier. In this case simple
+// indexes
+$columns = array();
+
+$columns[]= array( 'db' => 'rowid', 'dt' => 'entity_id' );
+$columns[]= array( 'db' => 'label', 'dt' => 'entity_label' );
+$columns[]= array( 'db' => 'description', 'dt' => 'entity_description' );
+$columns[]= array(
+ 'db' => 'rowid',
+ 'dt' => 'entity_name',
+ 'formatter' => function($value, $row) {
+ if (! empty($value)) {
+ global $object;
+ $object->fetch($value);
+ return $object->name;
+ }
+ }
+);
+$columns[]= array(
+ 'db' => 'rowid',
+ 'dt' => 'entity_zip',
+ 'formatter' => function($value, $row) {
+ if (! empty($value)) {
+ global $object;
+ $object->fetch($value);
+ return $object->zip;
+ }
+ }
+);
+$columns[]= array(
+ 'db' => 'rowid',
+ 'dt' => 'entity_town',
+ 'formatter' => function($value, $row) {
+ if (! empty($value)) {
+ global $object;
+ $object->fetch($value);
+ return $object->town;
+ }
+ }
+);
+$columns[]= array(
+ 'db' => 'rowid',
+ 'dt' => 'entity_country',
+ 'formatter' => function($value, $row) {
+ if (! empty($value)) {
+ global $object;
+ $object->fetch($value);
+ if ($cache = getCache('country_' . $object->country_id)) {
+ $country = $cache;
+ } else {
+ $country = getCountry($object->country_id);
+ setCache('country_' . $object->country_id, $country);
+ }
+ $img=picto_from_langcode($object->country_code, 'class="multicompany-flag-country"');
+ return ($img?$img.' ':'') . $country;
+ }
+ }
+);
+$columns[]= array(
+ 'db' => 'rowid',
+ 'dt' => 'entity_currency',
+ 'formatter' => function($value, $row) {
+ if (! empty($value)) {
+ global $langs, $object;
+ $object->fetch($value);
+ return currency_name($object->currency_code) . ' (' . $langs->getCurrencySymbol($object->currency_code) . ')';
+ }
+ }
+);
+$columns[]= array(
+ 'db' => 'rowid',
+ 'dt' => 'entity_language',
+ 'formatter' => function($value, $row) {
+ if (! empty($value)) {
+ global $langs, $object;
+ $object->fetch($value);
+ $img=picto_from_langcode($object->language_code, 'class="multicompany-flag-language"');
+ return ($img?$img.' ':'') . ($object->language_code=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$object->language_code));
+ }
+ }
+);
+if (! empty($extralabels)) {
+ foreach ($extralabels as $key => $name)
+ {
+ $columns[]= array(
+ 'db' => 'rowid',
+ 'dt' => 'entity_'.$key,
+ 'formatter' => function($value, $row) use ($key) {
+ global $object, $extrafields;
+ unset($object->array_options['options_'.$key]); // For avoid duplicate data in next row
+ $object->fetch_optionals();
+ return $extrafields->showOutputField($key, $object->array_options['options_'.$key]);
+ }
+ );
+ }
+}
+$columns[]= array(
+ 'db' => 'visible',
+ 'dt' => 'entity_visible',
+ 'formatter' => function($value, $row) {
+ global $langs;
+ if (! empty($value)) {
+ if ($value == 1) {
+ return img_picto($langs->trans("Enabled"),'on','id="visible_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-visible-on');
+ } else {
+ return ' ';
+ }
+ } else if (! empty($row['active'])) {
+ return img_picto($langs->trans("Disabled"),'off','id="visible_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-visible-off');
+ } else {
+ return img_picto($langs->trans("Disabled"),'off','id="visible_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-disabled');
+ }
+ }
+);
+$columns[]= array(
+ 'db' => 'active',
+ 'dt' => 'entity_active',
+ 'formatter' => function($value, $row) {
+ global $conf, $langs;
+ if ($row['rowid'] == 1 || $conf->entity == $row['rowid']) {
+ return img_picto($langs->trans("Enabled"),'on','id="active_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-disabled');
+ } else if (! empty($value)) {
+ if ($row['visible'] == 2) {
+ return img_picto($langs->trans("Enabled"),'on','id="activetemplate_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-active-on');
+ } else {
+ return img_picto($langs->trans("Enabled"),'on','id="active_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-active-on');
+ }
+ } else {
+ if ($row['visible'] == 2) {
+ return img_picto($langs->trans("Disabled"),'off','id="activetemplate_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-active-off');
+ } else {
+ return img_picto($langs->trans("Disabled"),'off','id="active_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-active-off');
+ }
+ }
+ }
+);
+$columns[]= array(
+ 'db' => 'rowid',
+ 'dt' => 'entity_tools',
+ 'formatter' => function($value, $row) {
+ global $conf, $langs, $caneditEntity, $candeleteEntity;
+ $ret='';
+ if ($caneditEntity) {
+ $ret.= img_edit($langs->transnoentities("Edit"),0, 'id="edit_' . $value . '" class="multicompany-button-setup"');
+ }
+ if ($candeleteEntity) {
+ if ($value == 1 || $conf->entity == $value) {
+ $ret.= img_delete($langs->transnoentities("Delete"), 'id="delete_' . $value . '" class="multicompany-button-disabled"');
+ } else {
+ $ret.= img_delete($langs->transnoentities("Delete"), 'id="delete_' . $value . '" class="multicompany-button-delete"');
+ }
+ }
+ return $ret;
+ }
+);
+
+//var_dump($columns);
+echo json_encode(
+ SSP::simple( $request, $db, $table, $primaryKey, $columns )
+);
+
+$db->close();
diff --git a/htdocs/custom/multicompany/core/js/index.html b/htdocs/custom/multicompany/core/js/index.html
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/htdocs/custom/multicompany/core/js/lib_head.js b/htdocs/custom/multicompany/core/js/lib_head.js
new file mode 100755
index 00000000000..668687e127e
--- /dev/null
+++ b/htdocs/custom/multicompany/core/js/lib_head.js
@@ -0,0 +1,214 @@
+// Copyright (C) 2014-2019 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 .
+// or see http://www.gnu.org/
+
+//
+// \file /multicompany/core/js/lib_head.js
+// \brief File that include javascript functions (included if option use_javascript activated)
+//
+
+/*
+ *
+ */
+function setMulticompanyConstant(url, code, input, entity) {
+ $.get( url, {
+ action: "set",
+ name: code,
+ entity: entity
+ },
+ function() {
+ $("#set_" + code).hide();
+ $("#del_" + code).show();
+ $.each(input, function(type, data) {
+ // Enable another element
+ if (type == "enabled") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).removeAttr("disabled");
+ });
+ // Disable another element
+ } else if (type == "disabled") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).attr("disabled", true);
+ });
+ // enable and disable another element
+ } else if (type == "disabledenabled") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).removeAttr("disabled");
+ });
+ // Show another element
+ } else if (type == "showhide" || type == "show") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).show();
+ });
+ } else if (type == "hideshow") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).hide();
+ });
+ // Set another constant
+ } else if (type == "set" || type == "del") {
+ $.each(data, function(key, value) {
+ if (type == "set") {
+ $("#set_" + value).hide();
+ $("#del_" + value).show();
+ $.get( url, {
+ action: type,
+ name: key,
+ value: value,
+ entity: entity
+ });
+ } else if (type == "del") {
+ $("#del_" + value).hide();
+ $("#set_" + value).show();
+ $.get( url, {
+ action: type,
+ name: value,
+ entity: entity
+ });
+ }
+ });
+ // reload the current page
+ } else if (type == "reload") {
+ var url = window.location.pathname;
+ location.href=url;
+ }
+ });
+ });
+}
+
+/*
+ *
+ */
+function delMulticompanyConstant(url, code, input, entity) {
+ $.get( url, {
+ action: "del",
+ name: code,
+ entity: entity
+ },
+ function() {
+ $("#del_" + code).hide();
+ $("#set_" + code).show();
+ $.each(input, function(type, data) {
+ // Enable another element
+ if (type == "enabled") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).removeAttr("disabled");
+ });
+ // Disable another element
+ } else if (type == "disabled") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).attr("disabled", true);
+ });
+ // enable and disable another element
+ } else if (type == "disabledenabled") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).attr("disabled", true);
+ });
+ } else if (type == "showhide" || type == "hide") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).hide();
+ });
+ } else if (type == "hideshow") {
+ $.each(data, function(key, value) {
+ var newvalue=(value.search("^#") < 0 ? "#" : "") + value;
+ $(newvalue).show();
+ });
+ // Delete another constant
+ } else if (type == "set" || type == "del") {
+ $.each(data, function(key, value) {
+ if (type == "set") {
+ $("#set_" + value).hide();
+ $("#del_" + value).show();
+ $.get( url, {
+ action: type,
+ name: key,
+ value: value,
+ entity: entity
+ });
+ } else if (type == "del") {
+ $("#del_" + value).hide();
+ $("#set_" + value).show();
+ $.get( url, {
+ action: type,
+ name: value,
+ entity: entity
+ });
+ }
+ });
+ // reload the current page
+ } else if (type == "reload") {
+ var url = window.location.pathname;
+ location.href=url;
+ }
+ });
+ });
+}
+
+/*
+ *
+ */
+function confirmMulticompanyConstantAction(action, url, code, input, box, entity, yesButton, noButton) {
+ var boxConfirm = box;
+ $("#confirm_" + code)
+ .attr("title", boxConfirm.title)
+ .html(boxConfirm.content)
+ .dialog({
+ resizable: false,
+ height: 180,
+ width: 500,
+ modal: true,
+ buttons: [
+ {
+ id : 'yesButton_' + code,
+ text : yesButton,
+ click : function() {
+ if (action == "set") {
+ setMulticompanyConstant(url, code, input, entity);
+ } else if (action == "del") {
+ delMulticompanyConstant(url, code, input, entity);
+ }
+ // Close dialog
+ $(this).dialog("close");
+ // Execute another method
+ if (boxConfirm.method) {
+ var fnName = boxConfirm.method;
+ if (window.hasOwnProperty(fnName)) {
+ window[fnName]();
+ }
+ }
+ }
+ },
+ {
+ id : 'noButton_' + code,
+ text : noButton,
+ click : function() {
+ $(this).dialog("close");
+ }
+ }
+ ]
+ });
+ // For information dialog box only, hide the noButton
+ if (boxConfirm.info) {
+ $("#noButton_" + code).button().hide();
+ }
+}
diff --git a/htdocs/custom/multicompany/core/login/functions_mc.php b/htdocs/custom/multicompany/core/login/functions_mc.php
new file mode 100755
index 00000000000..69dc4d86659
--- /dev/null
+++ b/htdocs/custom/multicompany/core/login/functions_mc.php
@@ -0,0 +1,166 @@
+
+ *
+ * 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 multicompany/core/login/functions_mc.php
+ * \ingroup multicompany
+ * \brief Authentication functions for Multicompany mode when combobox in login page is disabled
+ */
+
+
+/**
+ * Check validity of user/password/entity
+ * If test is ko, reason must be filled into $_SESSION["dol_loginmesg"]
+ *
+ * @param string $usertotest Login
+ * @param string $passwordtotest Password
+ * @param int $entitytotest Number of instance (always 1 if module multicompany not enabled)
+ * @return string Login if OK, '' if KO
+ */
+function check_user_password_mc($usertotest,$passwordtotest,$entitytotest=1)
+{
+ global $db,$conf,$langs;
+ global $mc;
+
+ dol_syslog("functions_mc::check_user_password_mc usertotest=".$usertotest);
+
+ $login='';
+
+ if (!empty($conf->multicompany->enabled))
+ {
+ $langs->loadLangs(array('main','errors','multicompany@multicompany'));
+
+ if (! empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX))
+ {
+ $entity=$entitytotest;
+
+ if (!empty($usertotest))
+ {
+ // If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko
+ $table = MAIN_DB_PREFIX."user";
+ $usernamecol = 'login';
+ $entitycol = 'entity';
+
+ $sql ='SELECT rowid, entity, pass, pass_crypted';
+ $sql.=' FROM '.$table;
+ $sql.=' WHERE '.$usernamecol." = '".$db->escape($usertotest)."'";
+ $sql.=' AND statut = 1';
+
+ dol_syslog("functions_mc::check_user_password_mc sql=" . $sql);
+ $resql=$db->query($sql);
+ if ($resql)
+ {
+ $obj=$db->fetch_object($resql);
+ if ($obj)
+ {
+ $passclear=$obj->pass;
+ $passcrypted=$obj->pass_crypted;
+ $passtyped=$passwordtotest;
+
+ $passok=false;
+
+ // Check crypted password
+ $cryptType='';
+ if (! empty($conf->global->DATABASE_PWD_ENCRYPTED)) $cryptType=$conf->global->DATABASE_PWD_ENCRYPTED;
+
+ // By default, we used MD5
+ if (! in_array($cryptType,array('md5'))) $cryptType='md5';
+ // Check crypted password according to crypt algorithm
+ if ($cryptType == 'md5')
+ {
+ if (dol_verifyHash($passtyped, $passcrypted))
+ {
+ $passok=true;
+ dol_syslog("functions_mc::check_user_password_mc Authentification ok - " . $cryptType . " of pass is ok");
+ }
+ }
+
+ // For compatibility with old versions
+ if (! $passok)
+ {
+ if ((! $passcrypted || $passtyped)
+ && ($passclear && ($passtyped == $passclear)))
+ {
+ $passok=true;
+ dol_syslog("functions_mc::check_user_password_mc Authentification ok - found pass in database");
+ }
+ }
+
+ if ($passok && !empty($obj->entity))
+ {
+ global $entitytotest;
+
+ $entitytotest = $obj->entity;
+
+ if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+ {
+ $sql = "SELECT uu.entity";
+ $sql.= " FROM " . MAIN_DB_PREFIX . "usergroup_user as uu";
+ $sql.= ", " . MAIN_DB_PREFIX . "entity as e";
+ $sql.= " WHERE uu.entity = e.rowid AND e.visible < 2"; // Remove template of entity
+ $sql.= " AND fk_user = " . $obj->rowid;
+
+ dol_syslog("functions_mc::check_user_password_mc sql=" . $sql, LOG_DEBUG);
+ $result = $db->query($sql);
+ if ($result)
+ {
+ while($array = $db->fetch_array($result)) // user allowed if at least in one group
+ {
+ $entitytotest = $array['entity'];
+ break; // stop in first entity
+ }
+ }
+ }
+
+ $ret=$mc->switchEntity($entitytotest, $obj->rowid);
+
+ if ($ret < 0) $passok=false;
+ }
+
+ // Password ok ?
+ if ($passok)
+ {
+ $login=$usertotest;
+ }
+ else
+ {
+ dol_syslog("functions_mc::check_user_password_mc Authentification ko bad password pour '".$usertotest."'", LOG_ERR);
+ $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
+ }
+ }
+ else
+ {
+ dol_syslog("functions_mc::check_user_password_mc Authentification ko user not found for '".$usertotest."'", LOG_ERR);
+ $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
+ }
+ }
+ else
+ {
+ dol_syslog("functions_mc::check_user_password_mc Authentification ko db error for '".$usertotest."' error=".$db->lasterror(), LOG_ERR);
+ $_SESSION["dol_loginmesg"]=$db->lasterror();
+ }
+ }
+ }
+ else
+ {
+ dol_syslog("functions_mc::check_user_password_mc Authentification ko, the drop-down list of entities on the login page must be hidden", LOG_ERR);
+ $_SESSION["dol_loginmesg"]=$langs->trans("ErrorDropDownListOfEntitiesMustBeHidden");
+ }
+ }
+
+ return $login;
+}
diff --git a/htdocs/custom/multicompany/core/login/index.html b/htdocs/custom/multicompany/core/login/index.html
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/htdocs/custom/multicompany/core/modules/index.html b/htdocs/custom/multicompany/core/modules/index.html
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/htdocs/custom/multicompany/core/modules/modMultiCompany.class.php b/htdocs/custom/multicompany/core/modules/modMultiCompany.class.php
new file mode 100755
index 00000000000..6f2bd0f908c
--- /dev/null
+++ b/htdocs/custom/multicompany/core/modules/modMultiCompany.class.php
@@ -0,0 +1,587 @@
+
+ * Copyright (C) 2011 Herve Prot
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \defgroup multicompany Module multicompany
+ * \brief Descriptor file for module multicompany
+ * \file htdocs/core/modules/modMultiCompany.class.php
+ * \ingroup multicompany
+ * \brief Description and activation file for module MultiCompany
+ */
+include_once DOL_DOCUMENT_ROOT . '/core/modules/DolibarrModules.class.php';
+
+
+/**
+ * \class modMultiCompany
+ * \brief Description and activation class for module MultiCompany
+ */
+class modMultiCompany extends DolibarrModules
+{
+ /**
+ * Constructor.
+ *
+ * @param DoliDB $db Database handler
+ */
+ function __construct($db)
+ {
+ global $langs;
+
+ $this->db = $db;
+
+ // Id for module (must be unique).
+ // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
+ $this->numero = 5000;
+ // Key text used to identify module (for permissions, menus, etc...)
+ $this->rights_class = 'multicompany';
+
+ // Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
+ // It is used to group modules in module setup page
+ $this->family = "base";
+ // Gives the possibility to the module, to provide his own family info and position of this family.
+ $this->familyinfo = array(
+ 'core' => array(
+ 'position' => '001',
+ 'label' => $langs->trans("iNodbox")
+ )
+ );
+ // Module position in the family
+ $this->module_position = 1;
+ // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
+ $this->name = preg_replace('/^mod/i','',get_class($this));
+ // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
+ $this->description = "Multi-Company Management";
+ //$this->descriptionlong = "A very lon description. Can be a full HTML content";
+ $this->editor_name = 'Régis Houssin';
+ $this->editor_url = 'https://www.inodbox.com';
+ // Can be enabled / disabled only in the main company with superadmin account
+ $this->core_enabled = 1;
+ // Possible values for version are: 'development', 'experimental', 'dolibarr' or version
+ $this->version = '12.0.1';
+ // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
+ $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
+ // Name of png file (without png) used for this module.
+ // Png file must be in theme/yourtheme/img directory under name object_pictovalue.png.
+ $this->picto='multicompany@multicompany';
+
+ // Data directories to create when module is enabled.
+ $this->dirs = array();
+
+ // Config pages. Put here list of php page names stored in admmin directory used to setup module.
+ $this->config_page_url = array("multicompany.php@multicompany");
+
+ // Defined all module parts (triggers, login, substitutions, menus, css, etc...)
+ $this->module_parts = array(
+ 'login' => array(
+ 'data' => 1,
+ 'entity' => '0'
+ ),
+ 'triggers' => array(
+ 'data' => 1,
+ 'entity' => '0'
+ ),
+ 'hooks' => array(
+ 'data' => array(
+ 'login',
+ 'main',
+ 'mainloginpage',
+ 'cashdeskloginpage',
+ 'passwordforgottenpage',
+ 'toprightmenu',
+ 'adminmodules',
+ 'admincompany',
+ 'commonobject',
+ 'thirdpartycard',
+ 'thirdpartylist',
+ 'customerlist',
+ 'prospectlist',
+ 'supplierlist',
+ 'usercard',
+ 'userperms',
+ 'groupcard',
+ 'groupperms',
+ 'userlist',
+ 'userhome',
+ 'userdao',
+ 'contactlist',
+ 'contactprospectlist',
+ 'contactcustomerlist',
+ 'contactsupplierlist',
+ 'contactotherlist',
+ 'productcard',
+ 'pricesuppliercard',
+ 'propalcard',
+ 'propallist',
+ 'ordercard',
+ 'orderlist',
+ 'invoicecard',
+ 'invoicelist',
+ 'warehousecard',
+ 'stocklist'
+ ),
+ 'entity' => '0'
+ ),
+ 'css' => array(
+ 'data' => '/multicompany/css/multicompany.css.php',
+ 'entity' => '0'
+ )
+ );
+
+ // Dependencies
+ $this->depends = array(); // List of modules id that must be enabled if this module is enabled
+ $this->requiredby = array(); // List of modules id to disable if this one is disabled
+ $this->phpmin = array(5,6); // Minimum version of PHP required by module
+ $this->need_dolibarr_version = array(12,0,0); // Minimum version of Dolibarr required by module
+ $this->langfiles = array("multicompany@multicompany");
+
+ // Constants
+ // List of particular constants to add when module is enabled
+ $this->const=array(
+ 1 => array('MULTICOMPANY_MAIN_VERSION', 'chaine', $this->version, '', 0, 'multicompany', 1),
+ 2 => array('MULTICOMPANY_EXTERNAL_MODULES_SHARING', 'chaine', '', '', 0, 'multicompany', 0),
+ 3 => array('MULTICOMPANY_NO_TOP_MENU_ENTITY_LABEL', 'chaine', 1, '', 0, 'multicompany', 0)
+ );
+
+ // Boxes
+ $this->boxes = array(); // List of boxes
+ $r=0;
+
+ // Permissions
+ $this->rights = array();
+ $r=0;
+
+ $r++;
+ $this->rights[$r][0] = 5001;
+ $this->rights[$r][1] = 'Read entities (For superadmin users)';
+ $this->rights[$r][2] = 'r';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'read';
+
+ $r++;
+ $this->rights[$r][0] = 5002;
+ $this->rights[$r][1] = 'Create/modify entities (For superadmin users)';
+ $this->rights[$r][2] = 'w';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'write';
+
+ $r++;
+ $this->rights[$r][0] = 5003;
+ $this->rights[$r][1] = 'Delete entities (For superadmin users)';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'delete';
+
+ // Thirdparty sharing (501x)
+
+ $r++;
+ $this->rights[$r][0] = 5011;
+ $this->rights[$r][1] = 'Read shared third parties';
+ $this->rights[$r][2] = 'r';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'thirdparty';
+ $this->rights[$r][5] = 'read';
+
+ $r++;
+ $this->rights[$r][0] = 5012;
+ $this->rights[$r][1] = 'Create/modify shared third parties';
+ $this->rights[$r][2] = 'w';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'thirdparty';
+ $this->rights[$r][5] = 'write';
+
+ $r++;
+ $this->rights[$r][0] = 5013;
+ $this->rights[$r][1] = 'Delete shared third parties';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'thirdparty';
+ $this->rights[$r][5] = 'delete';
+
+ // Contact sharing (502x)
+
+ $r++;
+ $this->rights[$r][0] = 5021;
+ $this->rights[$r][1] = 'Read shared contacts';
+ $this->rights[$r][2] = 'r';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'contact';
+ $this->rights[$r][5] = 'read';
+
+ $r++;
+ $this->rights[$r][0] = 5022;
+ $this->rights[$r][1] = 'Create/modify shared contacts';
+ $this->rights[$r][2] = 'w';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'contact';
+ $this->rights[$r][5] = 'write';
+
+ $r++;
+ $this->rights[$r][0] = 5023;
+ $this->rights[$r][1] = 'Delete shared contacts';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'contact';
+ $this->rights[$r][5] = 'delete';
+
+ // Product/service sharing (503x)
+
+ $r++;
+ $this->rights[$r][0] = 5031;
+ $this->rights[$r][1] = 'Read shared products/services';
+ $this->rights[$r][2] = 'r';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'product';
+ $this->rights[$r][5] = 'read';
+
+ $r++;
+ $this->rights[$r][0] = 5032;
+ $this->rights[$r][1] = 'Create/modify shared products/services';
+ $this->rights[$r][2] = 'w';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'product';
+ $this->rights[$r][5] = 'write';
+
+ $r++;
+ $this->rights[$r][0] = 5033;
+ $this->rights[$r][1] = 'Delete shared products/services';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'product';
+ $this->rights[$r][5] = 'delete';
+
+ // Proposal sharing (504x)
+
+ $r++;
+ $this->rights[$r][0] = 5041;
+ $this->rights[$r][1] = 'Read shared customer proposals';
+ $this->rights[$r][2] = 'r';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'propal';
+ $this->rights[$r][5] = 'read';
+
+ $r++;
+ $this->rights[$r][0] = 5042;
+ $this->rights[$r][1] = 'Create/modify shared customer proposals';
+ $this->rights[$r][2] = 'w';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'propal';
+ $this->rights[$r][5] = 'write';
+
+ $r++;
+ $this->rights[$r][0] = 5043;
+ $this->rights[$r][1] = 'Validate shared customer proposals';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'propal_advance';
+ $this->rights[$r][5] = 'validate';
+
+ $r++;
+ $this->rights[$r][0] = 5044;
+ $this->rights[$r][1] = 'Send shared customer proposals';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'propal_advance';
+ $this->rights[$r][5] = 'send';
+
+ $r++;
+ $this->rights[$r][0] = 5045;
+ $this->rights[$r][1] = 'Close shared customer proposals';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'propal';
+ $this->rights[$r][5] = 'close';
+
+ $r++;
+ $this->rights[$r][0] = 5046;
+ $this->rights[$r][1] = 'Delete shared customer proposals';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'propal';
+ $this->rights[$r][5] = 'delete';
+
+ // Order sharing (505x)
+
+ $r++;
+ $this->rights[$r][0] = 5051;
+ $this->rights[$r][1] = 'Read shared customer orders';
+ $this->rights[$r][2] = 'r';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'order';
+ $this->rights[$r][5] = 'read';
+
+ $r++;
+ $this->rights[$r][0] = 5052;
+ $this->rights[$r][1] = 'Close shared customer orders';
+ $this->rights[$r][2] = 'w';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'order';
+ $this->rights[$r][5] = 'write';
+
+ $r++;
+ $this->rights[$r][0] = 5054;
+ $this->rights[$r][1] = 'Validate shared customer orders';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'order_advance';
+ $this->rights[$r][5] = 'validate';
+
+ $r++;
+ $this->rights[$r][0] = 5056;
+ $this->rights[$r][1] = 'Send shared customer orders';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'order_advance';
+ $this->rights[$r][5] = 'send';
+
+ $r++;
+ $this->rights[$r][0] = 5057;
+ $this->rights[$r][1] = 'Close shared customer orders';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'order';
+ $this->rights[$r][5] = 'close';
+
+ $r++;
+ $this->rights[$r][0] = 5058;
+ $this->rights[$r][1] = 'Cancel shared customer orders';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'order_advance';
+ $this->rights[$r][5] = 'cancel';
+
+ $r++;
+ $this->rights[$r][0] = 5059;
+ $this->rights[$r][1] = 'Delete shared customer orders';
+ $this->rights[$r][2] = 'd';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'order';
+ $this->rights[$r][5] = 'delete';
+
+ // Invoice sharing (506x)
+
+ $r++;
+ $this->rights[$r][0] = 5061;
+ $this->rights[$r][1] = 'Read shared customer invoices';
+ $this->rights[$r][2] = 'a';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'invoice';
+ $this->rights[$r][5] = 'read';
+
+ $r++;
+ $this->rights[$r][0] = 5062;
+ $this->rights[$r][1] = 'Create/modify shared customer invoices';
+ $this->rights[$r][2] = 'a';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'invoice';
+ $this->rights[$r][5] = 'write';
+
+ // There is a particular permission for unvalidate because this may be not forbidden by some laws
+ $r++;
+ $this->rights[$r][0] = 5063;
+ $this->rights[$r][1] = 'Devalidate shared customer invoices';
+ $this->rights[$r][2] = 'a';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'invoice_advance';
+ $this->rights[$r][5] = 'unvalidate';
+
+ $r++;
+ $this->rights[$r][0] = 5064;
+ $this->rights[$r][1] = 'Validate shared customer invoices';
+ $this->rights[$r][2] = 'a';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'invoice_advance';
+ $this->rights[$r][5] = 'validate';
+
+ $r++;
+ $this->rights[$r][0] = 5065;
+ $this->rights[$r][1] = 'Send shared customer invoices';
+ $this->rights[$r][2] = 'a';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'invoice_advance';
+ $this->rights[$r][5] = 'send';
+
+ $r++;
+ $this->rights[$r][0] = 5066;
+ $this->rights[$r][1] = 'Issue payments on shared customer invoices';
+ $this->rights[$r][2] = 'a';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'invoice';
+ $this->rights[$r][5] = 'payment';
+
+ $r++;
+ $this->rights[$r][0] = 5067;
+ $this->rights[$r][1] = 'Re-open a fully paid shared customer invoices';
+ $this->rights[$r][2] = 'r';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'invoice_advance';
+ $this->rights[$r][5] = 'reopen';
+
+ $r++;
+ $this->rights[$r][0] = 5069;
+ $this->rights[$r][1] = 'Delete shared customer invoices';
+ $this->rights[$r][2] = 'a';
+ $this->rights[$r][3] = 0;
+ $this->rights[$r][4] = 'invoice';
+ $this->rights[$r][5] = 'delete';
+
+ // Main menu entries
+ $this->menus = array(); // List of menus to add
+ $r=0;
+
+ }
+
+ /**
+ * Function called when module is enabled.
+ * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
+ * It also creates data directories.
+ *
+ * @param string $options Options when enabling module ('', 'newboxdefonly', 'noboxes')
+ * 'noboxes' = Do not insert boxes
+ * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation
+ * @return int 1 if OK, 0 if KO
+ */
+ function init($options = '')
+ {
+ $sql = array();
+
+ $result=$this->load_tables();
+
+ $result=$this->setSuperAdmin();
+
+ $result=$this->setFirstEntity();
+
+ return $this->_init($sql, $options);
+ }
+
+ /**
+ * Function called when module is disabled.
+ * Remove from database constants, boxes and permissions from Dolibarr database.
+ * Data directories are not deleted.
+ *
+ * @param string $options Options when enabling module ('', 'noboxes')
+ * @return int 1 if OK, 0 if KO
+ */
+ function remove($options = '')
+ {
+ $sql = array(
+ "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = ".$this->db->encrypt('MAIN_MODULE_MULTICOMPANY_CSS', 1),
+ "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = ".$this->db->encrypt('MAIN_MODULE_MULTICOMPANY_LOGIN', 1)
+ );
+
+ return $this->_remove($sql, $options);
+ }
+
+ /**
+ * Create tables and keys required by module
+ * This function is called by this->init.
+ * @return int <=0 if KO, >0 if OK
+ */
+ function load_tables()
+ {
+ return $this->_load_tables('/multicompany/sql/');
+ }
+
+ /**
+ * Set the first entity
+ *
+ * @return int
+ */
+ function setSuperAdmin()
+ {
+ global $user;
+
+ $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.'user';
+ $sql.= ' WHERE admin = 1 AND entity = 0';
+ $res = $this->db->query($sql);
+ if ($res) $num = $this->db->fetch_array($res);
+ else dol_print_error($this->db);
+
+ if (empty($num[0]))
+ {
+ $this->db->begin();
+
+ $sql = 'UPDATE '.MAIN_DB_PREFIX.'user SET entity = 0';
+ $sql.= ' WHERE admin = 1 AND rowid IN (1,'.$user->id.')';
+ if ($this->db->query($sql))
+ {
+ $this->db->commit();
+ return 1;
+ }
+ else
+ {
+ $this->db->rollback();
+ return -1;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ /**
+ * Set the first entity
+ *
+ * @return int
+ */
+ function setFirstEntity()
+ {
+ global $user, $langs;
+
+ $langs->load('multicompany@multicompany');
+
+ $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.'entity';
+ $res = $this->db->query($sql);
+ if ($res) $num = $this->db->fetch_array($res);
+ else dol_print_error($this->db);
+
+ if (empty($num[0]))
+ {
+ $this->db->begin();
+
+ $now = dol_now();
+
+ $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'entity (';
+ $sql.= 'label';
+ $sql.= ', description';
+ $sql.= ', datec';
+ $sql.= ', fk_user_creat';
+ $sql.= ') VALUES (';
+ $sql.= '\''.$langs->trans("MasterEntity").'\'';
+ $sql.= ', \''.$langs->trans("MasterEntityDesc").'\'';
+ $sql.= ', \''.$this->db->idate($now).'\'';
+ $sql.= ', '.$user->id;
+ $sql.= ')';
+
+ if ($this->db->query($sql))
+ {
+ $this->db->commit();
+ return 1;
+ }
+ else
+ {
+ $this->db->rollback();
+ return -1;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ }
+}
diff --git a/htdocs/custom/multicompany/core/triggers/index.html b/htdocs/custom/multicompany/core/triggers/index.html
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/htdocs/custom/multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php b/htdocs/custom/multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php
new file mode 100755
index 00000000000..a8b444a7417
--- /dev/null
+++ b/htdocs/custom/multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php
@@ -0,0 +1,86 @@
+
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \file /multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php
+ * \ingroup multicompany
+ * \brief Trigger file for create multicompany data
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
+
+/**
+ * \class InterfaceMulticompanyWorkflow
+ * \brief Classe des fonctions triggers des actions personnalisees du module multicompany
+ */
+
+class InterfaceMulticompanyWorkflow extends DolibarrTriggers
+{
+ public $family = 'multicompany';
+
+ public $description = "Triggers of this module allows to create multicompany data";
+
+ /**
+ * Version of the trigger
+ *
+ * @var string
+ */
+ public $version = self::VERSION_DOLIBARR;
+
+ /**
+ *
+ * @var string Image of the trigger
+ */
+ public $picto = 'multicompany@multicompany';
+
+ /**
+ * Function called when a Dolibarrr business event is done.
+ * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/core/triggers (and declared)
+ *
+ * Following properties may be set before calling trigger. The may be completed by this trigger to be used for writing the event into database:
+ * $object->id (id of entity)
+ * $object->element (element type of object)
+ *
+ * @param string $action Event action code
+ * @param Object $object Object
+ * @param User $user Object user
+ * @param Translate $langs Object langs
+ * @param conf $conf Object conf
+ * @return int <0 if KO, 0 if no triggered ran, >0 if OK
+ */
+ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
+ {
+ // Mettre ici le code a executer en reaction de l'action
+ // Les donnees de l'action sont stockees dans $object
+
+ /*if ($action == 'COMPANY_CREATE')
+ {
+ $entity = GETPOST('new_entity', 'int', 2); // limit to POST
+
+ if ($entity > 0)
+ {
+ dol_syslog("Trigger '".$this->name."' for action '$action' launched by ". __FILE__ .". id=".$object->rowid);
+
+ return $ret;
+ }
+ }*/
+
+ return 0;
+ }
+
+}
diff --git a/htdocs/custom/multicompany/css/dropdown.inc.php b/htdocs/custom/multicompany/css/dropdown.inc.php
new file mode 100755
index 00000000000..ef91f9078cb
--- /dev/null
+++ b/htdocs/custom/multicompany/css/dropdown.inc.php
@@ -0,0 +1,199 @@
+
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+if (! defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet');
+$colorbackhmenu1='60,70,100'; // topmenu
+?>
+/*